springboot2.0.5集成mybatis(PageHelper分页插件、generator插件使用)
用IDEA搭建springboot2.0.5项目
选择Spring initializr就可以轻松搭建一个springboot项目,第一次搭建很费时
在Group写上公司域名,Artifact写上项目名,打包用Jar
选Web勾选
SQL项,勾选MySQL、JDBC、MyBatis,这里选择了过后,IDEA会方便地帮我们导入相关依赖
数据库建立
[code]CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `age` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `weight` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; INSERT INTO `user` VALUES ('1', '23', 'zhangsan', '123'); INSERT INTO `user` VALUES ('2', '25', 'lisi', '125'); INSERT INTO `user` VALUES ('3', '30', 'wangwu', '90'); INSERT INTO `user` VALUES ('4', '12', 'zhengxie', '120'); INSERT INTO `user` VALUES ('5', '50', 'zhaocao', '100'); INSERT INTO `user` VALUES ('6', '60', 'caohuai', '150');
搭建简陋的一张表新增、查询系统
项目名称会与上面不一致,因为做demo时没有截图。
搭建完成的结构如下图:
UserController代码:
[code]package com.zab.mybatis.web; import com.zab.mybatis.beans.User; import com.zab.mybatis.common.GeneralResponse; import com.zab.mybatis.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** *@author Jackson Zhang *@date 22:58 */ @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @PostMapping("/findAll") public GeneralResponse findAll(){ return userService.findAll(); } @PostMapping("/findByPage") public GeneralResponse findByPaging(Integer pageNum, Integer pageSize){ return userService.findByPaging(pageNum,pageSize); } @PostMapping("/selectByPrimaryKey") public GeneralResponse selectByPrimaryKey(Integer id){ return userService.selectByPrimaryKey(id); } @PostMapping("/insert") public GeneralResponse insert(@RequestBody User user){ return userService.insert(user); } }
UserServiceImpl代码:
[code]package com.zab.mybatis.service.impl; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.zab.mybatis.beans.User; import com.zab.mybatis.common.GeneralResponse; import com.zab.mybatis.mapper.UserMapper; import com.zab.mybatis.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** *@author Jackson Zhang *@date 22:59 */ @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper;//会报红线 @Override public GeneralResponse findAll() { List<User> users = userMapper.findAll(); return new GeneralResponse("0","查询成功","查询成功",users); } @Override public GeneralResponse selectByPrimaryKey(Integer id) { User user = userMapper.selectByPrimaryKey(id); return new GeneralResponse("0","查询成功","查询成功",user); } @Override public GeneralResponse insert(User user) { int result = userMapper.insert(user); if(result==1){ return new GeneralResponse("0","新增成功","新增成功",result); } return new GeneralResponse("1","新增失败","新增失败",result); } @Override public GeneralResponse findByPaging(Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum,pageSize); Page<User> userList = userMapper.findByPaging(); return new GeneralResponse("0","查询成功","查询成功",userList); } }
UserMapper代码:这里并不是自己写的,除了findByPaging方法都是用插件生成的!
[code]package com.zab.mybatis.mapper; import com.github.pagehelper.Page; import com.zab.mybatis.beans.User; import org.apache.ibatis.annotations.Mapper; import java.util.List; /** *@author Jackson Zhang *@date 23:01 */ @Mapper public interface UserMapper { List<User> findAll(); int deleteByPrimaryKey(Integer id); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(User record); int updateByPrimaryKey(User record); Page<User> findByPaging(); }
UserMapper.xml如下:
[code]<?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.zab.mybatis.mapper.UserMapper"> <resultMap id="BaseResultMap" type="com.zab.mybatis.beans.User"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="age" property="age" jdbcType="VARCHAR"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="weight" property="weight" jdbcType="VARCHAR"/> </resultMap> <sql id="Base_Column_List"> id, age, name, weight </sql> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer"> select <include refid="Base_Column_List"/> from user where id = #{id,jdbcType=INTEGER} </select> <select id="findAll" resultMap="BaseResultMap" parameterType="java.util.List"> select <include refid="Base_Column_List"/> from USER </select> <select id="findByPaging" resultMap="BaseResultMap" parameterType="com.github.pagehelper.Page"> select <include refid="Base_Column_List"/> from USER </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> delete from user where id = #{id,jdbcType=INTEGER} </delete> <insert id="insert" parameterType="com.zab.mybatis.beans.User"> insert into user (id, age, name, weight) values (#{id,jdbcType=INTEGER}, #{age,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{weight,jdbcType=VARCHAR}) </insert> <insert id="insertSelective" parameterType="com.zab.mybatis.beans.User"> insert into user <trim prefix="(" suffix=")" suffixOverrides=","> <if test="id != null"> id, </if> <if test="age != null"> age, </if> <if test="name != null"> name, </if> <if test="weight != null"> weight, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null"> #{id,jdbcType=INTEGER}, </if> <if test="age != null"> #{age,jdbcType=VARCHAR}, </if> <if test="name != null"> #{name,jdbcType=VARCHAR}, </if> <if test="weight != null"> #{weight,jdbcType=VARCHAR}, </i 20000 f> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.zab.mybatis.beans.User"> update user <set> <if test="age != null"> age = #{age,jdbcType=VARCHAR}, </if> <if test="name != null"> name = #{name,jdbcType=VARCHAR}, </if> <if test="weight != null"> weight = #{weight,jdbcType=VARCHAR}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> <update id="updateByPrimaryKey" parameterType="com.zab.mybatis.beans.User"> update user set age = #{age,jdbcType=VARCHAR}, name = #{name,jdbcType=VARCHAR}, weight = #{weight,jdbcType=VARCHAR} where id = #{id,jdbcType=INTEGER} </update> </mapper>
实体类User:
[code]package com.zab.mybatis.beans; /** *@author Jackson Zhang *@date 23:02 */ public class User { private Integer id; private String age; private String name; private String weight; //getter、setter略 }
通用响应类GeneralResponse:
[code]package com.zab.mybatis.common; /** * @author zhang anbing * @date 2018/8/21 */ public class GeneralResponse<T> { /** * 0表示正常,1表示异常 */ private String code; /** * 面向用户的消息 */ private String message; /** * 面向开发者的详细信息 */ private String detail; /** * 返回给前端的数据 */ private T datas; public GeneralResponse(String code, String message, String detail, T datas) { this.code = code; this.message = message; this.detail = detail; this.datas = datas; } public static GeneralResponse success(String message, String detail) { return new GeneralResponse("0", message, detail, null); } public static GeneralResponse fail(String message, String detail) { return new GeneralResponse("1", message, detail, null); } //getter、setter略 }
接下来就是配置文件,实际开发中配置文件绝不止一两个,springboot项目通常来说会有一个切换配置的配置文件application.yml:
[code]spring: profiles: active: dev
然后就是dev、test、prod等,这里只配开发application-dev.yml:
[code]server: port: 8080 spring: datasource: name: mybatis-test type: com.alibaba.druid.pool.DruidDataSource druid: url: jdbc:mysql://127.0.0.1:3306/test username: root password: root driver-class-name: com.mysql.jdbc.Driver mybatis: mapper-locations: classpath:mapping/*.xml #配置映射文件位置,classpath指resources type-aliases-package: com.zab.mybatis.beans #实体类所在位置 configuration: #打印sql到控制台 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl pagehelper: helperDialect: mysql #分页插件方言选择 reasonable: true #合理化参数,设为true时pageNum<=0 时会查第一页, pageNum>pages(超过总数时),会查询最后一页 supportMethodsArguments: true
整个demo项目的pom.xml文件如下:
[code]<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zab</groupId> <artifactId>mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>mybatis</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> </dependency> <!-- 分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <!-- alibaba的druid数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin> </plugins> </build> </project>
自动生成mapper(包括*mapper.xml和*mapper.java)的配置文件:
[code]<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- 数据库驱动:选择你的本地硬盘上面的数据库驱动包--> <classPathEntry location="D:\mvn_repository\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar"/> <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator> <property name="suppressDate" value="true"/> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true"/> </commentGenerator> <!--数据库链接URL,用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/test" userId="root" password="root"> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- 生成模型的包名和位置--> <javaModelGenerator targetPackage="com.zab.mybatis.beans" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- 生成映射文件的包名和位置--> <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!-- 生成DAO的包名和位置--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.zab.mybatis.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名--> <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table> </context> </generatorConfiguration>
generator使用方法
1.配置Maven Configurations如下
2.选择配置好的generator运行即可,就会发现配置好的文件夹中(java-->mapper和resource-->mapping)生成好了响应的mapper.java和mapper.xml
generator除了这种依靠IDEA的,还有一种GUI版,运行过后再弹出的窗口中定制Mapper生成地址,给出下载链接:
https://pan.baidu.com/s/13s9zO93eVmcVNBCGV4-T3A
MySQL分页简介
MySQL分页是通过limit完成的
[code]#LIMIT [offset], rows #offset是相对于首行的偏移量(首行是0),rows是返回条数。 # 每页10条记录,取第一页,返回的是前10条记录 select * from tableA limit 0,10; # 每页10条记录,取第二页,返回的是第11条记录,到第20条记录, select * from tableA limit 10,10;
其实说得简单点,limit会跟俩数字a和b,a表示排除几笔,b表示取几笔。
比如:
limit 1000,10 - 过滤出1010条数据,然后排除前1000条,取10条。
limit 100000,10 - 会过滤100010条数据,然后排除前100000条,取10条。当偏移量大(排除数量过多)的时候,性能会有所下降。
例如数据库有一千万条数据,你要取500万后面十条数据,采用如下方式是不合理的:
[code]select * from table limit 5000000,10;
可以考虑这样写:
[code]select * from table where id>5000000 limit 0,10;
PageHelper使用方法
插件作者是国人大神刘增辉,听朋友说以前也有个PageHelper的插件用的是内存分页,就是一次性全查,再分页,不清楚是不是说的这个,但是liuzh这个插件确实是物理分页。
使用很简单,介绍两种方式
第一种,也就是上面代码展示的:
[code]PageHelper.startPage(pageNum,pageSize); Page<User> userList = userMapper.findByPaging();
对应的*mapper.xml:
[code] <select id="findByPaging" resultMap="BaseResultMap" parameterType="com.github.pagehelper.Page"> select <include refid="Base_Column_List"/> from USER </select>
起初,我光看这几行代码,感觉这玩意是不是先全查,然后在内存中取了我们想要的那一页,毕竟sql语句是全查呀。
然后追了下源码,一调就是一下午啊,流程很复杂,也不能说看懂,大致有那么几个主要的类参与其中:MapperProxy、MapperMethod、DefaultSqlSession、Plugin、PageIntercepter(这就是PageHelper关键)、SqlSessionTemplate
注意到@Intercepts这个注解可以拦截Excutor类的query方法
拦截query方法过后,设置分页参数,这种分页与上述UserServiceImpl中
[code]PageHelper.startPage(pageNum,pageSize); Page<User> userList = userMapper.findByPaging();
的方式不一样,只是多了一个VO,少了PageHelper.startPage(pageNum,pageSize),原理都是要把分页参数通过拦截mybatis的执行流程加入到最终的sql中。
[code] Page<User> userList = userMapper.findByPaging(pageVo);
最后执行分页查询
前面说到PageHelper的第一种使用方式和简单过了下PageHelper怎么实现分页的,下面是PageHelper的第二种使用方式:
建一个PageVo类
[code]package com.zab.mybatis.vo; public class PageVo { private Integer pageNum; private Integer pageSize; //getter、setter略 }
把UserServiceImpl中的:
[code]PageHelper.startPage(pageNum,pageSize); Page<User> userList = userMapper.findByPaging();
改为:
[code] Page<User> userList = userMapper.findByPaging(pageVo);
响应的类中形参和实参进行修改就可以了,UserMapper.xml文件不用改动。
用postman测试
总共6笔数据,第二页取三笔:
提醒下,Controller类中方法的形参如果没有加@RequestBody,那么postman用x-www-form-urlencoded传参,加上@RequestBody则用raw中的json传参。
最后给出PageHelper的官方地址,详细使用请参考:
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
阅读更多
- spring-boot 集成mybatis的分页插件PageHelper和Generator (番外)
- spring-boot 集成mybatis的分页插件PageHelper和Generator (番外)
- spring-boot 集成mybatis的分页插件PageHelper和Generator
- Spring Boot系列教程十一: Mybatis使用分页插件PageHelper
- 记录问题:springboot中使用Mybatis-pagehelper分页插件遇到的版本兼容问题
- springboot如何集成mybatis的pagehelper分页插件
- SpringBoot集成MyBatis的分页插件PageHelper(回头草)
- springboot 集成myBatis PageHelper 分页插件
- SpringBoot集成MyBatis的分页插件PageHelper(回头草)
- Spring,SpringBoot 集成 MyBatis 的分页插件 PageHelper
- Spring Boot : 集成mybatis、pagehelper插件、开启事务、druid数据源配置、mybatis-generator(十一)
- [置顶] MyBatis基于Spring-boot集成通用Mapper以及pagehelper分页插件(含源码下载)
- Spring Boot系列六 Spring boot集成mybatis、分页插件pagehelper
- springboot 集成,pagehelper分页插件不起作用java.lang.ClassCastException: java.util.ArrayList cannot be cast to
- Mybatis分页插件 - PageHelper与springBoot的整合
- Spring + Mybatis 使用 PageHelper 插件分页
- Spring + Mybatis 使用 PageHelper 插件分页
- Spring + Mybatis 使用 PageHelper 插件分页
- SpringBoot之分页插件PageHelper的使用
- SpringBoot Mybatis PageHelper分页插件的两种用法(二)