这里的扩展指的是通用Mapper没有提供的功能,如批量 update。
例子:
类似于生成下面这样的SQL语句:
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
UPDATE tabple_emp SET emp_name=?,emp_age=?,emp_salary=? where emp_id=? ;
……
为了生成上面那样的 SQL 语句,我们需要使用到 MyBatis 的 foreach 标签。
<foreach collection="list" item="record" separator=";" >
UPDATE tabple_emp
SET emp_name=#{record.empName},
emp_age=#{record.empAge},
emp_salary=#{record.empSalary}
where emp_id=#{record.empId}
</foreach>
1.自定义一个接口
@RegisterMapper //这个注解别忘了
public interface MyBatchUpdateMapper<T> {
//method是固定值dynamicSQL,type指定具体提供sql语句的类
@UpdateProvider(type=MyBatchUpdateProvider.class, method="dynamicSQL")
void batchUpdate(List<T> list);
}
2.编写具体实现功能的类,类名为前面接口中type指的是类名,这个类必须继承MapperTemplate,重写构造方法
3.在类中提供一个和前面接口中同名的方法然后实现
public class MyBatchUpdateProvider extends MapperTemplate {
//首先继承MapperTemplate,然后重写构造方法
public MyBatchUpdateProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
/* 目的就是让这个方法为我们拼接一个字符串:下面 ↓
<foreach collection="list" item="record" separator=";" >
UPDATE tabple_emp
<set>
emp_name=#{record.empName},
emp_age=#{record.empAge},
emp_salary=#{record.empSalary},
</set>
where emp_id=#{record.empId}
</foreach>
*/
//然后提供一个同名的实现方法
public String batchUpdate(MappedStatement statement) {
//1.创建StringBuilder用于拼接SQL语句的各个组成部分
StringBuilder builder = new StringBuilder();
//2.拼接foreach标签
builder.append("<foreach collection=\"list\" item=\"record\" separator=\";\" >");
//3.获取实体类对应的Class对象
Class<?> entityClass = super.getEntityClass(statement);
//4.获取实体类在数据库中对应的表名
String tableName = super.tableName(entityClass);
//5.生成update子句
String updateClause = SqlHelper.updateTable(entityClass, tableName);
builder.append(updateClause);
builder.append("<set>");
//6.获取所有字段信息
Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);
String idColumn = null;
String idHolder = null;
for (EntityColumn entityColumn : columns) {
boolean isPrimaryKey = entityColumn.isId();
//7.判断当前字段是否为主键
if(isPrimaryKey) {
//8.缓存主键的字段名和字段值
idColumn = entityColumn.getColumn();
//※返回格式如:#{record.age,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
idHolder = entityColumn.getColumnHolder("record");
}else {
//9.使用非主键字段拼接SET子句
String column = entityColumn.getColumn();
String columnHolder = entityColumn.getColumnHolder("record");
builder.append(column).append("=").append(columnHolder).append(",");
}
}
builder.append("</set>");
//10.使用前面缓存的主键名、主键值拼接where子句
builder.append("where ").append(idColumn).append("=").append(idHolder);
builder.append("</foreach>");
//11.将拼接好的字符串返回
return builder.toString();
}
}
4.我们可以定义的一个Mapper接口,并继承于之前定义的那个Mapper接口
public interface MyMapper<T>
extends SelectAllMapper<T>,SelectByExampleMapper<T>,
MyBatchUpdateMapper<T> {//继承自己定义的接口
}
public interface EmployeeMapper extends Mapper<Employee> {
}
service
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
public void batchUpdateEmp(List<Employee> empList) {
employeeMapper.batchUpdate(empList);
}
}
这里MyMapper同样需要注册
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper.mappers"/>
<property name="properties">
<value>
mappers=com.example.mapper.mine_mappers.MyMapper
</value>
</property>
</bean>
最后测试通过即可
ClassPathXmlApplicationContext iocContainer = new ClassPathXmlApplicationContext("spring-context.xml");
EmployeeService employeeService = iocContainer.getBean(EmployeeService.class);
List<Employee> empList = new ArrayList<>();
empList.add(new Employee(25, "newName01", 111.11, 10));
empList.add(new Employee(26, "newName02", 222.22, 20));
empList.add(new Employee(27, "newName03", 333.33, 30));
employeeService.batchUpdateEmp(empList);
iocContainer.close();
标签:Mapper,builder,接口,empList,record,emp,Mybatis,public,append From: https://www.cnblogs.com/snad/p/17505305.html