文章目录
- 1、通用 Mapper 介绍
- 2、快速使用通用 Mapper
- 2.1、创建表、实体类和 Mapper 接口
- 2.2、集成通用 Mapper
- 2.3、配置扫描包
- 2.4、Mapper 接口继承通用 Mapper 的核心接口 Mapper< T >
- 3、常用注解
- 3.1、@Table
- 3.2、@Column
- 3.3、@Id
- 3.4、@GeneratedValue
- 3.5、@Transient
- 4、常用方法
- 4.1、selectOne 方法
- 4.2、xxxByPrimaryKey 方法
- 4.3、xxxSelective 方法
- 5、QBC 查询
- 5.1、概念
- 5.2、示例代码
- 6、逆向工程
- 6.1、原生 MyBatis 逆向工程和通用 Mapper 逆向工程对比
- 6.2、参考文档地址
- 6.3、在 pom 文件中添加参数
- 6.4、在 pom 文件中添加插件
- 6.5、创建 MBG 配置文件 generatorConfig.xml
- 6.6、运行通用 Mapper 逆向工程
- 6.6.1、Intellij 环境下
- 6.6.2、eclipse 环境下
表代码:
CREATE TABLE `table_emp` (
`emp_id` int NOT NULL AUTO_INCREMENT ,
`emp_name` varchar(500) NULL ,
`emp_salary` double(15,5) NULL ,
`emp_age` int NULL ,
PRIMARY KEY (`emp_id`)
);
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('tom', '1254.37', '27');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('jerry', '6635.42', '38');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('bob', '5560.11', '40');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('kate', '2209.11', '22');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('justin', '4203.15', '30');
实体类代码:
考虑到基本数据类型在 Java 类中都有默认值,会导致 MyBatis 在执行相关操作时很难判断当前字段是否为 null,所以如阿里开发手册所言,Java 实体类尽量不要使用基本数据类型,都使用对应的包装类型。
@Data // lombok 插件,自动生成 get、set 等方法
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
private Integer empAge;
}
操作数据库的 Mapper 接口代码:
public interface EmployeeMapper {
}
在 pom 文件中引入通用 Mapper 的启动器
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>2.0.3version>
dependency>
在 SpringBoot 启动类上面添加扫描包注解。此时用的是通用 Mapper 的扫描注解(其与原生 Mybatis 扫描包注解同名)
原始扫描包注解全类名:
import org.mybatis.spring.mapper.MapperScannerConfigurer
通用 Mapper 扫描包注解全类名:
import tk.mybatis.spring.mapper.MapperScannerConfigurer
原因是:由通用 Mapper 扫描的 dao 层接口,会在进入容器前,生成通用方法。
/**
* 具体操作数据库的 Mapper 接口,需要继承通用 Mapper 提供的核心接口 :Mapper
* 泛型类型就是实体类的类型
*/
public interface EmployeeMapper extends Mapper<Employee> {
}
作用: 建立实体类和数据库表之间的对应关系。(指定类对应的表名称)
默认规则为 实体类类名首字母小写作为表名。Employee 类→employee 表。
用法: 在@Table 注解的 name 属性中指定目标数据库表的表名
实体类代码:
@Data
@Table(name = "table_emp")
public class Employee {
private Integer empId;
private String empName;
private BigDecimal empSalary;
private Integer empAge;
}
作用: 建立实体类字段和数据库表字段之间的对应关系。
默认规则:
实体类字段:驼峰式命名
数据库表字段:使用“_”区分各个单词
用法: 在@Column 注解的 name 属性中指定目标字段的字段名
实体类代码:
@Data
@Table(name = "table_emp")
public class Employee {
@Column(name = "emp_id")
private Integer empId;
@Column(name = "emp_name")
private String empName;
@Column(name = "emp_salary")
private BigDecimal empSalary;
@Column(name = "emp_age")
private Integer empAge;
}
通用 Mapper 在执行 xxxByPrimaryKey(key)方法时,有两种情况:
情况 1:没有使用@Id 注解明确指定主键字段生成如下通用方法:
之所以会生成上面这样的 WHERE 子句是因为通用 Mapper 将实体类中的所有字段都拿来放在一起作为联合主键。
情况 2:使用 @Id 主键明确标记和数据库表中主键字段对应的实体类字段:
@Id
@Column(name = "emp_id")
private Integer empId;
作用: 让通用 Mapper 在执行 insert 操作之后将数据库自动生成的主键值回写到实体类对象中。
自增主键用法(MySQL):
@Id
@Column(name = "emp_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer empId;
序列主键用法(Oracle):
@Id
@Column(name = "emp_id")
@GeneratedValue(
strategy = GenerationType.IDENTITY,
generator = "select SEQ_ID.nextval from dual")
private Integer empId;
应用场景:
用于标记不与数据库表字段对应的实体类字段,即该属性不参与 SQL 语句。若属性没有加该注解,并且在数据库表中找不到匹配列,则会抛出列找不到异常
@Transient
private String otherThings; //非数据库表中字段
public Employee getOne(Employee employee) {
return employeeMapper.selectOne(employee);
}
public Employee getOne(Employee employee) {
return employeeMapper.selectByPrimaryKey(employee);
}
需要使用 @Id 主键明确标记和数据库表主键字段对应的实体类字段,否则通用 Mapper 会将所有实体类字段作为联合主键。
非主键字段如果为 null 值,则不加入到 SQL 语句中。适用于字段很多,但是插入少的情况。如果表字段很多,但是一开始可能只插入某几个字段,用此方法生成的 SQL 语句会很简介,并且便于调试。
//目标 SQL 查询语句:WHERE (emp_salary>? AND emp_age) OR (emp_salary AND emp_age>?)
//1.创建 Example 对象
Example example = new Example(Employee.class);
//***********************
//i.设置排序信息
example.orderBy("empSalary").asc().orderBy("empAge").desc();
//ii.设置“去重”
example.setDistinct(true);
//iii.设置 select 字段
example.selectProperties("empName","empSalary");
//***********************
//2.通过 Example 对象创建 Criteria 对象
Criteria criteria01 = example.createCriteria();
Criteria criteria02 = example.createCriteria();
//3.在两个 Criteria 对象中分别设置查询条件
//property 参数:实体类的属性名
//value 参数:实体类的属性值
criteria01.andGreaterThan("empSalary", 3000).andLessThan("empAge", 25);
criteria02.andLessThan("empSalary", 5000).andGreaterThan("empAge", 30);
//4.使用 OR 关键词组装两个 Criteria 对象
example.or(criteria02);
//5.执行查询
List<Employee> empList = employeeService.getEmpListByExample(example);
for (Employee employee : empList) {
System.out.println(employee);
}
代码生成器
在 pom 文件中写入所有参数并不是硬性的要求,可以在要用的时候硬编码写死到代码中。先把参数放在 pom 文件中方便管理
<properties>
<targetJavaProject>${basedir}/src/main/javatargetJavaProject>
<targetMapperPackage>per.cjh.example.mapperstargetMapperPackage>
<targetModelPackage>per.cjh.example.entitiestargetModelPackage>
<targetResourcesProject>${basedir}/src/main/resourcestargetResourcesProject>
<targetXMLPackage>mapperstargetXMLPackage>
<mapper.version>4.0.0mapper.version>
<mysql.version>8.0.19mysql.version>
properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
<plugin>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-maven-pluginartifactId>
<version>1.3.6version>
<configuration>
<configurationFile>
${basedir}/src/main/resources/generator/generatorConfig.xml
configurationFile>
<overwrite>trueoverwrite>
<verbose>trueverbose>
configuration>
<dependencies>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapperartifactId>
<version>${mapper.version}version>
dependency>
dependencies>
plugin>
plugins>
build>
注意:配置文件的路径要在上一步声明的路径下面。
<generatorConfiguration>
<properties resource="config.properties"/>
<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="${mapper.plugin}">
<property name="mappers" value="${mapper.Mapper}"/>
<property name="caseSensitive" value="true"/>
plugin>
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.url}"
userId="${jdbc.user}"
password="${jdbc.password}">
jdbcConnection>
<javaModelGenerator targetPackage="${targetModelPackage}"
targetProject="${targetJavaProject}"/>
<sqlMapGenerator targetPackage="${targetXMLPackage}"
targetProject="${targetResourcesProject}"/>
<javaClientGenerator targetPackage="${targetMapperPackage}"
targetProject="${targetJavaProject}"
type="XMLMAPPER"/>
<table tableName="account" domainObjectName="account">
<generatedKey column="id" sqlStatement="Mysql" identity="true"/>
table>
context>
generatorConfiguration>
右键 pom 文件,Run As -> Maven build
在弹出窗口的 Goals:文本框内写入右边的命令 mvn mybatis-generator:generate
点击Run