最近用SpringBoot+MyBatis在做个人博客网站,遇了条件分页查询,现在把解决流程与源代码记录下来,便于后续参考。
这里把主要的依赖放进来,其他相关依赖请自行导入
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!-- pagehelper 分页的一个工具 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency>数据表sql:
CREATE DATABASE /*!32312 IF NOT EXISTS*/`myblog` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `myblog`; /*Table structure for table `articles` */ DROP TABLE IF EXISTS `articles`; CREATE TABLE `articles` ( `article_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `user_id` bigint(20) NOT NULL COMMENT '用户ID', `title` varchar(255) DEFAULT NULL COMMENT '文章标题', `name` varchar(255) DEFAULT NULL, `view_num` int(11) DEFAULT NULL COMMENT '浏览数', `comment_num` int(11) DEFAULT NULL COMMENT '评论数', `category_id` bigint(20) DEFAULT NULL COMMENT '文章分类ID', `create_time` datetime DEFAULT NULL COMMENT '创建日期', `like_num` int(11) DEFAULT '0', PRIMARY KEY (`article_id`), KEY `key_category_id` (`category_id`), KEY `key_userId` (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8 COMMENT='文章表'; /*Data for the table `articles` */ insert into `articles`(`article_id`,`user_id`,`title`,`name`,`view_num`,`comment_num`,`category_id`,`create_time`,`like_num`) values (1,0,'555','555.md',0,3,1,'2020-09-22 00:00:00',0),(83,1,'daidai','daidai.md',0,4,1,'2020-09-30 11:09:42',0),(84,1,'redis安装','redis安装.md',0,1,1,'2020-09-30 11:09:43',0),(85,1,'淘宝革命的启示录','淘宝革命的启示录.md',0,2,1,'2020-09-30 11:09:43',0),(98,1,'444','444.md',0,9,0,'2020-10-01 10:55:45',0);定义与数据表相对应的Article 类
@Data @NoArgsConstructor @AllArgsConstructor public class Article implements Serializable { private Long articleId; private Long userId=1l ; private String title; private String name; private Integer viewNum=0 ; private Integer commentNum=0 ; private long categoryId ; private Timestamp createTime; }定义查询类
@Data public class ArticleQuery extends Article { //排序字段 public String sortView; //传入的sort字符串 public String sort; public String getSort(){ if(sortView!=null){ //驼峰命名转化为横线命名 例如commentNum=>commment_num 适应sql语句字段规则 this.sort=StringTool.humpToLine(this.sortView); } return this.sort; } //排序方向 public String direction; //页面大小 public Integer pageSize; //页数 public Integer pageNum;这里放一个驼峰命名转换的工具类:
public class StringTool { private static Pattern linePattern = Pattern.compile("_(\\w)"); /** 下划线转驼峰 */ public static String lineToHump(String str) { str = str.toLowerCase(); Matcher matcher = linePattern.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, matcher.group(1).toUpperCase()); } matcher.appendTail(sb); return sb.toString(); } /** 驼峰转下划线(简单写法,效率低于{@link #humpToLine2(String)}) */ public static String humpToLine(String str) { return str.replaceAll("[A-Z]", "_$0").toLowerCase(); } private static Pattern humpPattern = Pattern.compile("[A-Z]"); /** 驼峰转下划线,效率比上面高 */ public static String humpToLine2(String str) { Matcher matcher = humpPattern.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase()); } matcher.appendTail(sb); return sb.toString(); } public static void main(String[] args) { String lineToHump = lineToHump("f_parent_no_leader"); System.out.println(lineToHump);// fParentNoLeader System.out.println(humpToLine(lineToHump));// f_parent_no_leader System.out.println(humpToLine2(lineToHump));// f_parent_no_leader } }在application.yml中对mybatis相关属性进地配置,其他数据库连接相关配置就不说了。
#mybatis配置 mybatis: #config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml #定义.xml文件位置,注意不能与config-location共存 type-aliases-package: com.xinxin.pojo #定义别名,直接找到pojo这个包 configuration: map-underscore-to-camel-case: true #驼峰命名设置为true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #运时打印出sql语句在ArticleMapper.xml写对应的sql语句
<!--文章查询的sql片断,建议是以单表为单位定义查询条件,建议将常用的查询条件都写出来--> <sql id="query_items_where"> <if test="name!=null and name!=''"> and name like '%${name}%' </if> <if test="title!=null and title!=''"> and title like '%${title}%' </if> <if test="articleId!=null"> and article_id = #{articleId} </if> </sql> <select id="queryByCondition" parameterType="ArticleQuery" resultType="Article"> -- 注意ORDER BY后面用的是$而不是# select * from articles <where> <include refid="query_items_where" /> </where> <if test="sort!=null and sort!=''"> ORDER BY ${sort} </if> <if test="direction!=null and direction!=''"> ${direction} </if> </select>注意一定要开启mybatis二级缓存,这样如果第一次select,后面就不用都去查询数据库了,系统会变快!只需要在ArticleMapper.xml加一个“”即可。
<mapper namespace="com.xinxin.dao.ArticleDao"> <!-- 开启二级缓存,这样对所有select操作都会作缓存处理--> <cache /> ... </mapper>这里用到的工具类PageUtils定义为
import com.github.pagehelper.PageInfo; public class PageUtils { /** * 将分页信息封装到统一的接口 * @param pageInfo * @return */ public static PageResult getPageResult(PageInfo<?> pageInfo) { PageResult pageResult = new PageResult(); pageResult.setPageNum(pageInfo.getPageNum()); pageResult.setPageSize(pageInfo.getPageSize()); pageResult.setTotalSize(pageInfo.getTotal()); pageResult.setTotalPages(pageInfo.getPages()); pageResult.setContent(pageInfo.getList()); return pageResult; } }对应的PageResulto类封了分页所需要的信息:
public class PageResult<T> { /** * 当前页码 */ private int pageNum; /** * 每页数量 */ private int pageSize; /** * 记录总数 */ private long totalSize; /** * 页码总数 */ private int totalPages; /** * 数据模型 */ private List<T> content; public int getPageNum() { return pageNum; } public void setPageNum(int pageNum) { this.pageNum = pageNum; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public long getTotalSize() { return totalSize; } public void setTotalSize(long totalSize) { this.totalSize = totalSize; } public int getTotalPages() { return totalPages; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public List<T> getContent() { return content; } public void setContent(List<T> content) { this.content = content; } }成功打印出两行数据,且是按comment_num倒序排列,打印的sql语句也显示正确。
这里没有用mybatis-plus是想自己多实际写一写sql语句,同时复习一下之前的知识,实际项目中仍然以原生sql语句为主。感兴趣的网友,可以参考。