MyBatis的扩展应用

本文介绍MyBatis的批量操作方法,包括使用PageHelper分页插件、批量插入数据的效率对比,以及自定义类型处理器处理枚举类型的详细步骤。通过实例演示了批量操作的执行速度优势,并提供了在Spring环境中配置批量执行SqlSession的方法。

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;
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值