Mybatis-Plus使用和SpringBoot集成

1. Mybatis-Plus概述

1.1 什么是Mybatis-Plus?

      Mybatis-Plus(MP)是Mybatis的增强,在Mybatis的基础上不做改变只做增强,为简化开发、提高效率而生,尽可能的在开发过程中减少SQL语句的编写。
      MyBatis-Plus 官方文档:https://mp.baomidou.com/
      GitHub地址:https://github.com/baomidou/mybatis-plus
      Gitee项目地址:https://gitee.com/baomidou/mybatis-plus
      MyBatis-Plus开发组织:https://gitee.com/baomidou
      

1.2 Mybatis-Plus和Mybatis有什么区别?

Mybatis优点:

  • SQL语句*控制,较为灵活
  • SQL与业务代码分离,易于阅读与维护
  • 提供动态SQL语句,可以根据需求灵活控制

Mybatis缺点:

  • 简单的crud操作也必须提供对应SQL语句
  • 必须维护大量的xml文件
  • 自身功能有限,要拓展只能依赖第三方插件

Mybatis-Plus是在Mybatis的基础上进行加强,具有Mybatis的所有功能并拓展了独有的功能

Mybatis-Plus特点:

  • 提供无SQL 的CRUD操作
  • 内置代码生成器,分页插件, 性能分析插件等
  • 提供功能丰富的条件构造器快速进行无SQL开发

1.3 Mybatis-Plus入门体验(集成SpringBoot)

 
                         本次数据库使用MySQL,开发工具为IDEA
 
1、 创建一张新表,导入初始数据

#建表语句
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `email` varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
)

#导入初始数据
INSERT INTO `employee` VALUES (1, 'dayi', 'gfase345', 'dayi@1.com', 24);
INSERT INTO `employee` VALUES (2, 'geer', 'gs352', 'geer@2.com', 23);
INSERT INTO `employee` VALUES (3, 'zhangsan', 'ffafg4235', 'zhangsan@3.com', 21);
INSERT INTO `employee` VALUES (4, 'lisi', '5423fda', 'lisi@4.com', 24);
INSERT INTO `employee` VALUES (5, 'wangwu', 'dfaf543', 'wangwu@5.com', 24);
INSERT INTO `employee` VALUES (6, 'maliu', 'gag342', 'maliu@6.com', 32);

 
2、创建一个空的 Spring Boot 工程

                                                                                     可以选择Spring官方网页创建或者IDEA创建
 
 
3、导入本次项目的依赖

	<!--Springboot父依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
        <relativePath/>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

 
4、在yml文件中添加数据库配置项

#mysql
spring :
  datasource:
    url: jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    username: root
    password: admin
    driver-class-name: com.mysql.cj.jdbc.Driver

 
5、创建实体类

@Setter
@Getter
@ToString
public class Employee {
	@TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private String password;
    private String email;
    private Integer age;
}

 
6、创建Mapper接口

继承BaseMapper接口,有一个泛型,填上对应需要操作的实体类

public interface EmployeeMapper extends BaseMapper<Employee> {
}

 
7、启动类中添加MapperScan注解扫描mapper包

需要保证Mapper接口能够被扫描到,这里采用了动态代理的方式对扫描到的Mapper接口进行代理,向spring容器中注入代理对象

@SpringBootApplication
@MapperScan(basePackages = "com.liuyipeng.mp.mapper")
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

}

 
8、添加测试类,进行功能测试
                                                         这里的selectList()方法的参数为MP内置的条件封装器Wrapper,所以不填写就是无条件

@SpringBootTest
public class EmployeeMapperTest {
    @Autowired
    private EmployeeMapper employeeMapper;

    @Test
    public void test(){
        List<Employee> employees = employeeMapper.selectList(null);
        employees.forEach(System.out::println);
    }
}

控制台输出 :

Employee(id=1, name=dayi, password=gfase345, email=dayi@1.com, age=24)
Employee(id=2, name=geer, password=gs352, email=geer@2.com, age=23)
Employee(id=3, name=zhangsan, password=ffafg4235, email=zhangsan@3.com, age=21)
Employee(id=4, name=lisi, password=5423fda, email=lisi@4.com, age=24)
Employee(id=5, name=wangwu, password=dfaf543, email=wangwu@5.com, age=24)
Employee(id=6, name=maliu, password=gag342, email=maliu@6.com, age=32)

 
9、小结
通过上面8个步骤,我们就实现了Employee表的简单全表查询,不需要创建XML文件和编写SQL语句
也体验到了在Spring Boot工程下集成Mybatis Plus是多么的方便 ,只需要引入starter依赖,并配置Mapper扫描路径即可
 
 

2. 基本注解使用

注解文档 : https://baomidou.com/guide/annotation.html#tablename

@TableName
      描       述 :表名注解
      用       法 :贴在表对应实体类上
      作       用 :通过value属性指定映射的表
      其它属性 :略

