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

来源:互联网 发布:微软人工智能框架 编辑:程序博客网 时间:2024/05/24 02:39
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;    }}


新建一个BaseMapper<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语句起作用.上面主要介绍的是第二种

 
原创粉丝点击