一、mybatis的版本必须为3.3.1及其以上
项目所依赖的mybatis的版本必须为3.3.1及其以上,低版本的不行,保证hap项目的依赖的mybatis的jar的版本必需为需要的版本:
二、在Dao层不能使用@Param注解,且Mapper.xml文件中使用list变量接收Dao层中的集合
数据库库结构设计:
对应的Dto层:
对应的Mapper接口:
对应的Mapper.xml文件:
具体代码如下,需要使用到mycat的注解,指定该插入为批量数据插入:
/*!mycat:catlet=io.mycat.route.sequence.BatchInsertSequence */
insert into test_sharding_by_accounting_date (rule_code,name,accounting_date)
values
(#{item.ruleCode,jdbcType=DECIMAL},#{item.name,jdbcType=VARCHAR},#{item.accountingDate,jdbcType=DATE})
三、Mycat为分库表做全局序列的配置
schema.xml文件:
server.xml文件的全局序列方式设置为本地读取:
sequence_conf.properties文件的配置:
在Mybatis中,在执行insert操作时,如果我们希望返回数据库的自增主键的ID值,那么需要使用到KeyGenerator对象。需要注意的是,KeyGenerator的作用是返回数据库的自增的主键值,而不是去生成数据库的自增主键值,返回的主键值存放在parameter Object的主键属性上的。
KeyGenerator接口的申明如下:
/**
* @author Clinton Begin
*/
public interface KeyGenerator {
void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter);
void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter);
}
主要就是在insert前、insert后去处理主键的值:
Jdbc3KeyGenerator:用于处理数据库支持自增主键的情况,如MySQL的auto_increment。
NoKeyGenerator:空实现,不需要处理主键。
SelectKeyGenerator:用于处理数据库不支持自增主键的情况,比如Oracle的sequence序列。
原生的jdbc的方式生成主键ID的原理:
lass.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "123");
conn.setAutoCommit(false);
PreparedStatement pstm = conn.prepareStatement("insert into students(name, email) values(?, ?)",
Statement.RETURN_GENERATED_KEYS);
pstm.setString(1, "name1");
pstm.setString(2, "email1");
pstm.addBatch();
pstm.setString(1, "name2");
pstm.setString(2, "email2");
pstm.addBatch();
pstm.executeBatch();
// 返回自增主键值
ResultSet rs = pstm.getGeneratedKeys();
while (rs.next()) {
Object value = rs.getObject(1);
System.out.println(value);
}
conn.commit();
rs.close();
pstm.close();
conn.close();
output:
246
247
Jdbc3KeyGenerator源码解读:
public class Jdbc3KeyGenerator implements KeyGenerator {
@Override
public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
// do nothing
}
@Override
public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
processBatch(ms, stmt, getParameters(parameter));
}
public void processBatch(MappedStatement ms, Statement stmt, Collection
SelectKeyGenerator的原理:
SELECT ELEARNING.STUD_ID_SEQ.NEXTVAL FROM DUAL
INSERT INTO
STUDENTS(STUD_ID, NAME, EMAIL, DOB, PHONE)
VALUES(#{studId}, #{name},
#{email}, #{dob}, #{phone})
在执行insert之前,先发起一个sql查询,将返回的序列值赋值给Student的stuId属性,然后再执行insert操作,这样表中的stud_id字段就有值了。order="BEFORE"表示insert前执行,比如取sequence序列值;order="AFTER"表示insert之后执行;比如使用触发器给主键stud_id赋值。由于selectKey本身返回单个序列主键值,也就无法支持批量insert操作并返回主键id列表了。如果要执行批量insert,请选择使用for循环执行多次插入操作。
参考地址:https://my.oschina.net/zudajun/blog/673612