1. 分页功能
具体使用可参见github中的官方说明,地址为:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md。
实现步骤:
- 导入相关包pagehelper-x.x.x.jar 和 jsqlparser-0.9.5.jar;
- 在MyBatis全局配置文件中配置分页插件;
- 使用PageHelper提供的方法进行分页;
- 可以使用更强大的PageInfo封装返回结果。
2. 批量操作
主要使用MyBatis框架的配置defaultExecutorType=BATCH,以创建BatchExecutor执行数据库操作。具体测试代码段如下所示:
/**
* 批量操作:ExecutorType.BATCH
* @throws Exception
*/
@Test
public void test() throws Exception {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
long start = System.currentTimeMillis();
for(int i = 0; i < 10000; i++) {
mapper.addEmp(new Employee(null, "name" + i, "1", "name" + i + "@163.com"));
}
sqlSession.commit();
long end = System.currentTimeMillis();
// 批量执行时:预编译1次 ==> 设置参数10000次 ==> 执行1次,执行时长:4115
// 非批量执行时:预编译、设置参数和执行均10000次,执行时长较长
System.out.println("执行时长:" + (end - start));
} finally {
sqlSession.close();
}
}
如果将MyBatis框架与Spring整合,则需要在applicationContext.xml文件中配置:
<!--创建出SqlSessionFactory对象 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- configLocation指定全局配置文件的位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--mapperLocations: 指定mapper文件的位置-->
<property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"></property>
</bean>
<!--配置一个可以进行批量执行的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对象注入,代码如下:
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Autowired
private SqlSession sqlSession;
public List<Employee> getEmps(){
return employeeMapper.getEmps();
}
}
注意:
- 批量操作是在
sqlSession.commit()
后才发送SQL语句给数据库进行执行的; - 如果想让其提前执行,以方便后续可能的查询操作获取数据,可使用
sqlSession.flushStatements()
方法,让其直接冲刷到数据库进行执行。
3. 存储过程
实际开发中,通常会写一些存储过程以方便后续使用,MyBatis也支持对存储过程的调用。
MySQL中一个简单的存储过程如下:
delimiter $$
create procedure test()
begin
select 'hello';
end $$
delimiter ;
存储过程的调用:
- select标签中
statementType="CALLABLE"
; - 标签体中调用语法:
{call procedure_name(#{param1_info},#{param2_info})}
。
存储过程-游标处理:
MyBatis对存储过程的游标提供了一个JdbcType=CURSOR
的支持,可以智能的把游标读取到的数据,映射到声明的结果集中。
Oracle数据库创建存储过程如下:
查询标签如下,其中的结果集封装省略:
4. 自定义类型处理器
创建自定义的类型处理器:
/**
* 1、实现TypeHandler接口。或者继承BaseTypeHandler
*/
public class MyEnumEmpStatusTypeHandler implements TypeHandler<EmpStatus> {
/**
* 定义当前数据如何保存到数据库中
*/
@Override
public void setParameter(PreparedStatement ps, int i, EmpStatus parameter,
JdbcType jdbcType) throws SQLException {
// TODO Auto-generated method stub
System.out.println("要保存的状态码:"+parameter.getCode());
ps.setString(i, parameter.getCode().toString());
}
@Override
public EmpStatus getResult(ResultSet rs, String columnName)
throws SQLException {
// TODO Auto-generated method stub
//需要根据从数据库中拿到的枚举的状态码返回一个枚举对象
int code = rs.getInt(columnName);
System.out.println("从数据库中获取的状态码:"+code);
EmpStatus status = EmpStatus.getEmpStatusByCode(code);
return status;
}
@Override
public EmpStatus getResult(ResultSet rs, int columnIndex)
throws SQLException {
// TODO Auto-generated method stub
int code = rs.getInt(columnIndex);
System.out.println("从数据库中获取的状态码:"+code);
EmpStatus status = EmpStatus.getEmpStatusByCode(code);
return status;
}
@Override
public EmpStatus getResult(CallableStatement cs, int columnIndex)
throws SQLException {
// TODO Auto-generated method stub
int code = cs.getInt(columnIndex);
System.out.println("从数据库中获取的状态码:"+code);
EmpStatus status = EmpStatus.getEmpStatusByCode(code);
return status;
}
}
使用自定义的类型处理器:
<typeHandlers>
<!--1、配置自定义的TypeHandler -->
<typeHandler handler="com.atguigu.mybatis.typehandler.MyEnumEmpStatusTypeHandler" javaType="com.atguigu.mybatis.bean.EmpStatus"/>
<!--2、也可以在处理某个字段的时候告诉MyBatis用什么类型处理器
保存:#{empStatus,typeHandler=xxxx}
查询:
<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmp">
<id column="id" property="id"/>
<result column="empStatus" property="empStatus" typeHandler=""/>
</resultMap>
注意:如果在参数位置修改TypeHandler,应该保证保存数据和查询数据用的TypeHandler是一样的。
-->
</typeHandlers>
待处理的枚举类为:
public enum EmpStatus {
LOGIN("100", "登录成功"), LOGOUT("200", "退出成功"), REMOVE("300", "用户不存在");
private String code;
private String message;
private EmpStatus(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static EmpStatus getEmpStatusByCode(String code) {
switch (code) {
case "100":
return LOGIN;
case "200":
return LOGOUT;
case "300":
return REMOVE;
default:
return LOGOUT;
}
}
}