前言:
Mybatis在持久层框架中还是比较流行的,现在一般项目都是基于SSM或者SpringBoot+Mybatis。虽然Mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但如果都要通过SQL语句进行,就必须写大量的xml文件。比如一般的单表操作,CRUD等简单操作,这些如果每一个都写一段SQL语句,就显得非常麻烦和不必要。Mybatis-plus就很好的解决了这个问题。
一、Mybatis-plus简介:
Mybatis-Plus 是一个 Mybatis框架的增强工具,在 Mybatis 的基础上只做增强不做改变,为了简化开发,提高效率而生。那么它是怎么增强的呢?其实就是它已经封装好了一些CRUD方法,我们不需要再写xml了,也不需要写SQL语句了,直接调用这些固定的方法就行,就类似于SpringDataJPA框架的ORM对象关系映射。
二、Spring整合Mybatis-plus:
正如官方所说,Mybatis-plus在Mybatis的基础上只做增强不做改变,因此其与Spring的整合和Mybatis与Spring基本一样非常简单。只需把Mybatis的依赖换成Mybatis-plus的依赖,再把sqlSessionFactory换成Mybatis-plus的即可。接下来看具体步骤:
1、pom.xml:
核心依赖如下:
<!-- spring 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- mybatis-plus 依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.3</version>
</dependency>
注意:这些是核心依赖,还有其他如Mysql驱动、Druid连接池、日志log4j、Lombok等项目依赖。集成Mybatis-plus要把Mybatis和Mybatis-spring依赖去掉,避免冲突。Lombok是一个工具,添加了这个依赖,开发工具再安装Lombok插件,就可以使用它了,最常用的用法就是在实体类中使用它的@Data注解,这样实体类就不用写set、get、toString等方法了。
2、jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://数据库名?useUnicode=true&characterEncoding=utf-8
jdbc.username=xxx
jdbc.password=xxx
3、mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
</configuration>
同时还需要在sqlSessionFactory中配置
< property name=“configLocation” value=“classpath:mybatis-configuration.xml”/>
这个配置之后就可以在控制台输出执行的SQL语句了
4、spring-application.xml:
因为是与spring整合,所有mybatis-plus的大部分都写在spring的配置文件中。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd">
<context:component-scan base-package="com.project.crm">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--配置数据库相关参数properties的属性:${url} -->
<context:property-placeholder location="classpath:properties/jdbc.properties"/>
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
<!-- 配置mybatis-plus的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 控制台输出sql语句 -->
<property name="configLocation" value="classpath:mybatis-configuration.xml"/>
<property name="typeAliasesPackage" value="com.project.crm.model"/>
<!-- 配置插件 -->
<property name="plugins">
<list>
<!-- 分页插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"/>
<!-- 输出每条SQL语句及其执行时间,生产环境不建议使用该插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="format" value="true"/><!-- 格式化SQL语句 -->
<property name="maxTime" value="1000"/><!-- sql执行时间超过value值就会停止执行,单位是毫秒 -->
</bean>
<!-- 如果是对全表的删除或更新操作,就会终止该操作 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true"/>
</bean>
</list>
</property>
<!-- 注入全局配置 -->
<!-- <property name="globalConfig" ref="globalConfiguration"/>-->
<!-- 导入.xml文件路径 -->
<!-- <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>-->
</bean>
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.project.crm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!-- mybatisplus的全局策略配置 -->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 2.3版本后,驼峰命名默认值就是true,所以可不配置 -->
<!--<property name="dbColumnUnderline" value="true"/>-->
<!-- 全局主键自增策略,0表示auto -->
<!-- <property name="idType" value="0"/>-->
<!-- 全局表前缀配置 -->
<!-- <property name="tablePrefix" value="tb_"/>-->
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<!-- 配置Spring的声明式事务管理 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置支持注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
</beans>
5、Entity:
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@TableName(value = "ts_user")
public class User implements Serializable {
//value与数据库主键列名一致,若实体类属性名与表主键列名一致可省略value
@TableId(value = "id",type = IdType.AUTO)//指定自增策略
private long id;
//若没有开启驼峰命名,或者表中列名不符合驼峰规则,可通过该注解指定数据库表中的列名,exist标明数据表中有没有对应列
@TableField(value = "user_name",exist = true)
private String userName;
private String gender;
private String phone;
}
这个和SpringDataJpa很相似,ORM关系映射。
6、Mapper:
public interface UserMapper extends BaseMapper<TsManageUser> {
}
继承BaseMapper,如果只是简单的CRUD,那么根本就不需要写XML文件,也不用编写SQL语句了。
7、Service:
public interface TsUserDepartService extends IService<TsUserDepart> {
}
继承IService,调用Mapper中的方法。
8、测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private DataSource dataSource;
@Test
public void testDataSource() throws SQLException {
System.out.println(dataSource.getConnection());
}
}
运行该测试方法,如果控制台输出获取到的连接,就说明整合成功:
com.mysql.jdbc.JDBC4Connection@289710d9
三、Mybatis-plus通用的CRUD:
需求:
存在一张 ts_user 表,且已有对应的实体类 User,实现ts_user 表的 CRUD 操作。
Mybatis:
需要编写 UserMapper 接口,并在UserMapper.xml 映射文件中手动编写 CRUD 方法对应的sql语句。
Mybatis-plus:
只需要创建 UserMapper 接口, 并继承 BaseMapper 接口,调用通用的CRUD方法即可。
1、insert操作
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void add(){
User user = new User();
user.setUserName("mybatis-plus");
user.setGender("男");
user.setAge(18);
user.setPhone("15000000000");
userMapper.insert(user);
//Mybatisplus会自动把当前插入对象在数据库中的id写回到该实体中
System.out.println("userId = "+user.getId());
}
}
控制台输出结果:
==> Preparing: INSERT INTO ts_user ( user_name, gender, age, phone ) VALUES ( ?, ?, ?, ? )
==> Parameters: mybatis-plus(String), 男(String), 18(Integer), 15000000000(String)
<== Updates: 1
userId = 9
2、update操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void update(){
//updateById方法,没有传值的字段不会进行更新
//updateAllColumnById方法,会更新所有的列,没有传值的列会更新为null。
User user = new User();
user.setId(4);
user.setUserName("mybatis-plus");
user.setAge(20);
user.setPhone("1511111111");
userMapper.updateById(user);
}
}
控制台输出结果:
==> Preparing: UPDATE ts_user SET user_name=?, age=?, phone=? WHERE id=?
==> Parameters: mybatis-plus(String), 20(Integer), 1511111111(String), 4(Long)
<== Updates: 1
3、select操作:
根据id查询:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void selectById(){
User user = userMapper.selectById(4);
System.out.println("user = " + user);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(4);
List<User> userList = userMapper.selectBatchIds(ids);
System.out.println("userList = " + userList);
}
}
控制台输出结果:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE id=?
==> Parameters: 4(Integer)
<== Columns: id, userName, gender, age, phone
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Total: 1
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE id IN ( ? , ? )
==> Parameters: 1(Integer), 4(Integer)
<== Columns: id, userName, gender, age, phone
<== Row: 1, 管理员, 男, 18, 13812818138
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Total: 2
根据条件查询:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void selectByMap(){
User user = new User();
//根据条件查询一条数据,若是数据库中符合条件的记录有多条,就会报错
user.setId(4);
user.setAge(20);
User backUser = userMapper.selectOne(user);
System.out.println("backUser = " + backUser);
//根据查询条件返回多条数据
Map<String,Object> map = new HashMap<>();
map.put("gender","女");
List<User> userList = userMapper.selectByMap(map);
System.out.println("userList = " + userList);
}
}
控制台输出:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE id=? AND age=?
==> Parameters: 4(Long), 20(Integer)
<== Columns: id, userName, gender, age, phone
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Total: 1
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE gender = ?
==> Parameters: 女(String)
<== Columns: id, userName, gender, age, phone
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Row: 5, mybatis-plus, 女, 18, 15000000000
<== Total: 2
分页查询:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void selectPage(){
/*
在page中传入分页信息,后者为null的是分页条件。
这个分页不是物理分页,而是内存分页,查询的时候并没有limit语句,配置了分页插件后才可以实现真正的limit分页。
*/
//查询前2条数据
List<User> userList = userMapper.selectPage(new Page<>(1, 2), null);
System.out.println("userList = " + userList);
}
}
控制台输出:
未配置分页插件:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user
==> Parameters:
<== Columns: id, userName, gender, age, phone
<== Row: 1, 管理员, 男, 18, 13812818138
<== Row: 4, mybatis-plus, 女, 20, 1511111111
配置了分页插件:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user LIMIT 0,2
==> Parameters:
<== Columns: id, userName, gender, age, phone
<== Row: 1, 管理员, 男, 18, 13812818138
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Total: 2
4、delete操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void delete(){
//根据id删除
userMapper.deleteById(6);
//根据id批量删除
List<Integer> ids = new ArrayList<>();
ids.add(7);
ids.add(8);
userMapper.deleteBatchIds(ids);
//根据条件删除
Map<String,Object> map = new HashMap<>();
map.put("gender","女");
userMapper.deleteByMap(map);
}
}
四、全局策略配置:
实体类需要加@TableName注解指定数据库表名,通过@TableId注解指定id的增长策略。实体类少倒也无所谓,实体类一多的话也麻烦。所以可以在spring-common.xml的文件中进行全局策略配置。
<!-- mybatisplus的全局策略配置 -->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 2.3版本后,驼峰命名默认值就是true,所以可不配置 -->
<property name="dbColumnUnderline" value="true"/>
<!-- 全局主键自增策略,0表示auto -->
<property name="idType" value="0"/>
<!-- 全局表前缀配置 -->
<property name="tablePrefix" value="ts_"/>
</bean>
还需要在sqlSessionFactory中注入配置:
<!--配置mybatis-plus的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 控制台输出sql语句 -->
<property name="configLocation" value="classpath:mybatis-configuration.xml"/>
<property name="typeAliasesPackage" value="com.project.crm.model"/>
<!-- 配置插件 -->
<property name="plugins">
<list>
<!-- 分页插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"/>
<!-- 输出每条SQL语句及其执行时间,生产环境不建议使用该插件 -->
<!-- <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">-->
<!-- <property name="format" value="true"/><!– 格式化SQL语句 –>-->
<!-- <property name="maxTime" value="1000"/><!– sql执行时间超过value值就会停止执行,单位是毫秒 –>-->
<!-- </bean>-->
<!-- 如果是对全表的删除或更新操作,就会终止该操作 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true"/>
</bean>
</list>
</property>
<!-- 注入全局配置 -->
<property name="globalConfig" ref="globalConfiguration"/>
<!-- 导入.xml文件路径 -->
<!-- <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>-->
</bean>
配置完成之后,实体类中的@TableName注解和@TableId注解就可以不用添加了。
五、条件构造器(EntityWrapper):
以上基本的 CRUD 操作,我们仅仅需要继承一个 BaseMapper 即可实现大部分单表 CRUD 操作。BaseMapper 提供了多达 17 个方法供使用, 可以极其方便的实现单一、批量、分页等操作,极大的减少开发负担。
但是在开发中,肯定不会只用这些简单地CRUD。
需求:
我们需要条件查询某些数据,并对这些数据进行分页操作。
MyBatis : 需要在 SQL 映射文件中编写带条件查询的 SQL,并用PageHelper 插件完成分页,实现以上一个简单的需求,但是往往需要我们做很多重复单调的工作。
Mybatis-plus: 依旧不用编写 SQL 语句,MP 提供了功能强大的条件构造器 ------ EntityWrapper。
1、分页查询年龄在0-20且gender为男的用户:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void select1(){
List<User> userList = userMapper.selectPage(new Page<>(1, 3),
new EntityWrapper<User>()
.between("age", 0, 20)
.eq("gender", "男"));
System.out.println("userList = " + userList);
}
}
控制台输出:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE (age BETWEEN ? AND ? AND gender = ?) LIMIT 0,3
==> Parameters: 0(Integer), 20(Integer), 男(String)
<== Columns: id, userName, gender, age, phone
<== Row: 1, 管理员, 男, 18, 13812818138
<== Row: 6, mybatis-plus, 男, 18, 15000000000
<== Row: 7, mybatis-plus, 男, 18, 15000000000
<== Total: 3
分页查询和之前一样,new 一个page对象传入分页信息即可。至于分页条件,new 一个EntityWrapper对象,调用该对象的相关方法即可。between方法三个参数,分别是column、value1、value2,该方法表示column的值要在value1和value2之间;eq是equals的简写,该方法两个参数,column和value,表示column的值和value要相等。注意column是数据表对应的字段,而非实体类属性字段。
2丶查询性别为男 并且名字like “mybatis” 或者电话like “150”
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void select2(){
List<User> userList = userMapper.selectList(new EntityWrapper<User>()
.eq("gender", "男")
.like("user_name", "mybatis")
//.or()//和or new 区别不大
.orNew()
.like("phone", "150"));
System.out.println("userList = " + userList);
}
}
控制台输出:
使用or()方法:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE (gender = ? AND user_name LIKE ? OR phone LIKE ?)
==> Parameters: 男(String), %mybatis%(String), %150%(String)
<== Columns: id, userName, gender, age, phone
<== Row: 5, mybatis-plus, 女, 18, 15000000000
<== Row: 6, mybatis-plus, 男, 18, 15000000000
<== Total: 2
使用orNew()方法:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE (gender = ? AND user_name LIKE ?) OR (phone LIKE ?)
==> Parameters: 男(String), %mybatis%(String), %150%(String)
<== Columns: id, userName, gender, age, phone
<== Row: 5, mybatis-plus, 女, 18, 15000000000
<== Row: 6, mybatis-plus, 男, 18, 15000000000
<== Total: 2
不进行分页查询,所以用selectList方法,用EntityWrapper的like方法进行模糊条件查询,like方法就是指column的值包含value值。
3丶查询性别为女 通过id排序 并分页
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void select3(){
List<User> userList = userMapper.selectList(new EntityWrapper<User>()
.eq("gender", "女")
//直接orderby 是升序,asc
.orderBy("id")
//在sql语句后面追加last里面的内容(改为降序,同时分页))
.last("desc limit 0,2"));
}
}
控制台输出:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE (gender = ?) ORDER BY id desc limit 0,2
==> Parameters: 女(String)
<== Columns: id, userName, gender, age, phone
<== Row: 5, mybatis-plus, 女, 18, 15000000000
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Total: 2
简单分页是指不用page对象进行分页。orderBy方法就是根据传入的column进行升序排序,若要降序,可以使用orderByDesc方法,也可以用last方法在后面添加上desc;last方法就是将last方法里面的value值追加到sql语句的后面,如添加上分页参数limit 0,2。
4、分页查询年龄在0-20且gender为女的用户:
条件构造器除了EntityWrapper,还有Condition。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void select4(){
List<User> userList = userMapper.selectPage(new Page<User>(1, 2),
Condition.create()
.between("age", 0, 20)
.eq("gender", "女"));
System.out.println("userList = " + userList);
}
}
控制台输出:
==> Preparing: SELECT id AS id,user_name AS userName,gender,age,phone FROM ts_user WHERE (age BETWEEN ? AND ? AND gender = ?) LIMIT 0,2
==> Parameters: 0(Integer), 20(Integer), 女(String)
<== Columns: id, userName, gender, age, phone
<== Row: 4, mybatis-plus, 女, 20, 1511111111
<== Row: 5, mybatis-plus, 女, 18, 15000000000
<== Total: 2
Condition和EntityWrapper的区别就是,创建条件构造器时,EntityWrapper是new出来的,而Condition是调create方法创建出来。
5、条件更新:
把名字为AAA,年龄为18的用户更改为名字BBB,年龄为20。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void update(){
User user = new User();
user.setUserName("BBB");
user.setAge(20);
userMapper.update(user,new EntityWrapper<User>()
.eq("user_name","AAA")
.eq("age",18));
}
}
控制台输出:
==> Preparing: UPDATE ts_user SET user_name=?, age=? WHERE (user_name = ? AND age = ?)
==> Parameters: BBB(String), 20(Integer), AAA(String), 18(Integer)
<== Updates: 1
6、条件删除:
把名字为BBB,年龄为20的用户删除。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-common.xml"})
public class TestTest {
@Autowired
private UserMapper userMapper;
@Test
public void delete(){
userMapper.delete(new EntityWrapper<User>()
.eq("user_name","BBB")
.eq("age","20"));
}
}
控制台输出:
==> Preparing: DELETE FROM ts_user WHERE (user_name = ? AND age = ?)
==> Parameters: BBB(String), 20(String)
<== Updates: 1
以上就是Mybatis-plus的一些简单用法,当然Mybatis-plus的用法远远不止这些,其强大并不限于此。