1.PageHelper分页插件
pagehelper文档:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
使用方法参照文档
2.MyBatis的批量操作
1.使用动态sql,拼接大量sql语句,进行操作。
缺点:如果操作量非常大,可能导致数据库不能接受很长的sql语句
2.MyBatis提供了批量操作的配置
但是如果在全局配置文件修改,那么所有sql语句执行都会变成批量执行器
解决:
在获取SqlSession时使用SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
拿到一个可以执行批量操作的sqlSession就行了
测试:插入10000条数据,批量操作与非批量操作的速度快慢
sql映射文件:
<!-- public void addEmps(Employee employee); --> <insert id="addEmps"> insert into tbl_employee(last_name,email,gender) values(#{lastname},#{email},#{gender}) </insert>
1.批量操作:
测试代码:
@Test void test03() throws IOException { SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(); // 拿到一个可以执行批量操作的sqlSession SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { mapper.addEmps(new Employee(UUID.randomUUID().toString().substring(0, 5), "a", "1")); } openSession.commit(); long end = System.currentTimeMillis(); System.out.println("执行时间:" + (end - start)); } finally { openSession.close(); } }
批量操作结果:
插入10000条数据耗时4856ms
2.非批量操作:
测试代码:
@Test void test03() throws IOException { SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(); // 不使用批量操作 SqlSession openSession = sqlSessionFactory.openSession(/* ExecutorType.BATCH */); try { EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { mapper.addEmps(new Employee(UUID.randomUUID().toString().substring(0, 5), "a", "1")); } openSession.commit(); long end = System.currentTimeMillis(); System.out.println("执行时间:" + (end - start)); } finally { openSession.close(); } }
批量操作结果:
耗时10756ms
结果分析:
从部分的执行结果截图来看:
批量操作是:预编译sql一次,设置参数10000次,sql执行一次
非批量操作:预编译sql==设置参数==sql执行==10000次
如何在Spring中使用可以进行批量执行的SqlSession
在spring文件中配置一个可以进行批量执行的sqlSession
<!-- 配置一个可以执行批量操作的sqlSession --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg> <constructor-arg name="executorType" value="BATCH"></constructor-arg> </bean>
如果要使用:在需要使用的service下自动注入一个SqlSession对象,使用该对象获取mapper,进行批量操作
@Autowired SqlSession session; public void addEmps(Employee employee) { EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); /* 批量操作 */ }
3.存储过程
1.在数据库端写好存储过程
2.在sql映射文件配置SQL
CALLABLE:表示要调用的是存储过程
4.自定义类型处理器处理枚举类型
MyBatis默认处理枚举对象是保存的枚举的名字,使用的类是EnumTypeHandler
改变使用:EnumOrdinalTypeHandler的方法
在全局配置文件中配置
<typeHandlers> <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/> </typeHandlers>
就可以使用EnumOrdinalTypeHandler
自定义类型处理器:
1.实现TypeHandler接口,或者继承BaseTypeHandler
2.在全局配置文件中使用这个类型处理器
自定义类型处理器:
package cn.it.mybatis.typehandler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import cn.it.mybatis.baen.EnumEpmStatus; public class MyEnumEpmStatusTypeHandler implements TypeHandler<EnumEpmStatus> { @Override public void setParameter(PreparedStatement ps, int i, EnumEpmStatus parameter, JdbcType jdbcType) throws SQLException { // TODO Auto-generated method stub ps.setString(i, parameter.getCode().toString()); } @Override public EnumEpmStatus getResult(ResultSet rs, String columnName) throws SQLException { // TODO Auto-generated method stub // 需要根据从数据库中拿到的枚举状态码返回一个枚举对象 int code = rs.getInt(columnName); System.out.println("从数据库中获取的状态码:" + code); EnumEpmStatus enumEpmStatusByCode = EnumEpmStatus.getEnumEpmStatusByCode(code); return enumEpmStatusByCode; } @Override public EnumEpmStatus getResult(ResultSet rs, int columnIndex) throws SQLException { // TODO Auto-generated method stub int code = rs.getInt(columnIndex); System.out.println("从数据库中获取的状态码:" + code); EnumEpmStatus enumEpmStatusByCode = EnumEpmStatus.getEnumEpmStatusByCode(code); return enumEpmStatusByCode; } @Override public EnumEpmStatus getResult(CallableStatement cs, int columnIndex) throws SQLException { // TODO Auto-generated method stub int code = cs.getInt(columnIndex); System.out.println("从数据库中获取的状态码:" + code); EnumEpmStatus enumEpmStatusByCode = EnumEpmStatus.getEnumEpmStatusByCode(code); return enumEpmStatusByCode; } }