您的位置:首页 > 其它

SSM框架中集成TKMybatis+PageHelper实现高效查询和分页

2017-08-26 12:18 931 查看
Mybatis 通用 Mapper  极其方便的使用 Mybatis 单表的增删改查,支持单表操作,不支持通用的多表联合查询

优点:

通用 Mapper 可以极大的方便开发人员。 
通用 Mapper 可以缓存,全部针对单表操作,每个实体类都需要继承通用 Mapper 接口来获得通用方法。

TKMybatis依赖包:

javax.persistence-2.1.0.jar

mapper-3.3.8.jar

PageHelper依赖包:

pagehelper-4.0.0.jar

jsqlparser-0.9.1.jar

在pom.xml增加

<dependency>

    <groupId>tk.mybatis</groupId>

    <artifactId>mapper</artifactId>

    <version>3.3.8</version>

</dependency>

  <dependency>

    <groupId>org.eclipse.persistence</groupId>

    <artifactId>javax.persistence</artifactId>

    <version>2.1.0</version>

</dependency>

  

<dependency>

    <groupId>com.github.pagehelper</groupId>

    <artifactId>pagehelper</artifactId>

    <version>4.0.0</version>

</dependency>

spring-mybatis.xml修改

<!-- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">-->

<!-- <property name="basePackage" value="com.tk.dao" />-->

<!-- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>-->

<!-- </bean> -->

改为:

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="basePackage" value="com.tk.dao" />
   <property name="properties">
       <value> 
           mappers=tk.mybatis.mapper.common.Mapper,tk.mybatis.mapper.common.special.InsertListMapper
       </value>
   </property>
   <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>

</bean>

给model增加注释

@Table(name = "slee")
public class SLee implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

private static final long serialVersionUID = 1L;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}
}


新建一个B
4000
aseMapper<T>接口类(名称自定义)并继承Mapper<T>,InsertListMapper<T>

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.special.InsertListMapper;

public interface  BaseMapper<T> extends Mapper<T>,InsertListMapper<T>{

}

修改mapper接口类并注释掉常用方法。也需要注释掉对应mapper.xml里的相关查询

package com.tk.dao; 

import com.tk.entity.SBaby;

import com.tk.util.BaseMapper;

public interface SBabyMapper extends BaseMapper<SBaby>{

 //int deleteByPrimaryKey(Integer id); 

 //int insert(SBaby record);

