Mybatis插件和批量操作

扩展一个简单的实现 

@Intercepts({
        @Signature(type = StatementHandler.class,method = "parameterize",args = java.sql.Statement.class)
})
public class MyFirstPlugin implements Interceptor {
    /**
     * intercept:拦截
     *      拦截目标对象的方法的执行
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("MyFirstPlugin....interceptor:"+invocation.getMethod());

        //动态改变sql运行的参数:以前1号员工,现在4号

        Object target = invocation.getTarget();
        System.out.println("当前拦截对象:"+target);
        //拿到StatementHandler====》ParameterHandler===》ParameterObject
        //拿到目标对象target的元数据
        MetaObject metaObject = SystemMetaObject.forObject(target);
        Object value = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("SQL语句用的参数是"+value);
        metaObject.setValue("parameterHandler.parameterObject",4);


        //执行目标方法
        Object proceed = invocation.proceed();
        //返回执行后的返回值
        return proceed;
    }

    /**
     * plugin:包装目标对象——包装:为目标对象创建一个代理类
     * @param target
     * @return
     */
    @Override
    public Object plugin(Object target) {
        System.out.println("MyFirstPlugin....plugin:mybatis将要包装的对象"+target);
        //我们可以借助Plugin的wrap方法来使用当前的intercept包装我们目标对象
        Object wrap = Plugin.wrap(target, this);
        //返回为当前target创建好的动态代理
        return wrap;
    }

    /**
     * setProperties:将插件注册时的property属性设置进来
     * @param properties
     */
    @Override
    public void setProperties(Properties properties) {
        System.out.println("插件配置的信息"+properties);
    }
}


@Test
public void testPlugin() throws IOException {
    SqlSession sqlSession = getSqlSession();
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
    Employee e = mapper.getEmps(1);
    System.out.println(e);
}


分页插件pageHelper

配置依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.2</version>
</dependency>

在全局配置文件中配置拦截器

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

在代码中使用PageHelper.startPage( )即可实现分页

@Test
public void test() throws IOException {
    SqlSession sqlSession = getSqlSession();
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

    PageHelper.startPage(1,5);

    List<Employee> employeeList = mapper.getEmps();
    for (Employee e:employeeList) {
        System.out.println(employeeList);
    }
}

插件会自动查询数量和进行分页的sql


其他信息

@Test
public void test() throws IOException {
    SqlSession sqlSession = getSqlSession();
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

    Page<Object> page = PageHelper.startPage(1, 5);

    List<Employee> employeeList = mapper.getEmps();
    for (Employee e:employeeList) {
        System.out.println(employeeList);
    }

    System.out.println("当前页码"+page.getPageNum());
    System.out.println("总记录数"+page.getTotal());
    System.out.println("每页记录数"+page.getPageSize());
    System.out.println("总页码"+page.getPages());
}

还可以使用PageInfo达到更多分页的信息:

@Test
public void test() throws IOException {
    SqlSession sqlSession = getSqlSession();
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

    Page<Object> page = PageHelper.startPage(1, 5);

    List<Employee> employeeList = mapper.getEmps();

    PageInfo info = new PageInfo(employeeList);

    for (Employee e:employeeList) {
        System.out.println(employeeList);
    }

    System.out.println("当前页码"+info.getPageNum());
    System.out.println("总记录数"+info.getTotal());
    System.out.println("每页记录数"+info.getPageSize());
    System.out.println("总页码"+info.getPages());
    System.out.println("是否第一页"+info.isIsFirstPage());
    System.out.println("是否最后一页"+info.isIsLastPage());
批量操作

可以使用<foreach>标签做批量,但是使用这个标签是对sql执行拼接,但是比如MySQL数据库对于大量数据的这种处理是特别麻烦!

使用批量:

@Test
public void testBatch() throws IOException {
   String str = "mybatis-config.xml";
   Reader reader = Resources.getResourceAsReader(str);
   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    //可以执行批量操作sqlSession
    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.addEmployee(new Employee(UUID.randomUUID().toString().substring(1,5)+"lala","1","lala@qq.com"));
        }
        sqlSession.commit();
        long end = System.currentTimeMillis();
        System.out.println("执行的时长"+(end-start));
    } finally {
        sqlSession.close();
    }
}


预编译SQL一次==》设置参数10000次==》数据库执行(批量,1次)

非批量:

public void testBatch() throws IOException {
   String str = "mybatis-config.xml";
   Reader reader = Resources.getResourceAsReader(str);
   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    //可以执行批量操作sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            mapper.addEmployee(new Employee(UUID.randomUUID().toString().substring(1,5)+"lala","1","lala@qq.com"));
        }
        sqlSession.commit();
        long end = System.currentTimeMillis();
        System.out.println("执行的时长"+(end-start));
    } finally {
        sqlSession.close();
    }
}


预编译SQL==》设置参数==》执行——调用多少次执行多少次


与spring整合的时候,批量:

在spring配置文件中:

<!--配置一个可以批量执行的SqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
    <constructor-arg name="executorType" value="BATCH"/>
</bean>

使用:在service中

@Autowired
private SqlSession sqlSession;
这个就是可以使用批量的SqlSession


posted @ 2018-05-27 00:01  惶者  阅读(603)  评论(0编辑  收藏  举报