您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
mybatis-plus特性学习
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
mybatis-plus特性学习
自猿其说Tech
2022-05-10
IP归属:未知
15640浏览
计算机编程
### 1 对比Mybatis #### 1.1 Mybatis解决了什么问题 这次分享,虽然我们在学习mp,但是我们得明确一个概念:mybatis是一个很优秀的持久层框架,mybatis-plus是站在巨人的肩膀上进行了一些体验增强。 1)如果没有Mybatis,我们会怎么查询数据库? dao层定义接口,然后定义实现类实现接口,实现类中写JDBC连接数据库代码(注册驱动、获取连接、获取preparedstatement对象,传输sql获取结果集、解析结果集、释放连接)。 问题:代码冗余、sql、数据库配置和代码耦合、向sql语句传参麻烦、解析结果集麻烦 2)Mybatis通过动态代理的方式,封装了JDBC连接的操作,我们只需要开发dao接口,在xml中写sql,并遵循mybatis开发规范,即可完成数据库访问。 #### 1.2 Mybatis-plus vs Mybatis 1. MyBatis-plus是一款MyBatis的增强工具,在MyBatis 的基础上只做增强不做改变; 2. Mybatis-plus支持Mybatis的所有特性,并在它的基础上有如下增强:https://baomidou.com/pages/24112f/#%E7%89%B9%E6%80%A7 本文我们重点了解以下特性: - 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 - 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 - 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用 - 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询 - 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作 #### 1.3 Mybatis开发规范 - xml文件通过namespace和dao层接口绑定,配置文件中通过mybatis.mapper-locations指定xml文件的位置 - xml文件中定义的SQL语句段,有唯一的id,这个id值和dao层接口的方法名对应 - 传参有2种方式,#和$,支持通过Map传值、Bean传值(推荐)、单值传递 - 支持动态SQL - where+if实现动态拼接查询条件 #### 1.4 编码简单对比 ##### 1.4.1 maven依赖、配置 ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <!-- lombok、数据库驱动、连接池等(省略) --> ``` ``` # 查看mybatis-plus生成的sql logging.level.包名: debug mybatis-plus.mapper-locations: classpath:/mapper/*.xml ``` ##### 1.4.2 dao层 ```java @Data @TableName("`sys_user`") public class SysUser { @TableId(value = "user_id", type = IdType.AUTO) private Long userId; @TableField(value = "name") private String name; } ``` ```java @Mapper public interface SysUserDao extends BaseMapper<SysUser> {} ``` ```java <?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="cn.yskcoder.fire.mapper.SysUserMapper"> <resultMap id="BaseResultMap" type="cn.yskcoder.fire.domain.SysUser"> <id property="userId" column="user_id" jdbcType="BIGINT"/> <result property="name" column="name" jdbcType="VARCHAR"/> </resultMap> </mapper> ``` ##### 1.4.3 service层 ```java public interface SysUserService extends IService<SysUser> {} ``` ```java @Service public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService{} ``` ### 2 mybatis-plus特性 #### 2.1 代码自动生成 自动生成的代码包括:dao层接口、xml文件、service层接口、service层实现类、表对应实体对象类 - 方法一:通过执行代码https://baomidou.com/pages/d357af/#%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B - 方法二:MybatisX插件https://baomidou.com/pages/ba5b24/#%E5%8A%9F%E8%83%BD 这个插件除了自动生成代码,还可是实现dao层接口和XML中对应的sql跳转(点击小鸟图标) ![](//img1.jcloudcs.com/developer.jdcloud.com/f626a21d-02da-492b-95af-60fd794bb04320220510155303.png) #### 2.2 单表CRUD 以下方法是dao层接口继承的BaseMaper提供的一些简单的单表方法。 ```java // 增 int insert(T entity); // 删 int deleteById(Serializable id); int delete(Wrapper<T> queryWrapper); // 改 int updateById(T entity); int update(T entity, Wrapper<T> updateWrapper); // 简单查询(查详情) T selectById(Serializable id); T selectById(Serializable id); ``` #### 2.3 条件构造器 + lambad形式调用 使用mybatis-plus进行条件查询的时候,我们会用到条件构造器QueryWrapper对象,它是用来构造查询条件的,它可以生成sql的select/where/order by/group by/having等关键字 ```java QueryWrapper<OrderEntity> wrappers = new QueryWrapper<>(); wrappers.select(OrderEntity.ID, OrderEntity.MANHOUR_CODE, OrderEntity.FIRST_CLASS,OrderEntity.SECOND_CLASS) .eq(isJoin(query.getCode()), OrderEntity.MANHOUR_CODE, query.getCode()) .eq(isJoin(query.getUpdateUser()), OrderEntity.UPDATE_USER, query.getUpdateUser()) .eq(isJoin(query.getStatus()), OrderEntity.STATUS, query.getStatus()) .eq(OrderEntity.YN, 0) .orderByDesc(OrderEntity.UPDATE_TIME); ``` 2)条件构造器也可以写成lambad形式,它们写法上的区别基本就在于获取实体类字段名方式不同。 上面的写法需要在实体类中为每一个字段设置一个字段名常量(可以自动生成),lambda不需要。 ```java LambdaQueryWrapper<OrderEntity> wrappers = Wrappers.<OrderEntity>lambdaQuery() .select(OrderEntity::getId, OrderEntity::getCode, OrderEntityEntity::getName, OrderEntity::getFirstClass) .eq(isJoin(query.getCode()), OrderEntity::getCode, query.getCode()) .eq(isJoin(query.getUpdateUser()), OrderEntity::getUpdateUser, query.getUpdateUser()) .eq(isJoin(query.getStatus()), OrderEntity::getStatus, query.getStatus()) .eq(OrderEntity::getYn, 0) .OrderByDesc(OrderEntity::getUpdateTime); ``` ```java // 列表查询,不考虑分页使用这个方法 List<T> selectList(Wrapper<T> queryWrapper); ``` #### 2.4 分页查询 需要添加一个分页插件,在springboot中表现为配置一个Bean(根据jar包版本配置对应的Bean) https://baomidou.com/pages/2976a3/#spring-boot ```java // 查列表,考虑分页 <P extends IPage<T>> P selectPage(P page, Wrapper<T> queryWrapper); ``` 分页查询的sql,mbatis实际执行了2步操作:首先统计count,然后进行查询 ![](//img1.jcloudcs.com/developer.jdcloud.com/d7ca396d-3c12-4b20-a942-c91eb456827920220510160059.png) 分页查询的结果: 重点关注这几个:records结果记录、total记录总数、pages页数、current当前页数、size每页记录数 ```json { "records": [ { "id": 2, "name": "Jack", "age": 20, "email": "test2@baomidou.com" }, { "id": 3, "name": "Jack", "age": 20, "email": "test2@baomidou.com" }, { "id": 4, "name": "Jack", "age": 20, "email": "test2@baomidou.com" } ], "total": 13, "size": 3, "current": 1, "orders": [], "optimizeCountSql": true, "searchCount": true, "countId": null, "maxLimit": null, "pages": 5 } ``` #### 2.5 多数据源(3步完成) 1)引入依赖 ``` <!-- 多数据源 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.1.0</version> </dependency> ``` 2)配置多数据源,primary和slave数据源,还可以再继续配置 ```yaml spring: datasource: dynamic: primary: master datasource: master: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mp_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&jdbcCompliantTruncation=false&serverTimezone=GMT%2B8 username: root password: root slave: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/fire?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&jdbcCompliantTruncation=false&serverTimezone=GMT%2B8 username: root password: root ``` 3)使用:@DS 可以注解在方法上或类上 如果没有该注解,默认连接主数据源 #### 2.6 ActiveRecord模式 实体类只需继承 Model 类可以直接调用上面提到的一些单表方法,比如insert()、updateById()等。 #### 2.7 自定义sql实现分页 ```java // 把Page当成List即可,自定义的方法中传入一个Page对象用于生成limit关键字 // user对象可以不传 // user对象可以是一个普通对象,可以用来给sql传参 Page<User> pageResult = userMapper.myPageMethod(page, user); 注意:xml的sql结束处不要写分号,否则,limit会拼在分号后面,会报错 ``` ### 3 总结 - mybatis是一个优秀的dao层框架,mybatis-plu站在巨人的肩膀上进行了体验增强。 - mybatis-plus结合一些插件使用开发很方便,MybatisX、Lombok、Database Tools and SQL - mp的多数据源实现很简单,操作3步就能使用,基本不会报错。 - mybatis-plus主要是对单表crud、分页等操作进行了api封装,我们可以不用再写sql,只要dao层接口 extends BaseMapper<pojo>,便可以直接使用mp提供的各种单表方法,但是一些复杂的sql查询,还有多表关联,如果不涉及到分页,我觉得和之前mybatis使用一样,还是自己写sql比较方便。 ### 4 参考文档 - mybatis-plus官方文档:https://baomidou.com/pages/24112f/ - mybatis-plus官方demo:https://github.com/baomidou/mybatis-plus-samples - mybatis-plus入门使用:https://www.jianshu.com/p/ceb1df475021 - mybatis-plus条件构造器了解:https://www.jianshu.com/p/c5537559ae3a - 自定义sql实现分页:https://icode9.com/content-2-945830.html ------------ ###### 自猿其说Tech-JDL京东物流技术与数据智能部 ###### 作者:杨力
原创文章,需联系作者,授权转载
上一篇:前端工程化在 WMS 6.0 中的实践
下一篇:Mapstruct源码解析与使用
相关文章
Taro小程序跨端开发入门实战
Flutter For Web实践
配运基础数据缓存瘦身实践
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号