 //int insertSelective(SBaby record);

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tk.dao.SBabyMapper">
<resultMap id="BaseResultMap" type="com.tk.entity.SBaby">
<id column="id" jdbcType="INTEGER" property="id" />
</resultMap>
<!--  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">-->
<!--    delete from sbaby-->
<!--    where id = #{id,jdbcType=INTEGER}-->
<!--  </delete>-->
<!--  <insert id="insert" parameterType="com.tk.entity.SBaby">-->
<!--    insert into sbaby (id)-->
<!--    values (#{id,jdbcType=INTEGER})-->
<!--  </insert>-->
<!--  <insert id="insertSelective" parameterType="com.tk.entity.SBaby">-->
<!--    insert into sbaby-->
<!--    <trim prefix="(" suffix=")" suffixOverrides=",">-->
<!--      <if test="id != null">-->
<!--        id,-->
<!--      </if>-->
<!--    </trim>-->
<!--    <trim prefix="values (" suffix=")" suffixOverrides=",">-->
<!--      <if test="id != null">-->
<!--        #{id,jdbcType=INTEGER},-->
<!--      </if>-->
<!--    </trim>-->
<!--  </insert>-->

</mapper>


对应service

package com.tk.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import com.tk.dao.SBabyMapper;

import com.tk.dao.SLeeMapper;

import com.tk.entity.SBaby;

import com.tk.entity.SLee;

import com.tk.service.ISBabyService;

@Service("sbabyService")

public class SBabyServiceImpl implements ISBabyService{

@Resource
private SBabyMapper babyDao;

public int insertbaby(SBaby baby) {
return babyDao.insertSelective(baby);
}

public List<SBaby> getAll() {
// TODO Auto-generated method stub
return babyDao.selectAll();
}

}

以上就是实现了tkmybatis的过程。通过dao可以直接调用已有的方法,不需要再去写mapper.xml查询就可以直接实现过程接下来配置pagehelper有两种方式:

 第一种:直接在spring-mybatis.xml里配置
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/tk/dao/*.xml"></property>

<property name="plugins">
   <array>
     <bean class="com.github.pagehelper.PageHelper">
       <property name="properties">
         <value>
           dialect=mysql
         </value>
       </property>
     </bean>
   </array>
</property>

<!-- <property name="configLocation" value="classpath:mybatis-config.xml"/>-->

</bean> 

第二种:configLocation属性指向的mybatis-config.xml文件,有关分页插件的配置都在mybatis-config.xml 在mybatis-config.xml新增

<plugins>  

        <!-- com.github.pagehelper为PageHelper类所在包名 -->  

        <plugin interceptor="com.github.pagehelper.PageHelper">  

            <!-- 4.0.0以后版本可以不设置该参数 -->  

            <property name="dialect" value="mysql"/>  

            <!-- 该参数默认为false -->  

            <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->  

            <!-- 和startPage中的pageNum效果一样-->  

            <property name="offsetAsPageNum" value="true"/>  

            <!-- 该参数默认为false -->  

            <!-- 设置为true时,使用RowBounds分页会进行count查询 -->  

            <property name="rowBoundsWithCount" value="true"/>  

            <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->  

            <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->  

            <property name="pageSizeZero" value="true"/>  

            <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->  

            <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->  

            <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->  

            <property name="reasonable" value="true"/>  

            <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->  

            <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->  

            <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->  

            <!-- 不理解该含义的前提下,不要随便复制该配置 -->  

            <property name="params" value="pageNum=start;pageSize=limit;"/>  

            <!-- 支持通过Mapper接口参数来传递分页参数 -->  

            <property name="supportMethodsArguments" value="true"/>  

            <!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->  

            <property name="returnPageInfo" value="check"/>  

        </plugin>  

    </plugins> 

通过spring-mybatis.xml进行mybatis-config.xml的引用

<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --> 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 

<property name="dataSource" ref="dataSource" /> 

<!-- 自动扫描mapping.xml文件 --> 

<property name="mapperLocations" value="classpath:com/tk/dao/*.xml"></property> 

<property name="configLocation" value="classpath:mybatis-config.xml"/> 

</bean> 

现在在Controller进行测试

package com.tk.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.transaction.annotation.Transactional;

import org.springframework.web.bind.annotation.RequestMapping;

 

import com.github.pagehelper.Page;

import com.github.pagehelper.PageHelper;

import com.github.pagehelper.PageInfo;

import com.tk.entity.SBaby;

import com.tk.service.ISBabyService;

@Controller

public class SBabyController {

@Autowired

private ISBabyService sbabyService;

@RequestMapping("getSBaby") 

public String  getAll(HttpServletRequest request)  {

try {

SBaby baby=new SBaby(); 

int a=sbabyService.insertbaby(baby);//插入数据

//获取第2页,5条内容,默认查询总数count

PageHelper.startPage(2, 5);

//PageHelper只对紧跟着的第一个SQL语句起作用

List<SBaby> list=sbabyService.getAll(); //调用service对应的方法

//后面的不会被分页,除非再次调用PageHelper.startPage

List<SBaby> list2=sbabyService.getAll(); //调用service对应的方法

//用PageInfo对结果进行包装

PageInfo page = new PageInfo(list);

request.setAttribute("STypeLists", list ); 

} catch (Exception e) {

e.printStackTrace();

}

return "listAll";

}

}

对PageHelper的说明:

PageHelper只对紧跟着的第一个SQL语句起作用

pageHelper会使用ThreadLocal获取到同一线程中的变量信息,各个线程之间的Threadlocal不会相互干扰,也就是Thread1中的ThreadLocal1之后获取到Tread1中的变量的信息,不会获取到Thread2中的信息

所以在多线程环境下,各个Threadlocal之间相互隔离,可以实现,不同thread使用不同的数据源或不同的Thread中执行不同的SQL语句

所以,PageHelper利用这一点通过拦截器获取到同一线程中的预编译好的SQL语句之后将SQL语句包装成具有分页功能的SQL语句,并将其再次赋值给下一步操作,所以实际执行的SQL语句就是有了分页功能的SQL语句

如上:所以若一个方法中涉及到多个查询,需要小心,避免为不需要分页的添加了分页,而真正需要分页的却没有被分页

PageHelper.startPage(pageNum, pageSize)

PageHelper.startPage(pageNum, pageSize, count)

PageHelper.startPage(pageNum, pageSize, count, reasonable)

PageHelper.startPage(pageNum, pageSize, count, reasonable, pageSizeZero)

参数说明

pageNum 页码

pageSize 每页显示数量

count 是否进行count查询

reasonable 分页合理化,null时用默认配置

pageSizeZero true且pageSize=0时返回全部结果,false时分页,null时用默认配置

PageInfo page = new PageInfo(list);

//PageInfo全部属性

//PageInfo包含了非常全面的分页属性

page.getPageNum();

page.getPageSize();

page.getStartRow();

page.getEndRow();

page.getTotal();

page.getPages();

page.getFirstPage();

page.getLastPage(); 

page.isIsFirstPage();

page.isIsLastPage();

page.isHasPreviousPage();

page.isHasNextPage();

分页的两种方式:

第一种RowBounds:在mapper.java中的方法中传入RowBounds对象。

第二种PageHelper:在调用查询方法之前调用。PageHelper只对紧跟着的第一个SQL语句起作用.上面主要介绍的是第二种



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: