看本文之前,請確保你已經在SpringBoot中集成MyBatis,並能正常使用。
如果沒有,那么請先移步 http://blog.csdn.net/catoop/article/details/50553714 做了解后,再按本文步驟操作。
使用MyBatis在我們通過xml集中配置SQL,並通過創建接口Mapper文件來完成持久化DAO層(mybatis內部使用的是動態代理,所以我們不需要自己編寫實現類)。
然而在實際開發中,單表操作非常多,如果你也想像JPA、JDBC那樣做一個所謂的BaseDao。那么可以實現一個通用Mapper來達到目的。現在有現成的通用Mapper插件,我們無需重新創造輪子(代碼是開源的,你也可以自己在其基礎上修改)。
通用Mapper插件網址:http://git.oschina.net/free/Mapper
下面是使用方法(本文直接將分頁插件PageHelper也集成了):
一、添加或修改pom依賴
<!-- MyBatis --> <!-- <dependency> --> <!-- <groupId>org.mybatis.spring.boot</groupId> --> <!-- <artifactId>mybatis-spring-boot-starter</artifactId> --> <!-- <version>1.0.1-SNAPSHOT</version> --> <!-- </dependency> --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.1</version> </dependency> <!--通用Mapper插件--> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>3.3.4</version> </dependency>
這里說一下,文章開始指定的那篇文章中直接依賴的mybatis的starter。因為本文在集成通用Mapper的時候直接使用出現了錯誤,所以將mybatis的starter中的Java類(它本身只有2個Java類,非常簡單)拷貝到工程中,注釋掉了頭部的//@ConditionalOnBean(DataSource.class),你不用去找那2個類的源碼了,下面會粘貼出來。
二、將下面4個Java類加入到工程中
將文件
MybatisAutoConfiguration.java
MyBatisMapperScannerConfig.java
MybatisProperties.java
MyMapper.java
添加到 org.springboot.sample.config.mybatis 中(包名根據自己工程修改)
最有一個MyMapper.java要特別注意,不要把MyMapper放到同其他Mapper一起,該類不能被當做普通Mapper一樣被掃描,否則會出錯。
package org.springboot.sample.config.mybatis; import java.util.Properties; import javax.annotation.PostConstruct; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import com.github.pagehelper.PageHelper; /** * {@link EnableAutoConfiguration Auto-Configuration} for Mybatis. Contributes a * {@link SqlSessionFactory} and a {@link SqlSessionTemplate}. * * If {@link org.mybatis.spring.annotation.MapperScan} is used, or a configuration file is * specified as a property, those will be considered, otherwise this auto-configuration * will attempt to register mappers based on the interface definitions in or under the * root auto-configuration package. * * @author Eddú Meléndez * @author Josh Long */ @Configuration @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class }) //@ConditionalOnBean(DataSource.class) @EnableConfigurationProperties(MybatisProperties.class) @AutoConfigureAfter(DataSourceAutoConfiguration.class) public class MybatisAutoConfiguration { private static Log log = LogFactory.getLog(MybatisAutoConfiguration.class); @Autowired private MybatisProperties properties; @Autowired(required = false) private Interceptor[] interceptors; @Autowired private ResourceLoader resourceLoader = new DefaultResourceLoader(); @PostConstruct public void checkConfigFileExists() { if (this.properties.isCheckConfigLocation()) { Resource resource = this.resourceLoader .getResource(this.properties.getConfig()); Assert.state(resource.exists(), "Cannot find config location: " + resource + " (please add config file or check your Mybatis " + "configuration)"); } } @Bean(name = "sqlSessionFactory") @ConditionalOnMissingBean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); if (StringUtils.hasText(this.properties.getConfig())) { factory.setConfigLocation( this.resourceLoader.getResource(this.properties.getConfig())); } else { if (this.interceptors != null && this.interceptors.length > 0) { factory.setPlugins(this.interceptors); } factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); factory.setMapperLocations(this.properties.getMapperLocations()); } return factory.getObject(); } @Bean @ConditionalOnMissingBean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory, this.properties.getExecutorType()); } /** * 分頁插件 * * @param dataSource * @return * @author SHANHY * @create 2016年2月18日 */ @Bean public PageHelper pageHelper(DataSource dataSource) { log.info("注冊MyBatis分頁插件PageHelper"); PageHelper pageHelper = new PageHelper(); Properties p = new Properties(); p.setProperty("offsetAsPageNum", "true"); p.setProperty("rowBoundsWithCount", "true"); p.setProperty("reasonable", "true"); pageHelper.setProperties(p); return pageHelper; } }
package org.springboot.sample.config.mybatis; import java.util.Properties; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import tk.mybatis.spring.mapper.MapperScannerConfigurer; /** * MyBatis掃描接口,使用的tk.mybatis.spring.mapper.MapperScannerConfigurer <br/> * 如果你不使用通用Mapper,可以改為org.xxx... * */ @Configuration //TODO 注意,由於MapperScannerConfigurer執行的比較早,所以必須有下面的注解 @AutoConfigureAfter(MybatisAutoConfiguration.class) public class MyBatisMapperScannerConfig { @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); mapperScannerConfigurer.setBasePackage("org.springboot.sample.mapper"); Properties properties = new Properties();//設置通用mapper的屬性 // 這里要特別注意,不要把MyMapper放到 basePackage 中,也就是不能同其他Mapper一樣被掃描到。 properties.setProperty("mappers", MyMapper.class.getName()); properties.setProperty("notEmpty", "false"); properties.setProperty("IDENTITY", "MYSQL"); mapperScannerConfigurer.setProperties(properties); return mapperScannerConfigurer; } }
package org.springboot.sample.config.mybatis; import org.apache.ibatis.session.ExecutorType; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.io.Resource; /** * Configuration properties for Mybatis. * * @author Eddú Meléndez */ @ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX) public class MybatisProperties { public static final String MYBATIS_PREFIX = "mybatis"; /** * Config file path. */ private String config; /** * Location of mybatis mapper files. */ private Resource[] mapperLocations; /** * Package to scan domain objects. */ private String typeAliasesPackage; /** * Package to scan handlers. */ private String typeHandlersPackage; /** * Check the config file exists. */ private boolean checkConfigLocation = false; /** * Execution mode. */ private ExecutorType executorType = ExecutorType.SIMPLE; public String getConfig() { return this.config; } public void setConfig(String config) { this.config = config; } public Resource[] getMapperLocations() { return this.mapperLocations; } public void setMapperLocations(Resource[] mapperLocations) { this.mapperLocations = mapperLocations; } public String getTypeHandlersPackage() { return this.typeHandlersPackage; } public void setTypeHandlersPackage(String typeHandlersPackage) { this.typeHandlersPackage = typeHandlersPackage; } public String getTypeAliasesPackage() { return this.typeAliasesPackage; } public void setTypeAliasesPackage(String typeAliasesPackage) { this.typeAliasesPackage = typeAliasesPackage; } public boolean isCheckConfigLocation() { return this.checkConfigLocation; } public void setCheckConfigLocation(boolean checkConfigLocation) { this.checkConfigLocation = checkConfigLocation; } public ExecutorType getExecutorType() { return this.executorType; } public void setExecutorType(ExecutorType executorType) { this.executorType = executorType; } }
package org.springboot.sample.config.mybatis; import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.MySqlMapper; /** * 被繼承的Mapper,一般業務Mapper繼承它 * */ public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> { //TODO //FIXME 特別注意,該接口不能被掃描到,否則會出錯 }
三、屬性配置文件
屬性配置文件中和文章開頭指定的文章一樣配置,沒有什么修改,下面粘貼出來:
mybatis.mapper-locations=classpath*:org/springboot/sample/mapper/sql/mysql/*Mapper.xml mybatis.type-aliases-package=org.springboot.sample.entity
四、在業務Mapper中繼承基礎MyMapper接口
public interface StudentMapper extends MyMapper<Student> { List<Student> likeName(String name); Student getById(int id); int add(Student stu); String getNameById(int id); }
然后在Service中使用即可,后面就沒什么說的了。
@Service public class StudentService { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private StudentMapper studentMapper; @TargetDataSource(name="ds2") public List<Student> likeName(String name){ return studentMapper.likeName(name); } public int testSave(){ Student stu = new Student(); stu.setAge(33); stu.setName("測試新增"); stu.setSumScore("66"); stu.setAvgScore("22"); return studentMapper.insert(stu);//這里調用的是基礎Mapper中的insert方法 } }
最后還有一點要說明,使用公共Mapper“可能”需要對實體類進行修改。如果你的實體字段和數據庫字段不一致(或者實體名稱和數據庫表名不一致),這樣才需要修改,例如:
/** * 學生實體 * * @author 單紅宇(365384722) * @myblog http://blog.csdn.net/catoop/ * @create 2016年1月12日 */ public class Student implements Serializable{ @Id private int id; private String name; @Column(name="SCORE_SUM") private String sumScore; @Column(name="SCORE_AVG") private String avgScore; private int age; // getter setter }
其他沒有什么可說的了,請至少要到 http://git.oschina.net/free/Mapper 把插件的其他說明再看一遍。
https://yq.aliyun.com/articles/5831
1、Maven依賴,注意使用PageHelper時的版本必須與Mybatis版本對應
<!-- 添加Mybatis依賴 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <!-- pageHelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.4</version> </dependency>
2、需要在Mybatis的配置信息中使用PageHelper插件,mybatis-config.xml
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <plugins> <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> </configuration>
3、在配置Spring配置文件中,配置Mybatis的SqlSessionFactory時,需要把mybatis-config.xml添加到屬性中
<!-- SqlSessionFactory --> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--設置數據源--> <property name="dataSource" ref="dataSource"></property> <!--設置映射文件--> <property name="mapperLocations" value="classpath:mybatis/sqlmap/mapper/*.xml"></property> <!--設置pageHelper--> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property> </bean>
4、使用Mybatis的mapper接口進行查詢,在查詢時,需要使用PageHelper.startPage方法
@Test public void testSelectAll() { Page<Doctor> page = PageHelper.startPage(1, 3); //selectAll查詢出的List即為上面定義的page doctorMapper.selectAll(); //注意: //使用PageHelper.startPage只是針對接下來的一條查詢語句, //如果又查詢了一次數據,則還需要使用一次PageHelper.startPage logger.info("獲取所有Doctor信息,獲得記錄數:{}", page.size()); logger.info("獲取所有Doctor信息,獲得記錄:{}", page); //使用PageInfo封裝 PageInfo<Doctor> info = new PageInfo<Doctor>(page); logger.info("info.getPages:{}",info.getPages()); }
5、Page對象繼承了ArrayList,因此在使用了PageHelper.startPage之后,Page即為查詢到的數據,並且在Page中還額外封裝了pageNum,pageSize等屬性,還可以使用PageInfo封裝Page,PageInfo中有更多的分頁屬性,例如isFirstPage是否為首頁、isLastPage是否為末尾、hasNextPage是否存在下一頁等。
http://www.cnblogs.com/cksvsaaa/p/6036068.html
application.properties中的配置
pagehelper.helperDialect=mysql pagehelper.offset-as-page-num=true pagehelper.reasonable=false pagehelper.supportMethodsArguments=true pagehelper.row-bounds-with-count=true
import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.Properties; @ConfigurationProperties(prefix = PageHelperProperties.PAGE_HELPER_PREFIX) public class PageHelperProperties { public static final String PAGE_HELPER_PREFIX = "pagehelper"; private Properties properties = new Properties(); public Properties getProperties() { return properties; } public String getOffsetAsPageNum() { return properties.getProperty("offsetAsPageNum"); } public void setOffsetAsPageNum(String offsetAsPageNum) { properties.setProperty("offsetAsPageNum", offsetAsPageNum); } public String getRowBoundsWithCount() { return properties.getProperty("rowBoundsWithCount"); } public void setRowBoundsWithCount(String rowBoundsWithCount) { properties.setProperty("rowBoundsWithCount", rowBoundsWithCount); } public String getPageSizeZero() { return properties.getProperty("pageSizeZero"); } public void setPageSizeZero(String pageSizeZero) { properties.setProperty("pageSizeZero", pageSizeZero); } public String getReasonable() { return properties.getProperty("reasonable"); } public void setReasonable(String reasonable) { properties.setProperty("reasonable", reasonable); } public String getSupportMethodsArguments() { return properties.getProperty("supportMethodsArguments"); } public void setSupportMethodsArguments(String supportMethodsArguments) { properties.setProperty("supportMethodsArguments", supportMethodsArguments); } public String getDialect() { return properties.getProperty("dialect"); } public void setDialect(String dialect) { properties.setProperty("dialect", dialect); } public String getHelperDialect() { return properties.getProperty("helperDialect"); } public void setHelperDialect(String helperDialect) { properties.setProperty("helperDialect", helperDialect); } public String getAutoRuntimeDialect() { return properties.getProperty("autoRuntimeDialect"); } public void setAutoRuntimeDialect(String autoRuntimeDialect) { properties.setProperty("autoRuntimeDialect", autoRuntimeDialect); } public String getAutoDialect() { return properties.getProperty("autoDialect"); } public void setAutoDialect(String autoDialect) { properties.setProperty("autoDialect", autoDialect); } public String getCloseConn() { return properties.getProperty("closeConn"); } public void setCloseConn(String closeConn) { properties.setProperty("closeConn", closeConn); } public String getParams() { return properties.getProperty("params"); } public void setParams(String params) { properties.setProperty("params", params); } }
import com.github.pagehelper.PageInterceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import javax.annotation.PostConstruct; import java.util.Map; import java.util.Properties; @Configuration @ConditionalOnClass(SqlSessionFactory.class) @EnableConfigurationProperties(PageHelperProperties.class) public class PageHelperConfig implements EnvironmentAware { @Autowired private SqlSessionFactory sqlSessionFactory; @Autowired private PageHelperProperties pageHelperProperties; private RelaxedPropertyResolver resolver; @Override public void setEnvironment(Environment environment) { resolver = new RelaxedPropertyResolver(environment, "pagehelper."); } @PostConstruct public void addPageInterceptor() { PageInterceptor interceptor = new PageInterceptor(); Properties properties = pageHelperProperties.getProperties(); Map<String, Object> subProperties = resolver.getSubProperties(""); for (String key : subProperties.keySet()) { if (!properties.containsKey(key)) { properties.setProperty(key, resolver.getProperty(key)); } } interceptor.setProperties(properties); sqlSessionFactory.getConfiguration().addInterceptor(interceptor); } }
通用mapper的配置:
import com.github.pagehelper.PageInterceptor; import com.tangcheng.db.util.MyMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import tk.mybatis.spring.mapper.MapperScannerConfigurer; import java.util.Properties; @Configuration public class MybatisConfig { private static final Logger LOGGER = LoggerFactory.getLogger(MybatisConfig.class); @Bean public MapperScannerConfigurer mapperScannerConfigurer() { //此處使用的是tk.mybatis.spring.mapper.MapperScannerConfigurer MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setMarkerInterface(MyMapper.class); mapperScannerConfigurer.setBasePackage("com.tangcheng.db.mapper"); Properties properties = new Properties(); properties.put("notEmpty", false);//notEmpty:insert和update中,是否判斷字符串類型!='',少數方法會用到 properties.put("IDENTITY", "MYSQL");//取回主鍵的方式, properties.put("style", "camelhump");//實體和表轉換時的約定規則,默認駝峰轉下划線。注解@Table和@Column優先級高於此配置 //http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/2.Integration.md mapperScannerConfigurer.setProperties(properties); return mapperScannerConfigurer; } /** * PageHelper Parameters * <p> * PageHelper provides several optional parameters, these parameters when used in accordance with the above two examples to configuration. * <p> * Optional parameters as follows: * <p> * dialect: Default paging using PageHelper way, if you want to implement your own page logic, you can implement Dialect(com.github.pagehelper.Dialect) interface, and then configure the attribute to the fully qualified name of the implementing class. * The following parameters are the parameters for the default dialect case. When implemented using a custom dialect, the following parameter has no effect. * <p> * helperDialect: PageHelper will detect the current database url by default, automatically select the corresponding database dialect. You can configure helperDialect Property to specify the dialect. You can use the following abbreviations : * oracle, mysql, mariadb, sqlite, hsqldb, postgresql, db2, sqlserver, informix, h2, sqlserver2012, derby. * You can also implement AbstractHelperDialect, and then configure the attribute to achieve the fully qualified class name. * Special note : When using the SqlServer2012 database, you need to manually specify for sqlserver2012, otherwise it will use the SqlServer2005 for paging. * <p> * offsetAsPageNum: Default value is false, This parameter is valid for RowBounds as a pagination parameter. When this parameter is set to true, theoffset parameter in RowBounds is used aspageNum. * <p> * rowBoundsWithCount: Default value is false, When this parameter is set to true, PageHelper will execute count query. * <p> * pageSizeZero: Default value is false, When this parameter is set to true, if pageSize=0 or RowBounds.Limit = 0 will query all the results (the equivalent of a Paged query did not execute, but the return type of the result is still Page). * <p> * reasonable: Rationalization of paging parameters, Default value is false。 When this parameter is set to true,pageNum <= 0 will query the first page, PageNum> pages (over the total number), will query the last page. Default false, the query directly based on parameters. * <p> * params: In support of startPage(Object params) method, The parameter is added to configure the parameter mapping for the value from the object based on the attribute name, you can configure pageNum,pageSize,count,pageSizeZero,reasonable, Default value is pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。 * <p> * supportMethodsArguments: Support via the Mapper interface parameters to pass the page parameter, the default value is 'false'. The use of methods can refer to the test code in the com.github.pagehelper.test.basic package under theArgumentsMapTest and ArgumentsObjTest. * <p> * autoRuntimeDialect: Default value is false。When set to true, it is possible to automatically recognize pagination of the corresponding dialect at run time from multiple data sources (Does not support automatic selection of sqlserver2012, can only usesqlserver), usage and precautions refer to the following Scene 5. * <p> * closeConn: Default value is true。 When you use a runtime dynamic data source or do not set the helperDialect property, PageHelper will automatically get the database type, then a database connection is automatically obtained, This property is used to set whether to close the connection, the default true close. When 'false' is set, It will not close the connection. * <p> * 4. How to choose Configure these parameters * <p> * Here are a few examples for some of the parameters may be used. * <p> * Scene 1 * <p> * If you are still in with a way to call a namespace like iBATIS, you might use rowBoundsWithCount. If you want to count when the paging query query, you need to set this parameter to true. * <p> * Note: PageRowBounds also need true. * <p> * Scene 2 * <p> * If you are still in with a way to call a namespace like iBATIS, If you think RowBounds in the two parametersoffset, limit not as good as pageNum, pageSize easy to understand. You can use the offsetAsPageNum parameter, when the parameter is set to true, offset as pageNum, limit and pageSize mean the same thing. * <p> * Scene 3 * <p> * If you feel you have to paginate a page somewhere and you still want to query all the results with control parameters. You can configure pageSizeZero totrue, After configuration, when pageSize = 0 or RowBounds.limit = 0 will query all the results. * <p> * Scene 4 * <p> * If you want the user to enter the page number is not in the legal scope (the first page to the last page) to correctly respond to the correct results page, Then you can configure reasonable totrue, and if pageNum <= 0 will query the first page, the pageNum> pages(total pages) will query the last page. * <p> * Scene 5 * <p> * If you configure dynamic data sources in Spring and connect different types of databases, you can configure autoRuntimeDialect totrue, which will use matching pagination queries when using different data sources. In this case, you also need to pay attention to the closeConn parameter, because the type of access to the data source will get a database connection, so the need to control this parameter to obtain a connection, whether to close the connection. * <p> * Default is true, and some database connections can not be closed after the follow-up database operations. And some database connections will not be closed soon because the number of connections out of the database caused no response. Therefore, when using this feature, in particular, you need to pay attention to whether the use of the data source needs to close the database connection. * <p> * When you do not use dynamic data sources but only automatically get helperDialect, the database connection will only get once, so there is no need to worry about whether this connection will lead to a database error, but also according to the characteristics of the data source to choose whether to close the connection. * https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/en/HowToUse.md * <p> * <p> * 分頁插件參數介紹 * <p> * 分頁插件提供了多個可選參數,這些參數使用時,按照上面兩種配置方式中的示例配置即可。 * <p> * 分頁插件可選參數如下: * <p> * dialect:默認情況下會使用 PageHelper 方式進行分頁,如果想要實現自己的分頁邏輯,可以實現 Dialect(com.github.pagehelper.Dialect) 接口,然后配置該屬性為實現類的全限定名稱。 * 下面幾個參數都是針對默認 dialect 情況下的參數。使用自定義 dialect 實現時,下面的參數沒有任何作用。 * <p> * helperDialect:分頁插件會自動檢測當前的數據庫鏈接,自動選擇合適的分頁方式。 你可以配置helperDialect屬性來指定分頁插件使用哪種方言。配置時,可以使用下面的縮寫值: * oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby * 特別注意:使用 SqlServer2012 數據庫時,需要手動指定為 sqlserver2012,否則會使用 SqlServer2005 的方式進行分頁。 * 你也可以實現 AbstractHelperDialect,然后配置該屬性為實現類的全限定名稱即可使用自定義的實現方法。 * <p> * offsetAsPageNum:默認值為 false,該參數對使用 RowBounds 作為分頁參數時有效。 當該參數設置為 true 時,會將 RowBounds 中的 offset 參數當成 pageNum 使用,可以用頁碼和頁面大小兩個參數進行分頁。 * <p> * rowBoundsWithCount:默認值為false,該參數對使用 RowBounds 作為分頁參數時有效。 當該參數設置為true時,使用 RowBounds 分頁會進行 count 查詢。 * <p> * pageSizeZero:默認值為 false,當該參數設置為 true 時,如果 pageSize=0 或者 RowBounds.limit = 0 就會查詢出全部的結果(相當於沒有執行分頁查詢,但是返回結果仍然是 Page 類型)。 * <p> * reasonable:分頁合理化參數,默認值為false。當該參數設置為 true 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最后一頁。默認false 時,直接根據參數進行查詢。 * <p> * params:為了支持startPage(Object params)方法,增加了該參數來配置參數映射,用於從對象中根據屬性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默認值, 默認值為pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。 * <p> * supportMethodsArguments:支持通過 Mapper 接口參數來傳遞分頁參數,默認值false,分頁插件會從查詢方法的參數值中,自動根據上面 params 配置的字段中取值,查找到合適的值時就會自動分頁。 使用方法可以參考測試代碼中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。 * <p> * autoRuntimeDialect:默認值為 false。設置為 true 時,允許在運行時根據多數據源自動識別對應方言的分頁 (不支持自動選擇sqlserver2012,只能使用sqlserver),用法和注意事項參考下面的場景五。 * <p> * closeConn:默認值為 true。當使用運行時動態數據源或沒有設置 helperDialect 屬性自動獲取數據庫類型時,會自動獲取一個數據庫連接, 通過該屬性來設置是否關閉獲取的這個連接,默認true關閉,設置為 false 后,不會關閉獲取的連接,這個參數的設置要根據自己選擇的數據源來決定。 * <p> * 重要提示: * <p> * 當 offsetAsPageNum=false 的時候,由於 PageNum 問題,RowBounds查詢的時候 reasonable 會強制為 false。使用 PageHelper.startPage 方法不受影響。 * <p> * 4. 如何選擇配置這些參數 * <p> * 單獨看每個參數的說明可能是一件讓人不爽的事情,這里列舉一些可能會用到某些參數的情況。 * <p> * 場景一(rowBoundsWithCount) * <p> * 如果你仍然在用類似ibatis式的命名空間調用方式,你也許會用到rowBoundsWithCount, 分頁插件對RowBounds支持和 MyBatis 默認的方式是一致,默認情況下不會進行 count 查詢,如果你想在分頁查詢時進行 count 查詢, 以及使用更強大的 PageInfo 類,你需要設置該參數為 true。 * <p> * 注: PageRowBounds 想要查詢總數也需要配置該屬性為 true。 * <p> * 場景二(offsetAsPageNum) * <p> * 如果你仍然在用類似ibatis式的命名空間調用方式,你覺得 RowBounds 中的兩個參數 offset,limit 不如 pageNum,pageSize 容易理解, 你可以使用 offsetAsPageNum 參數,將該參數設置為 true 后,offset會當成 pageNum 使用,limit 和 pageSize 含義相同。 * <p> * 場景三(pageSizeZero) * <p> * 如果覺得某個地方使用分頁后,你仍然想通過控制參數查詢全部的結果,你可以配置 pageSizeZero 為 true, 配置后,當 pageSize=0 或者 RowBounds.limit = 0 就會查詢出全部的結果。 * <p> * 場景四(reasonable) * <p> * 如果你分頁插件使用於類似分頁查看列表式的數據,如新聞列表,軟件列表, 你希望用戶輸入的頁數不在合法范圍(第一頁到最后一頁之外)時能夠正確的響應到正確的結果頁面, 那么你可以配置 reasonable 為 true,這時如果 pageNum<=0 會查詢第一頁,如果 pageNum>總頁數 會查詢最后一頁。 * <p> * 場景五(autoRuntimeDialect,closeConn) * <p> * 如果你在 Spring 中配置了動態數據源,並且連接不同類型的數據庫,這時你可以配置 autoRuntimeDialect 為 true,這樣在使用不同數據源時,會使用匹配的分頁進行查詢。 這種情況下,你還需要特別注意 closeConn 參數,由於獲取數據源類型會獲取一個數據庫連接,所以需要通過這個參數來控制獲取連接后,是否關閉該連接。 默認為 true,有些數據庫連接關閉后就沒法進行后續的數據庫操作。而有些數據庫連接不關閉就會很快由於連接數用完而導致數據庫無響應。所以在使用該功能時,特別需要注意你使用的數據源是否需要關閉數據庫連接。 * <p> * 當不使用動態數據源而只是自動獲取 helperDialect 時,數據庫連接只會獲取一次,所以不需要擔心占用的這一個連接是否會導致數據庫出錯,但是最好也根據數據源的特性選擇是否關閉連接。 * https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md * eg:http://www.jianshu.com/p/b0af2c0a7a9d * * @return */ // @Bean public PageInterceptor pageInterceptor() { /** * The MyBatis-Spring-Boot-Starter will detects beans that implements following interface provided by MyBatis. Interceptor DatabaseIdProvider http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/ */ PageInterceptor interceptor = new PageInterceptor(); Properties properties = new Properties(); properties.put("helperDialect", "mysql");//配置helperDialect屬性來指定分頁插件使用哪種方言。配置時,可以使用下面的縮寫值:oracle,mysql,mariadb properties.put("offsetAsPageNum", true);//offsetAsPageNum:默認值為 false,該參數對使用 RowBounds 作為分頁參數時有效。 當該參數設置為 true 時,會將 RowBounds 中的 offset 參數當成 pageNum 使用,可以用頁碼和頁面大小兩個參數進行分頁。 properties.put("rowBoundsWithCount", false);//默認值為false,使用 RowBounds 分頁不會進行 count 查詢 properties.put("pageSizeZero", false);//默認值為 false,當該參數設置為 true 時,如果 pageSize=0 或者 RowBounds.limit = 0 就會查詢出全部的結果 properties.put("reasonable", false);//默認值為false。當該參數設置為 true 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最后一頁 properties.put("supportMethodsArguments", true);//支持通過 Mapper 接口參數來傳遞分頁參數,默認值false interceptor.setProperties(properties); return interceptor; } }
