在spring-mybatis.xml 中配置pagehelper
maven导包:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
spring-mybatis.xml 中:
注册: <bean id="defaultSqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="你的数据源配置"/> <property name="configuration"> <bean class="org.apache.ibatis.session.Configuration"> <property name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl"/> <property name="aggressiveLazyLoading" value="false"/> <property name="autoMappingUnknownColumnBehavior" value="WARNING"/> <property name="databaseId" value="mysql"/> <property name="lazyLoadingEnabled" value="true"/> <property name="lazyLoadTriggerMethods" value="equals,hashCode,toString,clone,toJSON"/> <property name="localCacheScope" value="SESSION"/> <property name="useGeneratedKeys" value="true"/> </bean> </property> <!-- 指定mybatis的全局配置文件 --> <!-- <property name="configLocation" value="classpath:mybatis-config.xml"/> --> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <value> helperDialect=sqlserver </value> </property> </bean> </array> </property> <property name="mapperLocations" value="classpath*:mybatis-mappers/*Mapper.xml"/> <!-- 设置包中类的别名 --> <property name="typeAliasesPackage" value="com.keepbreath.entity"/> </bean>
如此即可使用:在查询语句的上一行代码写上:PageHelper.startPage(pageNumber, pageSize)
-
增加
dialect
属性,使用时可以指定该属性(不指定的情况下,分页插件会自动判断),可选值为oracle
,mysql
,mariadb
,sqlite
,hsqldb
,postgresql
,db2
,sqlserver
,informix
,h2
,sqlserver2012
。 -
增加
offsetAsPageNum
属性,默认值为false
,使用默认值时不需要增加该配置,需要设为true
时,需要配置该参数。当该参数设置为true
时,使用RowBounds
分页时,会将offset
参数当成pageNum
使用,可以用页码和页面大小两个参数进行分页。 -
增加
rowBoundsWithCount
属性,默认值为false
,使用默认值时不需要增加该配置,需要设为true
时,需要配置该参数。当该参数设置为true
时,使用RowBounds
分页会进行count查询。 -
增加
pageSizeZero
属性,默认值为false
,使用默认值时不需要增加该配置,需要设为true
时,需要配置该参数。当该参数设置为true
时,如果pageSize=0
或者RowBounds.limit = 0
就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page
类型)。 -
增加
reasonable
属性,默认值为false
,使用默认值时不需要增加该配置,需要设为true
时,需要配置该参数。具体作用请看上面配置文件中的注释内容。 -
为了支持
startPage(Object params)
方法,增加了一个params
参数来配置参数映射,用于从Map或ServletRequest中取值,可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值。 -
supportMethodsArguments
支持通过Mapper接口参数来传递分页参数,默认值false
,具体用法参考com.github.pagehelper.test.basic
包下的ArgumentsMapTest
和ArgumentsObjTest
测试类。 -
returnPageInfo
用来支持直接返回PageInfo
类型,默认值none
,可选参数always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page(List)类型。用法和配置参考com.github.pagehelper.test.basic
包下的PageInfoTest
,特别要注意接口的返回值和xml中的resultType
类型。 -
增加
closeConn
属性,当使用动态数据源或没有设置dialect
属性自动获取数据库类型时,会自动获取一个数据库连接,通过该属性来设置是否关闭获取的这个连接,默认true
关闭。
重要提示:
当offsetAsPageNum=false
的时候,由于PageNum问题,RowBounds
查询的时候reasonable会强制为false。使用PageHelper.startPage
方法不受影响。
另外使用RowBounds
在这种情况下返回的Page
对象由于没有正确的pageNum
属性,所以也不能使用PageInfo
处理。
如果你不理解为什么,可以看这样一个例子:查询offset=7,limit=10
,这个时候pageNum=?
,这种情况没法计算pageNum
,没法判断当前是第几页
实例编写
public interface UserInfoMapper extends Mapper<UserInfo> { //其他必须手写的接口... }
一旦继承了Mapper<T>
,继承的Mapper
就拥有了以下通用的方法:
//根据实体类不为null的字段进行查询,条件全部使用=号and条件 List<T> select(T record); //根据实体类不为null的字段查询总数,条件全部使用=号and条件 int selectCount(T record); //根据主键进行查询,必须保证结果唯一 //单个字段做主键时,可以直接写主键的值 //联合主键时,key可以是实体类,也可以是Map T selectByPrimaryKey(Object key); //插入一条数据 //支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写) //优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长 int insert(T record); //插入一条数据,只插入不为null的字段,不会影响有默认值的字段 //支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写) //优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长 int insertSelective(T record); //根据实体类中字段不为null的条件进行删除,条件全部使用=号and条件 int delete(T key); //通过主键进行删除,这里最多只会删除一条数据 //单个字段做主键时,可以直接写主键的值 //联合主键时,key可以是实体类,也可以是Map int deleteByPrimaryKey(Object key); //根据主键进行更新,这里最多只会更新一条数据 //参数为实体类 int updateByPrimaryKey(T record); //根据主键进行更新 //只会更新不是null的数据 int updateByPrimaryKeySelective(T record);
4. 泛型(实体类)<T>
的类型必须符合要求
实体类按照如下规则和数据库表进行转换,注解全部是JPA中的注解:
-
表名默认使用类名,驼峰转下划线,如
UserInfo
默认对应的表名为user_info
. -
表名可以使用
@Table(name = "tableName")
进行指定,对不符合第一条默认规则的可以通过这种方式指定表名. -
字段默认和
@Column
一样,都会作为表字段,表字段默认为Java对象的Field
名字驼峰转下划线形式. -
可以使用
@Column(name = "fieldName")
指定不符合第3条规则的字段名 -
使用
@Transient
注解可以忽略字段,添加该注解的字段不会作为表字段使用. -
建议一定是有一个
@Id
注解作为主键的字段,可以有多个@Id
注解的字段作为联合主键. -
默认情况下,实体类中如果不存在包含
@Id
注解的字段,所有的字段都会作为主键字段进行使用(这种效率极低). -
实体类可以继承使用,可以参考测试代码中的
com.github.abel533.model.UserLogin2
类. -
由于基本类型,如int作为实体类字段时会有默认值0,而且无法消除,所以实体类中建议不要使用基本类型.
除了上面提到的这些,Mapper还提供了序列(支持Oracle)、UUID(任意数据库,字段长度32)、主键自增(类似MySQL,Hsqldb)三种方式,其中序列和UUID可以配置多个,主键自增只能配置一个。