11 拓展

拓展

PageHelper分页插件使用

PageHelper是MyBatis中非常方便的第三方分页
插件。
• 官方文档:
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
• 我们可以对照官方文档的说明,快速的使用插件

• 1、导入相关包pagehelper-x.x.x.jar 和 jsqlparser-0.9.5.jar。
• 2、在MyBatis全局配置文件中配置分页插件。

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

• 3、使用PageHelper提供的方法进行分页
• 4、可以使用更强大的PageInfo封装返回结果

    @Test
    public void test01() throws IOException {
       //1.获取到 SqlSessionFactory 对象
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

        //2.获取 sqlSession 对象
        SqlSession openSession = sqlSessionFactory.openSession();

        try {
            //3.获取接口的实现类对象
            //会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            Page<Object> page = PageHelper.startPage(1, 5);
            List<Employee> emps = mapper.getEmps();

            //第二种
            PageInfo<Employee> info = new PageInfo<>(emps);

            for (Employee e:emps){
                System.out.println(e);
            }
//            System.out.println("当前页码:"+ page.getPageNum());
//            System.out.println("总记录数" + page.getTotal());
//            System.out.println("每页的记录数" + page.getPageSize());
//
            System.out.println("当前页码:"+ info.getPageNum());
            System.out.println("总记录数" + info.getTotal());
            System.out.println("每页的记录数" + info.getPageSize());
        } finally {
            openSession.close();
        }
    }

批量操作

• 默认的 openSession() 方法没有参数,它会创建有如下特性的
– 会开启一个事务(也就是不自动提交)
– 连接对象会从由活动环境配置的数据源实例得到。
– 事务隔离级别将会使用驱动或数据源的默认设置。
– 预处理语句不会被复用,也不会批量处理更新。

• openSession 方法的 ExecutorType 类型的参数,枚举类型:
– ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情(这是默认装配的)。它为每个语句的执行创建一个新的预处理语句。
– ExecutorType.REUSE: 这个执行器类型会复用预处理语句。
– ExecutorType.BATCH: 这个执行器会批量执行所有更新语

•批量操作我们是使用MyBatis提供的BatchExecutor进行的,他的底层就是通过jdbc攒sql的方式进行的。我们可以让他攒够一定数量后发给数据库一次。

    @Test
    public void testBatch() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //可以批量操作的sqlSession
        SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH);

        try {
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
            mapper.addEmps(new Employee(UUID.randomUUID().toString().substring(0,5),"e","1"));
            
        } finally {
        }

    }

• 与Spring整合中,我们推荐,额外的配置一个可以专门用来执行批量操作的sqlSession

<bean id="sqlSession" class="org.mybatis.spring.sqlSessionTemplate">
	<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
    <constructor-arg name="executorType" ref="BATH"></constructor-arg>
</bean>

需要用到批量操作的时候,我们可以注入配置的这个批量SqlSession。通过他获取到mapper映射器进行操作。
• 注意:
• 1、批量操作是在session.commit()以后才发送sql语句给数据库进行执行的
• 2、如果我们想让其提前执行,以方便后续可能的查询操作获取数据,我们可以使用sqlSession.flushStatements()方法,让其直接冲刷到数据库进行执行

存储过程

• 实际开发中,我们通常也会写一些存储过程,
MyBatis也支持对存储过程的调用
• 一个最简单的存储过程
delimiter $$
create procedure test()
begin
select 'hello';
end $$
delimiter ;
• 存储过程的调用
1、select标签中statementType=“CALLABLE”
2、标签体中调用语法:

存储过程-游标处理

• MyBatis对存储过程的游标提供了一个JdbcType=CURSOR的支持,
可以智能的把游标读取到的数据,映射到我们声明的结果集中
• 调用实例

    <!--     public void getPageByProcedure();
    1、使用select标签定义存储过程
     2、statementType="CALLABLE":表示要调用存储过程
    -->
    <select id="getPageByProcedure" statementType="CALLABLE">
        {call ,hello_test(
                #{start,mode=IN,jdbcType=INTEGER},
                #{end,mode=IN,jdbcType=INTEGER},
                #{count,mode=OUT,jdbcType=INTEGER},
                #{emps,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=PageEmp}
            )}
    </select>
orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521:orcl
orcl.username=scott
orcl.password=123456

orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521:orcl
orcl.username=scott
orcl.password=123456

<environment id="oracle_dev">
    <transactionManager type="JDBC" />
    <dataSource type="POOLED">
        <property name="driver" value="${orcl.driver}" />
        <property name="url" value="${orcl.url}" />
        <property name="username" value="${orcl.username}" />
        <property name="password" value="${orcl.password}" />
    </dataSource>
</environment>

<databaseIdProvider type="DB_VENDOR">
    <property name="MySQL" value="mysql"/>
    <property name="Oracle" value="oracle"/>
</databaseIdProvider>

自定义TypeHandler处理枚举

• 我们可以通过自定义TypeHandler的形式来在设置参数或者取出结果集的时候自定义参数封装策略。
• 步骤:
– 1、实现TypeHandler接口或者继承BaseTypeHandler
– 2、使用@MappedTypes定义处理的java类型
使用@MappedJdbcTypes定义jdbcType类型
– 3、在自定义结果集标签或者参数处理的时候声明使用自定义
TypeHandler进行处理或者在全局配置TypeHandler要处理的javaType

1、测试全局配置EnumOrdinalTypeHandler

    <typeHandlers>
        <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.atguigu.mybatis.bean.EmpStatus"/>
    </typeHandlers>

2 、测试参数位置设置自定义TypeHandler

<insert id="addDept">
	insert into tbl_dept
    values(#{deptName},#{status,typeHandeler=com.atgui.mybatis.dao.MyEnumEmpStatusTypeHandler})
</insert>

    <typeHandlers>
        <!--1、配置我们自定义的TypeHandler-->
        <typeHandler handler="com.atgui.mybatis.dao.MyEnumEmpStatusTypeHandler" javaType="com.atguigu.mybatis.bean.EmpStatus"/>
        <!--2、也可以在处理某个字段的时候告诉MyBatis用什么类型处理器
            保存:#{empStatus,typeHandler=xxxx}
            注意:如果在参数位置修改TypeHandler,应该保证保存数据和查询数据用的TypeHandler是一样的
        -->
    </typeHandlers>

/*
*
* 1、实现TypeHandler,或者继承BaseTypeHandler
* */
public class MyEnumEmpStatusTypeHandler implements TypeHandler<EmpStatus> {

    /*
    *  定义当前数据如何保存到数据库中
    * */
    @Override
    public void setParameter(PreparedStatement ps, int i, EmpStatus parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i,parameter.getCode().toString());

    }

    @Override
    public EmpStatus getResult(ResultSet rs, String columnName) throws SQLException {
        //需要根据从数据库中拿到的枚举的状态码返回一个枚举对象
        int code = rs.getInt(columnName);
        System.out.println(code);
        EmpStatus status = EmpStatus.getEmsStatusByCode(code);
        return status;
    }

    @Override
    public EmpStatus getResult(ResultSet rs, int columnIndex) throws SQLException {
        int code = rs.getInt(columnIndex);
        System.out.println(code);
        EmpStatus status = EmpStatus.getEmsStatusByCode(code);
        return status;
    }

    @Override
    public EmpStatus getResult(CallableStatement cs, int columnIndex) throws SQLException {
        int code = cs.getInt(columnIndex);
        System.out.println(code);
        EmpStatus status = EmpStatus.getEmsStatusByCode(code);
        return status;
    }
}


posted @   flypiggg  阅读(33)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示