Mybatis plus
介绍
-
如果写一个数据库表的 crud 接口,正常流程:编写实体类-》编写 Controller-》编写 Service-》编写 DAO-》-》编写 XML 文件
-
特别是管理后台,多数都是简单的 CRUD,用普通的 MyBatis 有的鸡肋
-
介绍
- 官网 https://baomidou.com/
- 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生
- 是怎么增强的呢?已经封装好了一些 crud 方法,我们不需要再写 XML 了,直接调用这些方法就行,类似 JPA 但优于 JPA
-
更多特性
1无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
2
3损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
4
5强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
6
7支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
8
9支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
10
11支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
12支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
13
14内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
15
16内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
17分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
18
19内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
20
21内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
准备数据
xd_shop
1
2CREATE TABLE `address` (
3 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
4 `user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
5 `default_status` int(1) DEFAULT NULL COMMENT '是否默认收货地址:0->否;1->是',
6 `receive_name` varchar(64) DEFAULT NULL COMMENT '收发货人姓名',
7 `phone` varchar(64) DEFAULT NULL COMMENT '收货人电话',
8 `province` varchar(64) DEFAULT NULL COMMENT '省/直辖市',
9 `city` varchar(64) DEFAULT NULL COMMENT '市',
10 `region` varchar(64) DEFAULT NULL COMMENT '区',
11 `detail_address` varchar(200) DEFAULT NULL COMMENT '详细地址',
12 `create_time` datetime DEFAULT NULL,
13 PRIMARY KEY (`id`)
14) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='电商-公司收发货地址表';
15
16
17
18CREATE TABLE `banner` (
19 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
20 `img` varchar(524) DEFAULT NULL COMMENT '图片',
21 `url` varchar(524) DEFAULT NULL COMMENT '跳转地址',
22 `weight` int(11) DEFAULT NULL COMMENT '权重',
23 PRIMARY KEY (`id`)
24) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
25
26INSERT INTO `banner` (`id`, `img`, `url`, `weight`)
27VALUES
28 (1, 'https://file.xdclass.net/video/2020/alibabacloud/zx-lbt.jpeg', 'https://m.xdclass.net/#/member', 1),
29 (2, 'https://file.xdclass.net/video/%E5%AE%98%E7%BD%91%E8%BD%AE%E6%92%AD%E5%9B%BE/20%E5%B9%B4%E5%8F%8C11%E9%98%BF%E9%87%8C%E4%BA%91/fc-lbt.jpeg', 'https://www.aliyun.com/1111/pintuan-share?ptCode=MTcwMTY3MzEyMjc5MDU2MHx8MTE0fDE%3D&userCode=r5saexap', 3),
30 (3, 'https://file.xdclass.net/video/%E5%AE%98%E7%BD%91%E8%BD%AE%E6%92%AD%E5%9B%BE/20%E5%B9%B4%E5%8F%8C11%E9%98%BF%E9%87%8C%E4%BA%91/FAN-lbu-vip.jpeg', 'https://file.xdclass.net/video/%E5%AE%98%E7%BD%91%E8%BD%AE%E6%92%AD%E5%9B%BE/Nginx.jpeg', 2);
31
32
33
34CREATE TABLE `coupon` (
35 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
36 `category` varchar(11) DEFAULT NULL COMMENT '优惠卷类型[NEW_USER注册赠券,TASK任务卷,PROMOTION促销劵]',
37 `publish` varchar(11) DEFAULT NULL COMMENT '发布状态, PUBLISH发布,DRAFT草稿,OFFLINE下线',
38 `coupon_img` varchar(524) DEFAULT NULL COMMENT '优惠券图片',
39 `coupon_title` varchar(128) DEFAULT NULL COMMENT '优惠券标题',
40 `price` decimal(16,2) DEFAULT NULL COMMENT '抵扣价格',
41 `user_limit` int(11) DEFAULT NULL COMMENT '每人限制张数',
42 `start_time` datetime DEFAULT NULL COMMENT '优惠券开始有效时间',
43 `end_time` datetime DEFAULT NULL COMMENT '优惠券失效时间',
44 `publish_count` int(11) DEFAULT NULL COMMENT '优惠券总量',
45 `stock` int(11) DEFAULT '0' COMMENT '库存',
46 `add_one` int(11) DEFAULT NULL COMMENT '是否叠加0是不行,1是可以',
47 `create_time` datetime DEFAULT NULL,
48 `condition_price` decimal(16,2) DEFAULT NULL COMMENT '满多少才可以使用',
49 PRIMARY KEY (`id`)
50) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
51
52
53
54
55CREATE TABLE `product` (
56 `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
57 `title` varchar(128) DEFAULT NULL COMMENT '标题',
58 `cover_img` varchar(128) DEFAULT NULL COMMENT '封面图',
59 `detail` varchar(256) DEFAULT '' COMMENT '详情',
60 `old_price` decimal(16,2) DEFAULT NULL COMMENT '老价格',
61 `price` decimal(16,2) DEFAULT NULL COMMENT '新价格',
62 `stock` int(11) DEFAULT NULL COMMENT '库存',
63 `create_time` datetime DEFAULT NULL COMMENT '创建时间',
64 `lock_stock` int(11) DEFAULT '0' COMMENT '锁定库存',
65 PRIMARY KEY (`id`)
66) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
67
68
69
70CREATE TABLE `product_order` (
71 `id` bigint(11) NOT NULL AUTO_INCREMENT,
72 `out_trade_no` varchar(64) DEFAULT NULL COMMENT '订单唯一标识',
73 `state` varchar(11) DEFAULT NULL COMMENT 'NEW 未支付订单,PAY已经支付订单,CANCEL超时取消订单',
74 `create_time` datetime DEFAULT NULL COMMENT '订单生成时间',
75 `total_fee` decimal(16,2) DEFAULT NULL COMMENT '订单总金额',
76 `pay_fee` decimal(16,2) DEFAULT NULL COMMENT '订单实际支付价格',
77 `pay_type` varchar(64) DEFAULT NULL COMMENT '支付类型,微信-银行-支付宝',
78 `nickname` varchar(64) DEFAULT NULL COMMENT '昵称',
79 `head_img` varchar(524) DEFAULT NULL COMMENT '头像',
80 `user_id` int(11) DEFAULT NULL COMMENT '用户id',
81 `del` int(5) DEFAULT '0' COMMENT '0表示未删除,1表示已经删除',
82 `update_time` datetime DEFAULT NULL COMMENT '更新时间',
83 `order_type` varchar(32) DEFAULT NULL COMMENT '订单类型 DAILY普通单,PROMOTION促销订单',
84 `receiver_address` varchar(1024) DEFAULT NULL COMMENT '收货地址 json存储',
85 PRIMARY KEY (`id`)
86) ENGINE=MyISAM DEFAULT CHARSET=utf8;
87
88
89CREATE TABLE `product_order_item` (
90 `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
91 `product_order_id` bigint(11) DEFAULT NULL COMMENT '订单号',
92 `out_trade_no` varchar(32) DEFAULT NULL,
93 `product_id` bigint(11) DEFAULT NULL COMMENT '产品id',
94 `product_name` varchar(128) DEFAULT NULL COMMENT '商品名称',
95 `product_img` varchar(524) DEFAULT NULL COMMENT '商品图片',
96 `buy_num` int(11) DEFAULT NULL COMMENT '购买数量',
97 `create_time` datetime DEFAULT NULL,
98 `total_fee` decimal(16,2) DEFAULT NULL COMMENT '购物项商品总价格',
99 `pay_fee` decimal(16,0) DEFAULT NULL COMMENT '购物项商品支付总价格',
100 PRIMARY KEY (`id`)
101) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
102
103
104
105CREATE TABLE `user` (
106 `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
107 `name` varchar(128) DEFAULT NULL COMMENT '昵称',
108 `pwd` varchar(124) DEFAULT NULL COMMENT '密码',
109 `head_img` varchar(524) DEFAULT NULL COMMENT '头像',
110 `slogan` varchar(524) DEFAULT NULL COMMENT '用户签名',
111 `sex` tinyint(2) DEFAULT '1' COMMENT '0表示女,1表示男',
112 `points` int(10) DEFAULT '0' COMMENT '积分',
113 `create_time` datetime DEFAULT NULL,
114 `mail` varchar(64) DEFAULT NULL COMMENT '邮箱',
115 `secret` varchar(12) DEFAULT NULL COMMENT '盐,用于个人敏感信息处理',
116 PRIMARY KEY (`id`),
117 UNIQUE KEY `mail_idx` (`mail`)
118) ENGINE=InnoDB DEFAULT CHARSET=utf8;
119
SpringBoot2.X 整合 MybatisPlus+Lombok
添加依赖
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7 <artifactId>spring-boot-starter-parent</artifactId>
8 <version>2.4.1</version>
9 <relativePath/> <!-- lookup parent from repository -->
10 </parent>
11 <groupId>net.xdclass</groupId>
12 <artifactId>1024shop-manager</artifactId>
13 <version>0.0.1-SNAPSHOT</version>
14 <name>1024shop-manager</name>
15 <description>Demo project for Spring Boot</description>
16
17 <properties>
18 <java.version>11</java.version>
19 </properties>
20
21 <dependencies>
22 <dependency>
23 <groupId>org.springframework.boot</groupId>
24 <artifactId>spring-boot-starter-web</artifactId>
25 </dependency>
26
27 <dependency>
28 <groupId>org.springframework.boot</groupId>
29 <artifactId>spring-boot-starter-test</artifactId>
30 <scope>test</scope>
31 </dependency>
32
33 <!-- lombok -->
34 <dependency>
35 <groupId>org.projectlombok</groupId>
36 <artifactId>lombok</artifactId>
37 <version>1.18.16</version>
38 <scope>provided</scope>
39 </dependency>
40
41 <!-- mysql -->
42 <dependency>
43 <groupId>mysql</groupId>
44 <artifactId>mysql-connector-java</artifactId>
45 </dependency>
46
47 <!--mybatis plus和springboot整合-->
48 <dependency>
49 <groupId>com.baomidou</groupId>
50 <artifactId>mybatis-plus-boot-starter</artifactId>
51 <version>3.4.1</version>
52 </dependency>
53
54
55 <!-- 代码自动生成依赖 begin -->
56 <dependency>
57 <groupId>com.baomidou</groupId>
58 <artifactId>mybatis-plus-generator</artifactId>
59 <version>3.4.1</version>
60 </dependency>
61 <!-- velocity -->
62 <dependency>
63 <groupId>org.apache.velocity</groupId>
64 <artifactId>velocity-engine-core</artifactId>
65 <version>2.0</version>
66 </dependency>
67 <!-- 代码自动生成依赖 end-->
68
69 </dependencies>
70
71 <build>
72 <plugins>
73 <plugin>
74 <groupId>org.springframework.boot</groupId>
75 <artifactId>spring-boot-maven-plugin</artifactId>
76 </plugin>
77 <plugin>
78 <groupId>org.apache.maven.plugins</groupId>
79 <artifactId>maven-compiler-plugin</artifactId>
80 <configuration>
81 <source>15</source>
82 <target>15</target>
83 </configuration>
84 </plugin>
85 </plugins>
86 </build>
87
88
89 <!-- 代码库 -->
90 <repositories>
91 <repository>
92 <id>maven-ali</id>
93 <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
94 <releases>
95 <enabled>true</enabled>
96 </releases>
97 <snapshots>
98 <enabled>true</enabled>
99 <updatePolicy>always</updatePolicy>
100 <checksumPolicy>fail</checksumPolicy>
101 </snapshots>
102 </repository>
103 </repositories>
104
105 <pluginRepositories>
106 <pluginRepository>
107 <id>public</id>
108 <name>aliyun nexus</name>
109 <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
110 <releases>
111 <enabled>true</enabled>
112 </releases>
113 <snapshots>
114 <enabled>false</enabled>
115 </snapshots>
116 </pluginRepository>
117 </pluginRepositories>
118
119
120
121</project>
122
增加数据库配置 application.properties
1server.port=8081
2#==============================数据库相关配置========================================
3spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
4spring.datasource.url=jdbc:mysql://192.168.31.101:50000/xd_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
5spring.datasource.username =root
6spring.datasource.password =123456
7
包扫描:添加 @MapperScan 注解
1package net.xdclass.shopmanager;
2
3import org.mybatis.spring.annotation.MapperScan;
4import org.springframework.boot.SpringApplication;
5import org.springframework.boot.autoconfigure.SpringBootApplication;
6
7@SpringBootApplication
8@MapperScan("net.xdclass.shopmanager.mapper")
9public class Application {
10
11 public static void main(String[] args) {
12 SpringApplication.run(Application.class, args);
13
14 }
15
16}
17
快速上手
基础准备
- 统一接口返回协议-JsonData
1package net.xdclass.shopmanager.util;
2
3import lombok.AllArgsConstructor;
4import lombok.Data;
5import lombok.NoArgsConstructor;
6
7@Data
8@AllArgsConstructor //会生成一个包含所有变量
9@NoArgsConstructor //生成一个无参数的构造方法
10public class JsonData {
11 /**
12 * 状态码 0 表示成功,1表示处理中,-1表示失败
13 */
14 private Integer code;
15 /**
16 * 数据
17 */
18 private Object data;
19 /**
20 * 描述
21 */
22 private String msg;
23
24 // 成功,传入数据
25 public static JsonData buildSuccess() {
26 return new JsonData(0, null, null);
27 }
28
29 // 成功,传入数据
30 public static JsonData buildSuccess(Object data) {
31 return new JsonData(0, data, null);
32 }
33
34 // 失败,传入描述信息
35 public static JsonData buildError(String msg) {
36 return new JsonData(-1, null, msg);
37 }
38
39 // 失败,传入描述信息,状态码
40 public static JsonData buildError(String msg, Integer code) {
41 return new JsonData(code, null, msg);
42 }
43
44}
BannerDO 类编写
1@Data
2@TableName("banner")//表名映射
3public class BannerDO {
4
5 private Integer id;
6 private String img;
7 private String url;
8 private Integer weight;
9}
Controller
1@RestController
2@RequestMapping("/api/banner/v1")
3public class BannerController {
4
5 //注入有红色告警可以忽略,idea识别问题
6 @Autowired
7 private BannerService bannerService;
8
9 @RequestMapping("list")
10 public JsonData list(){
11
12 return JsonData.buildSuccess(bannerService.list());
13 }
14
15}
Service
1public interface BannerService {
2 List<BannerDO> list();
3}
ServiceImpl
1@Service
2public class BannerServiceImpl implements BannerService {
3 @Autowired
4 private BannerMapper bannerMapper;
5
6 @Override
7 public List<BannerDO> list() {
8 //查询全部
9 List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());
10 return list;
11 }
12}
Mapper
1import com.baomidou.mybatisplus.core.mapper.BaseMapper;
2import net.xdclass.shopmanager.model.BannerDO;
3
4public interface BannerMapper extends BaseMapper<BannerDO> {
5}
6
测试
1// http://localhost:8081/api/banner/v1/list
2
3{
4 "code": 0,
5 "data": [
6 {
7 "id": 1,
8 "img": "https://file.xdclass.net/video/2020/alibabacloud/zx-lbt.jpeg",
9 "url": "https://m.xdclass.net/#/member",
10 "weight": 1
11 },
12 {
13 "id": 2,
14 "img": "https://file.xdclass.net/video/%E5%AE%98%E7%BD%91%E8%BD%AE%E6%92%AD%E5%9B%BE/20%E5%B9%B4%E5%8F%8C11%E9%98%BF%E9%87%8C%E4%BA%91/fc-lbt.jpeg",
15 "url": "https://www.aliyun.com/1111/pintuan-share?ptCode=MTcwMTY3MzEyMjc5MDU2MHx8MTE0fDE%3D&userCode=r5saexap",
16 "weight": 3
17 },
18 {
19 "id": 3,
20 "img": "https://file.xdclass.net/video/%E5%AE%98%E7%BD%91%E8%BD%AE%E6%92%AD%E5%9B%BE/20%E5%B9%B4%E5%8F%8C11%E9%98%BF%E9%87%8C%E4%BA%91/FAN-lbu-vip.jpeg",
21 "url": "https://file.xdclass.net/video/%E5%AE%98%E7%BD%91%E8%BD%AE%E6%92%AD%E5%9B%BE/Nginx.jpeg",
22 "weight": 2
23 }
24 ],
25 "msg": null
26}
单元测试、控制台数据 SQL
Spring Boot Test 是在 Spring Test 之上的再次封装, 使用 @SpringBootTest 后,Spring 将加载所有被管理的 bean,等同于启动了整个服务
项目添加依赖
1<dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-test</artifactId>
4</dependency>
MyBatis plus 配置控制台打印日志
1#配置mybatis plus打印sql日志
2mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
项目新建测试
1package net.xdclass.shopmanager;
2
3import lombok.extern.slf4j.Slf4j;
4import net.xdclass.shopmanager.model.BannerDO;
5import net.xdclass.shopmanager.service.BannerService;
6import org.junit.jupiter.api.Test;
7import org.springframework.beans.factory.annotation.Autowired;
8import org.springframework.boot.test.context.SpringBootTest;
9
10import java.util.List;
11
12@SpringBootTest(classes = Application.class)
13@Slf4j
14class ApplicationTests {
15
16 @Autowired
17 private BannerService bannerService;
18
19 @Test
20 public void testBannerList(){
21 List<BannerDO> list = bannerService.list();
22 log.info("轮播图列表:{}",list);
23 }
24
25}
核心类 BaseMapper
核心类介绍: Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得 CRUD 功能
- 方法很多:记住常用的几个就行
1
2/**
3 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
4 * <p>这个 Mapper 支持 id 泛型</p>
5 *
6 * @author hubin
7 * @since 2016-01-23
8 */
9public interface BaseMapper<T> extends Mapper<T> {
10
11 /**
12 * 插入一条记录
13 *
14 * @param entity 实体对象
15 */
16 int insert(T entity);
17
18 /**
19 * 根据 ID 删除
20 *
21 * @param id 主键ID
22 */
23 int deleteById(Serializable id);
24
25 /**
26 * 根据 columnMap 条件,删除记录
27 *
28 * @param columnMap 表字段 map 对象
29 */
30 int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
31
32 /**
33 * 根据 entity 条件,删除记录
34 *
35 * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
36 */
37 int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
38
39 /**
40 * 删除(根据ID 批量删除)
41 *
42 * @param idList 主键ID列表(不能为 null 以及 empty)
43 */
44 int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
45
46 /**
47 * 根据 ID 修改
48 *
49 * @param entity 实体对象
50 */
51 int updateById(@Param(Constants.ENTITY) T entity);
52
53 /**
54 * 根据 whereEntity 条件,更新记录
55 *
56 * @param entity 实体对象 (set 条件值,可以为 null)
57 * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
58 */
59 int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
60
61 /**
62 * 根据 ID 查询
63 *
64 * @param id 主键ID
65 */
66 T selectById(Serializable id);
67
68 /**
69 * 查询(根据ID 批量查询)
70 *
71 * @param idList 主键ID列表(不能为 null 以及 empty)
72 */
73 List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
74
75 /**
76 * 查询(根据 columnMap 条件)
77 *
78 * @param columnMap 表字段 map 对象
79 */
80 List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
81
82 /**
83 * 根据 entity 条件,查询一条记录
84 *
85 * @param queryWrapper 实体对象封装操作类(可以为 null)
86 */
87 T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
88
89 /**
90 * 根据 Wrapper 条件,查询总记录数
91 *
92 * @param queryWrapper 实体对象封装操作类(可以为 null)
93 */
94 Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
95
96 /**
97 * 根据 entity 条件,查询全部记录
98 *
99 * @param queryWrapper 实体对象封装操作类(可以为 null)
100 */
101 List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
102
103 /**
104 * 根据 Wrapper 条件,查询全部记录
105 *
106 * @param queryWrapper 实体对象封装操作类(可以为 null)
107 */
108 List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
109
110 /**
111 * 根据 Wrapper 条件,查询全部记录
112 * <p>注意: 只返回第一个字段的值</p>
113 *
114 * @param queryWrapper 实体对象封装操作类(可以为 null)
115 */
116 List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
117
118 /**
119 * 根据 entity 条件,查询全部记录(并翻页)
120 *
121 * @param page 分页查询条件(可以为 RowBounds.DEFAULT)
122 * @param queryWrapper 实体对象封装操作类(可以为 null)
123 */
124 <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
125
126 /**
127 * 根据 Wrapper 条件,查询全部记录(并翻页)
128 *
129 * @param page 分页查询条件
130 * @param queryWrapper 实体对象封装操作类
131 */
132 <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
133}
QueryWrapper 介绍
- 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
1List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());
MyBatis plus 常用注解
- @TableName 用于定义表名
- @TableId 用于定义表的主键
- 属性
1value 用于定义主键字段名
2type 用于定义主键类型(主键策略 IdType)
- 主键策略
1IdType.AUTO 主键自增,系统分配,不需要手动输入
2IdType.NONE 未设置主键
3IdType.INPUT 需要自己输入 主键值
4IdType.ASSIGN_ID 系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)
5IdType.ASSIGN_UUID 系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)
@TableField 用于定义表的非主键字段
- 属性
1value 用于定义非主键字段名,用于别名匹配,假如java对象属性和数据库属性不一样
2
3exist 用于指明是否为数据表的字段, true 表示是,false 为不是,假如某个java属性在数据库没对应的字段则要标记为faslse
4
5fill 用于指定字段填充策略(FieldFill,用的不多)
6 字段填充策略:一般用于填充 创建时间、修改时间等字段
7 FieldFill.DEFAULT 默认不填充
8 FieldFill.INSERT 插入时填充
9 FieldFill.UPDATE 更新时填充
10 FieldFill.INSERT_UPDATE 插入、更新时填充。
示例
1@Data
2@TableName("banner")//表名映射
3public class BannerDO {
4
5 @TableId(value = "id", type = IdType.AUTO)
6 private Integer id;
7
8 private String img;
9
10 private String url;
11
12 @TableField("weight")
13 private Integer weightAAA;
14
15 @TableField(exist = false)
16 private Date createTime;
17}
18
查询
- selectById
- selectBatchIds
- selectOne
- selectCount
- selectList
1package net.xdclass.shopmanager;
2
3import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4import lombok.extern.slf4j.Slf4j;
5import net.xdclass.shopmanager.mapper.BannerMapper;
6import net.xdclass.shopmanager.model.BannerDO;
7import net.xdclass.shopmanager.service.BannerService;
8import org.junit.jupiter.api.Test;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.boot.test.context.SpringBootTest;
11
12import java.util.Arrays;
13import java.util.List;
14
15@SpringBootTest(classes = Application.class)
16@Slf4j
17class ApplicationTests {
18
19 @Autowired
20 private BannerService bannerService;
21
22 @Autowired
23 private BannerMapper bannerMapper;
24
25 /**
26 * 根据主键ID查找
27 */
28 @Test
29 public void testSelectById(){
30 BannerDO bannerDO = bannerMapper.selectById(1);
31 log.info("bannerDO:{}",bannerDO);
32 }
33
34 /**
35 * 批量查找根据主键
36 */
37 @Test
38 public void selectBatchIds(){
39 List<BannerDO> bannerDOS = bannerMapper.selectBatchIds(Arrays.asList(1, 2));
40 log.info("bannerDOS:{}",bannerDOS);
41 }
42
43 /**
44 * 选择1条
45 */
46 @Test
47 public void selectOne(){
48 BannerDO bannerDO = bannerMapper.selectOne(new QueryWrapper<BannerDO>().eq("id",1));
49 log.info("bannerDO:{}",bannerDO);
50 }
51
52 /**
53 * 统计行数
54 */
55 @Test
56 public void selectCount(){
57 int size = bannerMapper.selectCount(null);
58 log.info("size:{}",size);
59 }
60
61 /**
62 * 查询所有数据
63 */
64 @Test
65 public void testBannerList(){
66 List<BannerDO> list = bannerService.list();
67 log.info("轮播图列表:{}",list);
68 }
69
70}
71
新增
1 /**
2 * 新增
3 */
4 @Test
5 public void testAdd(){
6 BannerDO bannerDO = new BannerDO();
7 bannerDO.setImg("xxx");
8 bannerDO.setUrl("xdclass.net");
9 bannerMapper.insert(bannerDO);
10 log.info("轮播图:{}", bannerDO);
11 }
删除
- 根据 id 删除
1 /**
2 * 根据id删除
3 */
4 @Test
5 public void testDeleteId(){
6 //影响行数
7 int rows = bannerMapper.deleteById(4);
8 log.info("rows:{}",rows);
9 }
- 条件删除
1 /**
2 * 通用删除操作 deleteByMap map要写列名条件 不能是实体属性名
3 */
4 @Test
5 public void testCommonDeleteByMap() {
6 Map<String, Object> columnMap = new HashMap<>();
7 columnMap.put("weight",12);
8 columnMap.put("url","bbb");
9 int result=bannerMapper.deleteByMap(columnMap);
10 System.out.println("*******************"+result);
11 }
更新
- queryWrapper 更新操作
1BannerDO bannerDO = new BannerDO();
2bannerDO.setImg("iiiii");
3//空字段不会更新,只会更新设置的字段
4bannerMapper.update(bannerDO,new QueryWrapper<BannerDO>().eq("id","1"));
- updateWrapper 更新操作
1UpdateWrapper updateWrapper = new UpdateWrapper();
2//设置要更新的字段和值,key是db的属性名称
3updateWrapper.set("img","uuuu");
4//条件
5updateWrapper.eq("id",1);
6
7bannerMapper.update(null,updateWrapper);
查询封装类 QueryWrapper 比较 API
QueryWrapper 介绍
- 可以封装 SQL 对象,包括 where 条件,order by 排序,select 哪些字段等等
- 查询包装类,可以封装多数查询条件,泛型指定返回的实体类
1List<BannerDO> list = bannerMapper.selectList(new QueryWrapper<BannerDO>());
-
核心 API
- eq 等于
- ne 不等于
- gt 大于
- ge 大于等于
- lt 小于
- le 小于等于
- or 拼接 or
- between 两个值中间
- notBetween 不在两个值中间
-
- like 模糊匹配
- notLike 不像
- likeLeft 左匹配
- likeRight 右边匹配
- isNull 字段为空
- in in 查询
- groupBy 分组
- orderByAsc 升序
- orderByDesc 降序
- having having 查询
1 @Test
2 public void testQueryWrapper(){
3 QueryWrapper queryWrapper = new QueryWrapper();
4 queryWrapper.eq("id", 1);
5 queryWrapper.ne("url", "bbbc.com");
6 List list = bannerMapper.selectList(queryWrapper);
7 log.info("list:{}",list); // list:[BannerDO(id=1, img=https://file.xdclass.net/video/2020/alibabacloud/zx-lbt.jpeg, url=https://m.xdclass.net/#/member, weightAAA=1, createTime=null)]
8 }
配置分页插件
新建配置类
1package net.xdclass.shopmanager.config;
2
3import com.baomidou.mybatisplus.annotation.DbType;
4import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
5import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
6import org.springframework.context.annotation.Bean;
7import org.springframework.context.annotation.Configuration;
8
9@Configuration
10public class MybatisPlusPageConfig {
11
12 /* 旧版本配置
13 @Bean
14 public PaginationInterceptor paginationInterceptor(){
15 return new PaginationInterceptor();
16 }*/
17
18
19 /**
20 * 新的分页插件
21 */
22 @Bean
23 public MybatisPlusInterceptor mybatisPlusInterceptor() {
24 MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
25 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
26 return interceptor;
27 }
28
29}
30
31
测试分页
1 /***
2 * 测试分页
3 */
4 @Test
5 public void testPage() {
6 QueryWrapper<BannerDO> wrapper = new QueryWrapper<>();
7 wrapper.eq("weight",4);
8 //第1页,每页2条
9 Page<BannerDO> page = new Page<>(1, 2);
10 IPage<BannerDO> iPage = bannerMapper.selectPage(page, wrapper);
11 System.out.println("总条数"+iPage.getTotal());
12 System.out.println("总页数"+iPage.getPages());
13 //获取当前数据
14 System.out.println(iPage.getRecords().toString());
15 }
MyBatis plus 自定义 XML SQL 脚本
Mapper 类中增加方法
1package net.xdclass.shopmanager.mapper;
2
3import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4import net.xdclass.shopmanager.model.BannerDO;
5
6import java.util.List;
7
8public interface BannerMapper extends BaseMapper<BannerDO> {
9 List<BannerDO> list();
10}
11
新建 XML src\main\resources\mapper\BannerMapper.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3<!--这个名称空间是Mapper接口的路径,记得修改-->
4<mapper namespace="net.xdclass.shopmanager.mapper.BannerMapper">
5 <select id="list" resultType="net.xdclass.shopmanager.model.BannerDO">
6 select * from banner
7 </select>
8</mapper>
配置文件告诉 mapper.xml 路径(如果采用默认路径可以不配)
1#默认配置路径
2mybatis-plus.mapper-locations=classpath*:/mapper/*Mapper.xml
测试
1 @Test
2 public void testList(){
3 List<BannerDO> list = bannerMapper.list();
4 log.info("list:{}",list);
5 }
MyBatis plus 全局配置案例
配置 Myabits 的全局配置文件
- 注意:config-location 和 configuration 不能同时出现,需要注释配置文件里的相关配置
1#配置文件
2server.port=8081
3#==============================数据库相关配置
4spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
5spring.datasource.url=jdbc:mysql://192.168.0.114:3306/xd_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
6spring.datasource.username=root
7spring.datasource.password=xdclass.net
8
9#开启控制台打印sql
10#mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
11
12#配置mybatis plus打印sql日志
13#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
14
15#配置最新全局配置文件!!!!
16mybatis-plus.config-location = classpath:mybatis-config.xml
- 创建 mybatis-config.xml
1<?xml version="1.0" encoding="UTF-8" ?>
2<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
3<configuration>
4
5 <settings>
6 <!--控制台输出日志-->
7 <setting name="logImpl" value="STDOUT_LOGGING"/>
8 </settings>
9
10</configuration>
- 配置文件配置 自定义 SQL 的包扫描
1mybatis-plus.type-aliases-package= net.xdclass.shop.model
- XML 改为
1<!--旧-->
2<select id="list" resultType="net.xdclass.shop.model.BannerDO">
3 select * from banner
4</select>
5
6<!--新-->
7<select id="list" resultType="BannerDO">
8 select * from banner
9</select>
- MyBatis plus 下划线转驼峰配置,默认就是 true
1mybatis-plus.configuration.map-underscore-to-camel-case=true
- 配置全局默认主键类型,实体类就不用加 @TableId(value = "id", type = IdType.AUTO)
1mybatis-plus.global-config.db-config.id-type=auto
性能优化之指定 select 字段查询
面试题:select * 和 select 指定字段的区别
- 网络 IO 问题
1select * 会查出所有的字段,有些是不需要的,当应用程序和服务器不在同一个局域网时,字段过多会影响网络传输的性能
- 索引问题
1在 指定字段有索引的情况下,mysql是可以不用读data,直接使用index里面的值就返回结果的。
2但是一旦用了select *,就会有其他列需要从磁盘中读取才会返回结果,这样就造成了额外的性能开销
- MybatisPlus 指定查询字段
1bannerMapper.selectList(new QueryWrapper<BannerDO>().select("id","name"));
ActiveRecord
- 什么是 ActiveRecord(只做简单了解即可)
1Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
- MyBatis Plus 对 AR 有一定支持, 在 MP 中开启 AR,仅需要实体类继承 Model 类即可
1@Data
2//表名映射,用于新增才需要
3@TableName("banner")
4public class BannerDO extends Model<BannerDO> {
5
6 @TableId(value = "id", type = IdType.AUTO)
7 private Integer id;
8
9 private String img;
10
11 private String url;
12
13 private Integer weight;
14}
- 使用
1BannerDO bannerDO = new BannerDO();
2BannerDO b = bannerDO.selectOne(new QueryWrapper<BannerDO>().eq("id","1"));
3System.out.println(b);
使用建议
- 业务逻辑比较简单,当类基本上和数据库中的表一一对应时, ActiveRecord 是非常方便的, 即业务逻辑大多数是对单表操作,简单,直观 一个类就包括了数据访问和业务逻辑.
- ActiveRecord 虽然有业务逻辑, 但基本上都是基于单表的. 跨表逻辑一般会放到当发生跨表的操作时, 往往会配合使用事务脚本(Transaction Script)中.
- 如果对象间的关联越来越多, 你的事务脚本越来越庞大, 重复的代码越来越多, 就不建议使用了
- 模型容易混乱,ActiveRecord 保存了数据, 使它有时候看上去像数据传输对象(DTO). 但是 ActiveRecord 有数据库访问能力, 所以所以分布式或者大型项目基本不用
- POJO: model/domain/dto/vo/bo/do
数据库高并发乐观锁
- 什么是乐观锁
1每次去拿数据的时候都认为别人不会修改,更新的时候会判断是别人是否回去更新数据,通过版本来判断,如果数据被修改了就拒绝更新
2
3Java里面大量使用CAS, CAS这个是属于乐观锁,性能较悲观锁有很大的提高
4AtomicXXX 等原子类底层就是CAS实现,一定程度比synchonized好,因为后者是悲观锁
5
6小结:悲观锁适合写操作多的场景,乐观锁适合读操作多的场景,乐观锁的吞吐量会比悲观锁多
- 数据库的乐观锁
1大多是基于数据版本 (Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通
2
3过为数据库表增加一个 “version” 字段来 实现。 读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据,库表对应记录的当前版本信息进行比对,如果提交的数据 版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据
MybatisPlus 乐观锁插件使用
- MyBatis Plus 里面自带一个插件,可以帮我们轻松实现乐观锁
- 使用:实体类增加 version 属性配置
1@Version
2private Integer version;
- 数据库增加 version 版本字段
1CREATE TABLE `banner` (
2 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
3 `img` varchar(524) DEFAULT NULL COMMENT '图片',
4 `url` varchar(524) DEFAULT NULL COMMENT '跳转地址',
5 `weight` int(11) DEFAULT NULL COMMENT '权重',
6 `version` int(11) DEFAULT '1' COMMENT '乐观锁版本号',
7 `deleted` int(11) DEFAULT '0' COMMENT '0是未删除,1是已经删除',
8 PRIMARY KEY (`id`)
9) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4;
- 增加乐观锁插件
1 @Bean
2 public MybatisPlusInterceptor mybatisPlusInterceptor() {
3 MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
4 //分页插件
5 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
6
7 //乐观锁插件
8 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
9 return interceptor;
10}
- 使用
1//先根据ID找记录,得到 id 和 version
2BannerDO bannerDO = new BannerDO();
3bannerDO.setVersion(1);//旧版本号,即查询出来的版本号
4bannerDO.setId(1);
5bannerDO.setUrl("xdclass.net");
6bannerMapper.updateById(bannerDO);
注意
- 乐观锁数据类型支持 int、integer、long、timestamp
- 仅支持 updateById 和 update 方法
MybatisPlus 逻辑删除配置
- 什么是逻辑删除
1很多互联网公司在数据库设计规范中都加入了逻辑删除的强制规定,运营人员可以分析和审查数据,也方便将数据沉淀下来用于商业分析
2
3比如用户删除了订单,只不过是更新了标记,不会真正的物理删除。
- 数据量过多,也会采用数据仓库,通过监听应用数据库的数据数据变化,进行迁移到数据仓库
- MybatisPlus 如何使用
- 数据库增加 deleted 字段,0 是未删除,1 表示删除
- 实体类增加属性配置 @TableLogic 或者 在配置文件增加指定
1@TableLogic
2private Integer deleted;
- 配置文件新增配置
1#删除是1
2mybatis-plus.global-config.db-config.logic-delete-value=1
3#未删除是0
4mybatis-plus.global-config.db-config.logic-not-delete-value=0
5
6#如果java实体类没加注解@TableLogic,则可以配置这个,推荐这里配置
7mybatis-plus.global-config.db-config.logic-delete-field=deleted
验证
- deleteById 删除后就是,结果就是更新 字段 delete = 1
- 查询的时候会自动拼接上 deleted=0 的检索条件
Mybatis-plus-generator 代码自动生成工具
- Mybatis-plus-generator 介绍
- AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
- 底层是模板引擎技术,可以自定义生成的 Java 类模板
- 大家以前或多或少用过基础版 mybatis-genarator
- 进阶版 mybatis-plus-genarator 实战
- 添加依赖
1 <!-- 代码自动生成依赖 begin -->
2 <dependency>
3 <groupId>com.baomidou</groupId>
4 <artifactId>mybatis-plus-generator</artifactId>
5 <version>3.4.1</version>
6 </dependency>
7 <!-- velocity -->
8 <dependency>
9 <groupId>org.apache.velocity</groupId>
10 <artifactId>velocity-engine-core</artifactId>
11 <version>2.0</version>
12 </dependency>
13 <!-- 代码自动生成依赖 end-->
- 代码(标记 TODO 的记得修改)
1package net.xdclass.shopmanager;
2
3import com.baomidou.mybatisplus.annotation.DbType;
4import com.baomidou.mybatisplus.annotation.IdType;
5import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
6import com.baomidou.mybatisplus.generator.AutoGenerator;
7import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
8import com.baomidou.mybatisplus.generator.config.GlobalConfig;
9import com.baomidou.mybatisplus.generator.config.PackageConfig;
10import com.baomidou.mybatisplus.generator.config.StrategyConfig;
11import com.baomidou.mybatisplus.generator.config.rules.DateType;
12import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
13import org.apache.commons.lang3.StringUtils;
14
15import java.util.Scanner;
16
17/**
18 * 小滴课堂,愿景:让技术不再难学
19 *
20 * @Description
21 * @Author 二当家小D
22 * @Remark 有问题直接联系我,源码-笔记-技术交流群
23 * @Version 1.0
24 **/
25
26public class MyBatisPlusGenerator {
27
28 public static void main(String[] args) {
29 //1. 全局配置
30 GlobalConfig config = new GlobalConfig();
31 // 是否支持AR模式
32 config.setActiveRecord(true)
33 // 作者
34 .setAuthor("二当家小D")
35 // 生成路径,最好使用绝对路径,window路径是不一样的
36 //TODO TODO TODO TODO
37 .setOutputDir("E:\\demo\\src\\main\\java")
38 // 文件覆盖
39 .setFileOverride(true)
40 // 主键策略
41 .setIdType(IdType.AUTO)
42
43 .setDateType(DateType.ONLY_DATE)
44 // 设置生成的service接口的名字的首字母是否为I,默认Service是以I开头的
45 .setServiceName("%sService")
46
47 //实体类结尾名称
48 .setEntityName("%sDO")
49
50 //生成基本的resultMap
51 .setBaseResultMap(true)
52
53 //不使用AR模式
54 .setActiveRecord(false)
55
56 //生成基本的SQL片段
57 .setBaseColumnList(true);
58
59 //2. 数据源配置
60 DataSourceConfig dsConfig = new DataSourceConfig();
61 // 设置数据库类型
62 dsConfig.setDbType(DbType.MYSQL)
63 .setDriverName("com.mysql.cj.jdbc.Driver")
64 //TODO TODO TODO TODO
65 .setUrl("jdbc:mysql://192.168.31.101:50000/xd_shop?useSSL=false")
66 .setUsername("root")
67 .setPassword("123456");
68
69 //3. 策略配置globalConfiguration中
70 StrategyConfig stConfig = new StrategyConfig();
71
72 //全局大写命名
73 stConfig.setCapitalMode(true)
74 // 数据库表映射到实体的命名策略
75 .setNaming(NamingStrategy.underline_to_camel)
76
77 //使用lombok
78 .setEntityLombokModel(true)
79
80 //使用restcontroller注解
81 .setRestControllerStyle(true)
82
83 // 生成的表, 支持多表一起生成,以数组形式填写
84 //TODO TODO TODO TODO 两个方式,直接写,或者使用命令行输入
85 .setInclude("product","banner","address","coupon","product_order");
86 //.setInclude(scanner("表名,多个英文逗号分割").split(","));
87
88 //4. 包名策略配置
89 PackageConfig pkConfig = new PackageConfig();
90 pkConfig.setParent("net.xdclass.shopmanager")
91 .setMapper("mapper")
92 .setService("service")
93 .setController("controller")
94 .setEntity("model")
95 .setXml("mapper");
96
97 //5. 整合配置
98 AutoGenerator ag = new AutoGenerator();
99 ag.setGlobalConfig(config)
100 .setDataSource(dsConfig)
101 .setStrategy(stConfig)
102 .setPackageInfo(pkConfig);
103
104 //6. 执行操作
105 ag.execute();
106 System.out.println("======= 小滴课堂 Done 相关代码生成完毕 ========");
107 }
108
109 /**
110 * <p>
111 * 读取控制台内容
112 * </p>
113 */
114 public static String scanner(String tip) {
115 Scanner scanner = new Scanner(System.in);
116 StringBuilder help = new StringBuilder();
117 help.append("请输入" + tip + ":");
118 System.out.println(help.toString());
119 if (scanner.hasNext()) {
120 String ipt = scanner.next();
121 if (StringUtils.isNotBlank(ipt)) {
122 return ipt;
123 }
124 }
125 throw new MybatisPlusException("请输入正确的" + tip + "!");
126 }
127}
128
自动化生成代码-加入项目
- 对比生成的代码进行配置
- 数据库连接和库名称
- 需要生成的表
- 生成的路径
- 拷贝自动生成的代码进入到项目
- model 类拷贝
- mapper 类拷贝
- mapper XML 脚本拷贝
- service 和 controller 不拷贝
- 注意
- 使用起来和普通版的 MyBatis generator 一样,但是这个纯代码,不用复杂 XML 配置
- 任何框架,不要使用过多的侵入或者框架定制化深的内容,防止后续改动耦合性高,成本大
总结
- 优点
1无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
2
3损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
4
5强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
6
7内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
8
9内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
10
11内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 缺点
1项目映入了第三方包,未来升级存在一定的兼容性问题
2
3社区相对新生-文档缺乏相关的信息, 或者更新不及时
项目使用建议
- 任何框架或技术肯定有利也有弊,看的角度和结合团队实际情况
- 高内聚-低解耦肯定是软件设计思想必须要遵守的原则,所以业务代码可以适当使用 MyBatisPlus 好的功能
- 好用的:通用 crud、自动生成工具、分页查询
- 有点耦合但也不错的功能:逻辑删除、乐观锁等
- AR 则不怎么建议使用
- 偏业务型项目、管理后端项目等推荐使用,和 jpa 类似