1.前言
Springboot最近可谓是非常的火,本人也在项目中尝到了甜头。之前一直使用Springboot+JPA,用了一段时间发现JPA不是太灵活,也有可能是我不精通JPA,总之为了多学学Springboot我决定尝试一下Springboot+MyBatis+JPA三项集成,集成过程中遇到了很多问题,但最后总算是集成成功了,现在记录一下方法。
1.1 如何使用MyBatis Generator自动生成xxxMapper.java接口以及xxxMapper.xml文件
以前用过SpringMVC,知道写xxxMapper.java接口以及xxxMapper.xml文件的辛苦,这次集成最先想到的就是先解决如何使用如何使用MyBatis Generator自动生成这些文件的问题。
先扔出MyBatis Generator的官网->
我使用的Maven集成插件的方式,IDE使用的是IDEA
1.1.1 创建项目
1.1.2 修改pom.xml
添加了Druid依赖和MyBatis Generator插件
其他依赖请自行添加
4.0.0 com.study.springboot mybatis 1.0 war demo springboot+mybatis+jpa org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-data-jpa org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.1 org.springframework.boot spring-boot-starter-web mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-test test com.alibaba druid 1.1.5 org.springframework.boot spring-boot-maven-plugin org.mybatis.generator mybatis-generator-maven-plugin 1.3.5 Generate MyBatis Artifacts generate
1.1.3 配置generatorConfiguration
generatorConfig.xml放在resource文件夹下
常用配置已经注释了,请自行查看
可选:
1. schema:数据库的schema 2. catalog:数据库的catalog 3. alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName 4. domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面 5. enableInsert(默认true):指定是否生成insert语句 6. enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get) 7. enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句 8. enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update) 9. enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete) 10. enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句 11. enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询) 12. enableUpdateByExample(默认true)MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性) 13. modelType:参考context元素的defaultModelType,相当于覆盖 14. delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性) 15. delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来.默认为false,delimitIdentifiers参考context的属性
注意,table里面很多参数都是对javaModelGenerator,context等元素的默认属性的一个复写 -->
1.1.4 生成xxxMapper.java接口以及xxxMapper.xml文件
注意,如果存放xxxMapper.java和xxxMapper.xml文件的包不存在会报错
1.1.5 修改自动生成的实体类
对于model包下的实体类需要添加基于JPA的注解,否则JPA接口无法引用
例如对于User.java实体类需要进行如下修改
package com.study.springboot.mybatis.model;import javax.persistence.*;@Entity@Table(name = "user")public class User { @Id @GeneratedValue @Column(name = "id") private Integer id; @Column(name = "user_name") private String userName; @Column(name = "passwd") private String passwd; @Column(name = "nick_name") private String nickName; @Column(name = "telephone") private String telephone; @Column(name = "email") private String email; @Column(name = "authority") private Integer authority; @Column(name = "department") private String department; @Column(name = "create_at") private String createAt; @Column(name = "update_at") private String updateAt; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName == null ? null : userName.trim(); } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd == null ? null : passwd.trim(); } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName == null ? null : nickName.trim(); } public String getTelephone() { return telephone; } public void setTelephone(String telephone) { this.telephone = telephone == null ? null : telephone.trim(); } public String getEmail() { return email; } public void setEmail(String email) { this.email = email == null ? null : email.trim(); } public Integer getAuthority() { return authority; } public void setAuthority(Integer authority) { this.authority = authority; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department == null ? null : department.trim(); } public String getCreateAt() { return createAt; } public void setCreateAt(String createAt) { this.createAt = createAt == null ? null : createAt.trim(); } public String getUpdateAt() { return updateAt; } public void setUpdateAt(String updateAt) { this.updateAt = updateAt == null ? null : updateAt.trim(); }}
1.1.6 添加xxxJPA接口,例如UserJPA.java
import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.JpaSpecificationExecutor;import java.io.Serializable;public interface UserJPA extends Serializable, JpaRepository, JpaSpecificationExecutor {}
1.1.7 测试
测试之前需要配置application.yml(你的有能是application.properties,改一下后缀名即可,我比较喜欢.yml文件的简洁)
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 driver-class-name: com.mysql.jdbc.Driver username: root password: 123456mybatis: # 重要配置 type-aliases-package: com.study.springboot.mybatis.model mapper-locations: classpath:mapper/*.xml
对于每一个xxxMapper.java接口,需要使用@Component注解
自动生成的xxxMapper.java接口是不带@Component注解的
@Componentpublic interface UserMapper { int deleteByPrimaryKey(Integer id); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(User record); int updateByPrimaryKey(User record);}
在入口类中需要添加@MapperScan("com.study.springboot.mybatis.mapper")注解
@SpringBootApplication@MapperScan("com.study.springboot.mybatis.mapper")public class MybatisApplication { public static void main(String[] args) { SpringApplication.run(MybatisApplication.class, args); }}
打开测试类,为测试类添加@MapperScan("com.study.springboot.mybatis.mapper")注解
1 @RunWith(SpringRunner.class) 2 @SpringBootTest 3 @MapperScan("com.study.springboot.mybatis.mapper") 4 public class MybatisApplicationTests { 5 6 @Autowired 7 private UserMapper userMapper; 8 9 @Autowired10 private UserJPA userJPA;11 12 @Test13 public void contextLoads() {14 System.out.println(userMapper.selectByPrimaryKey(11).getUserName());15 System.out.println(userJPA.findOne(11).getUserName());16 }17 18 }
最后如果出现
java.lang.NoClassDefFoundError: org/apache/ibatis/session/SqlSession
的错误,请检查本地Maven仓库的配置,有可能是没有Maven没有下载需要引用的包