MyBatis-09 扩展

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

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值