@Tableld
      描       述 :主键注解
      用       法 :贴在主键对应的字段上
      作       用 :通过value属性表示映射的主键列
      其它属性 :略

@TableField
      描       述 :字段注解(非主键)
      用       法 :贴在字段上
      作       用 :通过value属性表示当前映射表中哪一列,不贴默认属性名和列名一致
      其它属性 :exist (false代表表中没有此列)

@Version
      描       述 :乐观锁注解
      用       法 :贴在字段上
      作       用 :用于标记乐观锁操作字段
      其它属性 :略

其它注解请自行查阅官方文档!
 
 

3. 通用Mapper接口(BaseMapper<T>)

解释 :
        1、通用 CRUD 封装BaseMapper接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
        2、泛型 T 为任意实体对象
        3、参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id主键
        4、对象 Wrapper 为条件构造器

 

Insert

源码:

/**
* 插入一条记录
*
* @param entity 实体对象
*/
int insert(T entity);

向数据库中添加一条数据:

@Test
public void testInsert(){
    Employee employee  = new Employee();
    employee.setName("xiaoliu");
    employee.setAge(18);
    employee.setEmail("xiaoliu@q.com");
    employee.setPassword("xiaoliu999");
    employeeMapper.insert(employee);
}

只需封装好对应对象,调用通用Mapper接口中的方法即可快速的向数据库中添加一条数据

 

Update

1、根据 Id 更新

源码:

/**
* 根据 ID 修改
*
* @param entity 实体对象
*/
int updateById(@Param(Constants.ENTITY) T entity);

根据Id进行更新:

@Test
public void testUpdateById(){
   Employee employee = employeeMapper.selectById(1L);
   employee.setName("daliu");
   employeeMapper.updateById(employee);
}

注意 : 如果我们实体类中某些字段使用的是基本数据类型,在创建对象时会有默认的值,导致在执行sql语句时,非null的的字段也进行了set拼接,就会导致表中有些数据为0的情况,这里步骤为先查询,再设置,再修改

2、根据条件构造器更新

源码:

/**
* 根据 whereEntity 条件,更新记录
*
* @param entity        实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

根据条件构造器更新:

@Test
public void testUpdate() {
    UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
    wrapper.set("age",18);
    wrapper.eq("name","xiaoliu");
    employeeMapper.update(null,wrapper);
}

SQL:UPDATE employee SET age = ? WHERE (name = ?)

使用方式建议
1、知道Id,并且所有更新用updateById
2、部分字段更新,用update ,通过wrapper构建条件

updateById : 全量更新, 只要传入对象属性不为null, 都可以进行update更新, 条件是通过id匹配
正确操作姿势: 前提: 必须知道id
1> 查
3> 更新
 
update+wrapper:部分字段更新, 通过wrapper对象拼接各种满足要求条件 , 更新set的列由wrapper 决定
正确操作姿势:
1> 设置更新条件
2> 拼接更新列

 

Delete

1、根据 ID 删除单条记录

源码:

/**
* 根据 ID 删除
*
* @param id 主键ID
*/
int deleteById(Serializable id);

根据 ID 删除:

@Test
public void testDeleteById() {
  	employeeMapper.deleteById(1L);
}

SQL : DELETE FROM employee WHERE id=?

2、根据 ID 批量删除

源码:

/**
* 删除(根据ID 批量删除)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

根据 ID 批量删除:

@Test
public void testDeleteBatchIds() {
  	employeeMapper.deleteBatchIds(Arrays.asList("2","3"));
}

SQL : DELETE FROM employee WHERE id IN ( ? , ? )

3、根据 Map 删除

源码:

/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

根据 Map 删除:

@Test
public void testDeleteByMap() {
    Map<String, Object> map = new HashMap<>();
    map.put("name","xaioliu");
    map.put("age",18);
    employeeMapper.deleteByMap(map);
}

SQL : DELETE FROM employee WHERE name = ? AND age = ?

4、根据 Wrapper 条件构造器删除

源码:

/**
* 根据 entity 条件,删除记录
*
* @param wrapper 实体对象封装操作类(可以为 null)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

根据 Wrapper 删除:

@Test
public void testDelete() {
    UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
    wrapper.eq("name","wangwu").eq("age",18);
    employeeMapper.delete(wrapper);
}

SQL : DELETE FROM employee WHERE (name = ? AND age = ?)

 

Select

1、根据 ID 查询

源码:

/**
 * 根据 ID 查询
 *
 * @param id 主键ID
 */
T selectById(Serializable id);

根据 ID 查询:

@Test
public void testSelectById() {
	 Employee employee = employeeMapper.selectById(5L);
 	 System.out.println(employee);
}
2、根据 ID 批量查询
上一篇:Mybatis-plus报Invalid bound statement (not found)错误


下一篇:kuangbin动态规划