使用通用Mapper
的目的是为了替我们生成常用增删改查操作的SQL
语句,并能够简化对于Mybatis
的操作。
一、快速入门
1.1 数据库表的创建
CREATE TABLE `tabple_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' );
1.2 对应实体类的创建
基本数据类型在Java
类中都有默认值,会导致Mybatis
在执行相关操作时很难判断当前字段是否为Null
。因此,在Mybatis
环境下使用Java
实体类时尽量不要使用基本数据类型,都使用对应的包装类型。
public class Employee implements Serializable {
private Integer empId;
private String empName;
private Double empSalary;
private Integer empAge;
public Employee() {
}
public Employee(Integer empId, String empName, Double empSalary, Integer empAge) {
this.empId = empId;
this.empName = empName;
this.empSalary = empSalary;
this.empAge = empAge;
}
// 省略了getter、setter以及toString()方法的展示
}
1.3 Spring-SpringMVC-Mybatis的整合
整合步骤见此文ssm框架的整合。
二、通用Mapper的MBG
原生的MBG
和通用的MBG
做对比。
通用Mapper
的逆向工程,通过其特点的插件,同样的生成Java
实体类对象,带有注解(@Id
、@Column
等注解);在dao
接口层,即mapper
接口继承通用Mapper
中核心的接口Mapper<T>
;生成的实体类Mapper
文件(XXxMapper
文件)没有SQL
语句标签。
当通用Mapper
与Spring
或SpringBoot
整合完以后,通用Mapper
的MBG
可参考官方文档使用Maven
执行MBG
的方式。
2.1 自定义Mapper
接口
其自己的Mapper<T>
接口层次结构如上所示。
作用,根据我们自身的需要,继承上方的层级结构中的mapper
接口,供我们自身开发。
举例:
自定义接口:
自定义的Mapper不能和原有的实体类Mapper放在同一级的目录下。
public interface MyInterface<T> extends BaseMapper<T>, ExampleMapper<T> {
}
@Repository
public interface EmployeeMapper extends MyMapper<Employee> {
}
配置MapperScannerConfigurer
注册MyMapper<T>
,或者在我们自定义的Mapper
接口中加入注解@RegisterMapper
!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中 -->
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描所有dao接口的实现,加入到ioc容器中 -->
<property name="basePackage" value="cn.lizhi.dao"></property>
<property name="properties">
<value>
mapper=cn.lizhi.myInterface.MyMapper
</value>
</property>
</bean>
其中value
值默认的是原生mapper
的值。
2.2 通用Mapper接口扩展
其扩展用来指增加通用Mapper中没有提供的功能。
示例:批量更新。
思路:当我们写SQL
语句时,如何能做到批量更新呢?即用;
分割我们需要更新的SQL
语句。
UPDATE table_emp SET emp_name=?,emp_age=?,emp_salary=? WHERE emp_id=?;
UPDATE table_emp SET emp_name=?,emp_age=?,emp_salary=? WHERE emp_id=?;
UPDATE table_emp SET emp_name=?,emp_age=?,emp_salary=? WHERE emp_id=?;
UPDATE table_emp SET emp_name=?,emp_age=?,emp_salary=? WHERE emp_id=?;
...
那么Mybatis
又是如何做到上面这种形式的呢?即,通过foreach
标签达到语句的拼接。
<foreach collection='list' item='record' separator=';'>
UPDATE table_emp
SET
emp_name=#{record.empName},
emp_age=#{record.empAge},
emp_salay=#{record.empSalary}
WhERE emp_id=#{record.empId}
</foreach>
即我们需要使用通用Mapper能够做到动态的生成上面的SQL
语句,供我们使用,即可做到接口的扩展。
2.2.1 需要提供的接口和实现类
在我们自定义的MyMapper<T>
接口中除了需要继承Mapper<T>
中下方层次结构的接口,它还需要继承我们自己自定义功能的Mapper
接口,这里是MyBatchUpdateProvider
。
其中MyBatchUpdateProvider
是我们自己编写的类(需要继承模板),用于解析xml
的SQL
语句。
代码示例:
首先编写我们自定义的接口MyBatchUpdateMapper
。
@RegisterMapper
public interface MyBatchUpdateMapper<T> {
@UpdateProvider(type=MyBatchUpdateProvider.