SpringBoot
是为了简化 Spring
应用的创建、运行、调试、部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工程
在一起来学SpringBoot | 第七篇:整合Mybatis一文中,我们介绍了Mybatis
这款优秀的框架,顺便提及了民间大神开发的两款插件(通用Mapper
、PageHelper
),从此告别简单CURD代码的编写….
插件介绍
以下两款插件作者均是同一个人,如果你想深入了解Mybatis
以及插件开发可以购买作者的书籍
MyBatis 从入门到精通
分页插件
在没有分页插件之前,写一个分页需要两条SQL语句,一条查询一条统计,然后才能计算出页码,这样的代码冗余而又枯燥,更重要的一点是数据库迁移
,众所周知不同的数据库分页写法是不同的,而Mybatis
不同于Hibernate
的是它只提供动态SQL和结果集映射。值得庆幸的是,它虽然没有为分页提供良好的解决方案,但却提供了Interceptor
以供开发者自己扩展,这也是这款分页插件的由来….
通用Mapper
通用 Mapper
是一个可以实现任意 MyBatis
通用方法的框架,项目提供了常规的增删改查操作以及 Example
相关的单表操作。通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。
导入依赖
在 pom.xml
中添加通用Mapper与分页插件的依赖包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
<!-- 通用Mapper插件 文档地址:https://gitee.com/free/Mapper/wikis/Home --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.0.2</version> </dependency> <!-- 分页插件 文档地址:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <!-- MYSQL包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 默认就内嵌了Tomcat 容器,如需要更换容器也极其简单--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 测试包,当我们使用 mvn package 的时候该包并不会被打入,因为它的生命周期只在 test 之内--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
|
属性配置
在 application.properties
文件中分别添加上数据库
、Mybatis
、通用Mapper
、PageHelper
的属性配置,这里只提供了常见场景的配置,更全的配置可以参考上文所述的文文档(#^.^#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
spring.datasource.url=jdbc:mysql://localhost:3306/chapter7?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false spring.datasource.password=root spring.datasource.username=root # 如果想看到mybatis日志需要做如下配置 logging.level.com.battcn=DEBUG ########## Mybatis 自身配置 ########## mybatis.mapper-locations=classpath:com/battcn/mapper/*.xml mybatis.type-aliases-package=com.battcn.entity # 驼峰命名规范 如:数据库字段是 order_id 那么 实体字段就要写成 orderId mybatis.configuration.map-underscore-to-camel-case=true ########## 通用Mapper ########## # 主键自增回写方法,默认值MYSQL,详细说明请看文档 mapper.identity=MYSQL mapper.mappers=tk.mybatis.mapper.common.BaseMapper # 设置 insert 和 update 中,是否判断字符串类型!='' mapper.not-empty=true # 枚举按简单类型处理 mapper.enum-as-simple-type=true ########## 分页插件 ########## pagehelper.helper-dialect=mysql pagehelper.params=count=countSql pagehelper.reasonable=false pagehelper.support-methods-arguments=true
|
通用Mapper
- mapper.enum-as-simple-type: 枚举按简单类型处理,如果有枚举字段则需要加上该配置才会做映射
- mapper.not-empty: 设置以后,会去判断 insert 和 update 中符串类型!=’’
分页插件
- pagehelper.reasonable: 分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
- support-methods-arguments: 支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。
注意事项
由于 mybatis.mapper-locations=classpath:com/battcn/mapper/*.xml
配置的在java package
中,而Spring Boot
默认只打入java package -> *.java
,所以我们需要给pom.xml
文件添加如下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
<build> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
|
具体编码
完成基本配置后,接下来进行具体的编码操作。
表结构
创建一张 t_user
的表
1 2 3 4 5 6
|
CREATE TABLE `t_user` ( `id` int(8) NOT NULL AUTO_INCREMENT COMMENT '主键自增', `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(50) NOT NULL COMMENT '密码', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';
|
实体类
通用Mapper
采用了JPA规范包中的注解,这种的设计避免了重复造轮子,更是让Spring Data Jpa
的应用可以轻松切换到Mybatis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
package com.battcn.entity;
import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable;
/** * @author Levin * @since 2018/5/10 0007 */ @Table(name = "t_user") public class User implements Serializable {
private static final long serialVersionUID = 8655851615465363473L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; // TODO 省略get set }
|
持久层
为了更好的让熟悉它,此处模拟了一个自定义的SQL,可以发现使用 通用Mapper
后并不会破坏原有代码结构
UserMapper
继承 BaseMapper<T>
就可以了,这点是不是有点类似 JpaRepository
,同时也可以根据自己需要扩展出更适合自己项目的BaseMapper
,它的灵活也是众多开发者喜爱的因素之一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
package com.battcn.mapper;
import com.battcn.entity.User; import org.apache.ibatis.annotations.Mapper; import tk.mybatis.mapper.common.BaseMapper;
/** * t_user 操作,继承 BaseMapper<T> 就可以了,是不是有点类似 JpaRepository * * @author Levin * @since 2018/5/10 0007 */ @Mapper public interface UserMapper extends BaseMapper<User> {
/** * 根据用户名统计(TODO 假设它是一个很复杂的SQL) * * @param username 用户名 * @return 统计结果 */ int countByUsername(String username); }
|
UserMapper
映射文件
1 2 3 4 5 6 7 8
|
<?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.battcn.mapper.UserMapper">
<select id="countByUsername" resultType="java.lang.Integer"> SELECT count(1) FROM t_user WHERE username = #{username} </select> </mapper>
|
测试
完成数据访问层接口后,编写一个junit
测试类来检验代码的正确性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
package com.battcn;
import com.battcn.entity.User; import com.battcn.mapper.UserMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
/** * @author Levin */ @RunWith(SpringRunner.class) @SpringBootTest public class Chapter7ApplicationTests {
private static final Logger log = LoggerFactory.getLogger(Chapter7ApplicationTests.class);
@Autowired private UserMapper userMapper;
@Test public void test1() throws Exception { final User user1 = new User("u1", "p1"); final User user2 = new User("u1", "p2"); final User user3 = new User("u3", "p3"); userMapper.insertSelective(user1); log.info("[user1回写主键] - [{}]", user1.getId()); userMapper.insertSelective(user2); log.info("[user2回写主键] - [{}]", user2.getId()); userMapper.insertSelective(user3); log.info("[user3回写主键] - [{}]", user3.getId()); final int count = userMapper.countByUsername("u1"); log.info("[调用自己写的SQL] - [{}]", count);
// TODO 模拟分页 userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); userMapper.insertSelective(new User("u1", "p1")); // TODO 分页 + 排序 this.userMapper.selectAll() 这一句就是我们需要写的查询,有了这两款插件无缝切换各种数据库 final PageInfo<Object> pageInfo = PageHelper.startPage(1, 10).setOrderBy("id desc").doSelectPageInfo(() -> this.userMapper.selectAll()); log.info("[lambda写法] - [分页信息] - [{}]", pageInfo.toString());
PageHelper.startPage(1, 10).setOrderBy("id desc"); final PageInfo<User> userPageInfo = new PageInfo<>(this.userMapper.selectAll()); log.info("[普通写法] - [{}]", userPageInfo); } }
|
总结
- Mybatis官方文档: http://www.mybatis.org/mybatis-3/zh/index.html
- 通用Mapper文档: https://gitee.com/free/Mapper/wikis/1.1-java?parent=1.integration
- 分页插件文档: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
- Springboot集成mybatis通用Mapper与分页插件PageHelper
插件介绍 通用 Mapper 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及 Example 相关的单表操作.通用 Mapper 是为了解决 MyBatis 使用 ...
- (通用Mapper、分页,批量插入,一分钟接入)spring mvc+mybatis+maven集成tkmapper+pagehelper
<!-- maven tkmapper引入--> <dependency> <groupId>tk.mybatis</groupId> <arti ...
- PageHelper分页插件及通用分页js
分页概述 1.物理分页 物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果. ...
- 六、mybatis分页插件集成
本文基于上一篇“集成mybatis”内容 1.添加依赖 <!-- mybatis-pageHelper --> <dependency> <groupId>com. ...
- Mybatis-generator/通用Mapper/Mybatis-Plus对比
mybatis-plus-boot-starter和mybatis-spring-boot-starter冲突导致MapperScan失效问题还没有解决,只能不用mybatis-plus-boot-s ...
- springboot学习笔记:8. springboot+druid+mysql+mybatis+通用mapper+pagehelper+mybatis-generator+freemarker+layui
前言: 开发环境:IDEA+jdk1.8+windows10 目标:使用springboot整合druid数据源+mysql+mybatis+通用mapper插件+pagehelper插件+mybat ...
- 使用通用mapper 生成代码
参考通用mapper 文档:https://github.com/abel533/Mapper/wiki/4.1.mappergenerator 使用maven 的方法: 1,修改pom.xml &l ...
- Springboot 系列(十二)使用 Mybatis 集成 pagehelper 分页插件和 mapper 插件
前言 在 Springboot 系列文章第十一篇里(使用 Mybatis(自动生成插件) 访问数据库),实验了 Springboot 结合 Mybatis 以及 Mybatis-generator 生 ...
- Spring Boot MyBatis 通用Mapper插件集成 good
看本文之前,请确保你已经在SpringBoot中集成MyBatis,并能正常使用.如果没有,那么请先移步 http://blog.csdn.net/catoop/article/details/505 ...
随机推荐
- Java实现 蓝桥杯VIP 算法训练 采油区域
算法训练 采油区域 时间限制:2.0s 内存限制:512.0MB 提交此题 查看参考代码 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整 ...
- Java实现 LeetCode 217 存在重复元素
217. 存在重复元素 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3 ...
- Java实现填写乘法算式
观察下面的算式: * * × * * = * * * 它表示:两个两位数字相乘,结果是3位数.其中的星号(*)代表任意的数字,可以相同,也可以不同,只要不是在首位的就可以是0.当然,满足这个要求的算式 ...
- java实现海盗比酒量
** 海盗比酒量** 有一群海盗(不多于20人),在船上比拼酒量.过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了.再打开一瓶酒平分,又有倒下的,再次重复- 直到开了第4瓶酒,坐着的已经所剩 ...
- java实现第五届蓝桥杯奇怪的分式
奇怪的分式 题目描述 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png) 老师刚想批 ...
- TZOJ 复习时间
描述 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.为了追求更高的效率,xhd要根据难度值来选择合适的课程进行复习,复习后一门课的效率为前一门课之间的难度差的平方,而复习第一门课的效率 ...
- 数据结构&算法
20个最常用.最基础数据结构与算法: 10个数据结构:数组.链表.栈.队列.散列表.二叉树.堆.跳表.图.Trie 树. 10个 算法 :递归.排序.二分查找.搜索.哈希.贪心.分治.回溯. ...
- [Google Guava] 强大的集合工具类:java.util.Collections中未包含的集合工具
转载的,有问题请联系我 原文链接 译文链接 译者:沈义扬,校对:丁一 尚未完成: Queues, Tables工具类 任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collecti ...
- [BZOJ]最长道路
题目 点这里看题目. BZOJ 上是权限题目. 分析 这道题可以用点分治,但是我就是喜欢边分治 QAQ . 分治过程中,我们考虑经过分治边的路径的最大痛苦值.一条经过分治边的路径会被 ...
- Random Point in Triangle【随机数解决期望值问题】
Random Point in Triangle 题目链接(点击) 题目描述 Bobo has a triangle ABC with A(x1,y1),B(x2,y2)A(x1,y1),B(x2,y ...