springboot整合mybatis-plus

        MyBatis-plus简单来说就是一款 Mybatis 增强工具,用于简化开发,提高效率。下文使用缩写 mp来简化表示 MyBatis-plus,致力于 MyBatis 的基础上只做增强不做改变,为简化开发,提高效率而生。mybatis-plus只支持单表操作,联表查询不能使用。

1、mybatis-plus特点:

  1. 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring 。
  2. 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 。
  3. 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击 。
  4. 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 。
  5. 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题 。
  6. 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  7. 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
  8. 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码(生成自定义文件,避免开发重复代码),支持模板引擎、有超多自定义配置等。
  9. 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。
  10. 支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词 。
  11. 内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。
  12. 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库.
  13. 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询 。
  14. 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作。
  15. 默认将实体类的类名查找数据库中的表,使用@TableName(value="table1")注解指定表名,@TableId指定表主键,若字段与表中字段名保持一致可不加注解。

2、使用mybatis-plus

(1)创建数据库和表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `address` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (2, '李四', 21, '郑州');
INSERT INTO `student` VALUES (3, '王五', 19, '深圳');
INSERT INTO `student` VALUES (4, '小黑', 24, '商丘');
INSERT INTO `student` VALUES (5, '小白', 17, '太原');
INSERT INTO `student` VALUES (7, 'dumpling', 23, '郑州');

SET FOREIGN_KEY_CHECKS = 1;

(2)引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--引入mybatis-plus依赖-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

编写配置文件中的数据源配置和加入mybatis-plus的日志文件

# 配置mysql数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.1.29:3306/stu?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=990412

# mybatis-plus的日志文件stdout
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

(3)创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
//如果表名和实体类名不一致,使用该注解
@TableName("student")
public class Student {
    //标记该属性为主键,value标记列名和属性名对应
    @TableId(value = "id")
    private Long id;
    //如果属性名和列名不一致使用该注解
    @TableField(value = "name")
    private String name;
    private Integer age;
    private String address;

    public Student(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

(4)编写dao层

//BaseMapper接口中提供了单表的所有操作。crud.
@Mapper
public interface StudentMapper extends BaseMapper<Student> {

}

(5)测试

@SpringBootTest
class SpringbootMybatisPlusApplicationTests {

    @Autowired
    StudentMapper studentMapper;

    @Test
    void testSelectById(){
        Student student = studentMapper.selectById(2);
        System.out.println(student);
    }
}

3、mybatis-plus添加

mybatis-plus框架为主键提供了相应的生成策略:

AUTO(0):递增策略,如果使用该策略必须要求数据表的列也是递增。

NONE(1)和INPUT(2):没有策略,必须人为的输入id值。

ASSIGN_ID(3),:随机生成一个Long类型的值。该值一定是唯一。而且每次生成都不会相同。使用雪花算法,适合分布式主键。要求数据库中该列的类型为bigint,实体类中的数据类型为long类型.

@SpringBootTest
class SpringbootMybatisPlusApplicationTests {

    @Autowired
    StudentMapper studentMapper;

    @Test
    void testInsert(){
        Student student = new Student("dumplings",21,"太宁宫");
        int insert = studentMapper.insert(student);
        System.out.println(insert);
    }
}



@Data
@AllArgsConstructor
@NoArgsConstructor
//如果表名和实体类名不一致,使用该注解
@TableName("student")
public class Student {
    //标记该属性为主键,value标记列名和属性名对应
    /*AUTO(0),递增策略,如果使用该策略必须要求数据表的列也是递增。
      NONE(1),
      INPUT(2),没有策略,必须人为的输入id值
      ASSIGN_ID(3), 随机生成一个Long类型的值。该值一定是唯一。而且每次生成都不会相同。算法:雪花算法。 适合分布式主键。
      要求数据库中该列的类型为bigint,实体类中的数据类型为long类型
      ASSIGN_UUID(4); 随机产生一个String类型的值。该值也是唯一的。*/
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    //如果属性名和列名不一致使用该注解
    @TableField(value = "name")
    private String name;
    private Integer age;
    private String address;

    public Student(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

运行结果:

 4、mybatis-plus删除

在实际开发中,我们所谓的删除可能是逻辑删除,所谓的逻辑删除就是修改功能,修改该表中的逻辑字段,这个逻辑删除功能只对自动注入的sql起效:

插入:不限制,

查找:追加where条件过滤已删除数据,且使用wrapper.entity生成的where条件会忽略这个字段;

更新:追加where条件防止更新到已删除数据,且使用wrapper.entity生成的where条件会忽略这个字段;

删除:转变为更新
      (1)增加一个逻辑字段: isdeleted  0表示未删除 1表示删除.
      (2)实体类上的字段添加   @TableLogic注解,标记这个字段为逻辑字段

@SpringBootTest
class SpringbootMybatisPlusApplicationTests {

    @Autowired
    StudentMapper studentMapper;

    /**
     *  实际开发中: 我们的删除可能是逻辑删除。所谓的逻辑删除就是修改功能。把某个列修改以删除的状      态值。
     *  只对自动注入的 sql 起效:
     * 插入: 不作限制---
     * 查找: 追加 where 条件过滤掉已删除数据,且使用 wrapper.entity 生成的 where 条件会忽略该字段
     * 更新: 追加 where 条件防止更新到已删除数据,且使用 wrapper.entity 生成的 where 条件会忽略该字段
     * 删除: 转变为 更新
     * (1)增加一个逻辑字段: isdeleted  0表示未删除 1表示删除.
     * (2)实体类上的字段添加   @TableLogic.
     */
    @Test
    void testDelete(){
        int i = studentMapper.deleteById(1551549433282404353L);
        System.out.println(i);
    }

}


@Data
@AllArgsConstructor
@NoArgsConstructor
//如果表名和实体类名不一致,使用该注解
@TableName("student")
public class Student {
    //标记该属性为主键,value标记列名和属性名对应
    /*AUTO(0),递增策略,如果使用该策略必须要求数据表的列也是递增。
      NONE(1),
      INPUT(2),没有策略,必须人为的输入id值
      ASSIGN_ID(3), 随机生成一个Long类型的值。该值一定是唯一。而且每次生成都不会相同。算法:雪花算法。 适合分布式主键。
      要求数据库中该列的类型为bigint,实体类中的数据类型为long类型
      ASSIGN_UUID(4); 随机产生一个String类型的值。该值也是唯一的。*/
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    //如果属性名和列名不一致使用该注解
    @TableField(value = "name")
    private String name;
    private Integer age;
    private String address;
    //标记该字段为逻辑字段,删除时修改该字段
    @TableLogic
    private Boolean isdeleted;

    public Student(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

运行结果:

 5、mybatis-plus修改

 自动填充功能:
     在阿里规则中我们的每一张表必须具备的三个字段 id,create_time,update_time.
     这两个字段要不要自己添加。
     (1)在需要自动填充属性上@TableField(fill=)
     (2)创建mp自动填充类

@SpringBootTest
class SpringbootMybatisPlusApplicationTests {

    @Autowired
    StudentMapper studentMapper;

    @Test
    void testUpdate(){
        Student student = new Student();
        student.setId(1551549433282404353L);
        student.setName("skin");
        int update = studentMapper.updateById(student);
        System.out.println(update);
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
//如果表名和实体类名不一致,使用该注解
@TableName("student")
public class Student {
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    //如果属性名和列名不一致使用该注解
    @TableField(value = "name")
    private String name;
    private Integer age;
    private String address;

    //标记该字段为逻辑字段,删除时修改该字段
    @TableLogic
    @TableField(fill = FieldFill.INSERT)
    private Boolean isdeleted;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;

    public Student(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}



@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        //添加记录时,自动填充逻辑字段的值为0
        this.strictInsertFill(metaObject,"isDeleted",()->0,Integer.class);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); 
    }
}

执行结果:

6、 mybatis-plus查询

(1)根据主键查询

@SpringBootTest
class SpringbootMybatisPlusApplicationTests {

    @Autowired
    StudentMapper studentMapper;

    @Test
    void testSelectById(){
        Student student = studentMapper.selectById(2L);
        System.out.println(student);
    }

}

执行结果:

(2)根据各种条件查询

Wrapper:封装了关于查询的各种条件方法。有三个子类最常用:

QueryWrapper查询条件 

UpdateWrapper修改条件 

LambdaQueryWrapper查询使用lambda表达式条件

@Test
void testSelectByCondition(){
    QueryWrapper<Student> wrapper = new QueryWrapper<>();
    wrapper.ge("age",18);
    studentMapper.selectList(wrapper);
}

执行结果:

(3)根据条件查询一条记录

@Test
void testSelectOne(){
    //可以用于登录功能,比较用户名和密码两个列
    QueryWrapper<Student> wrapper = new QueryWrapper<>();
    wrapper.eq("name","dumpling");
    wrapper.eq("age",23);
    studentMapper.selectOne(wrapper);
}

执行结果:

(4)分页查询

        mybatis-plus中内置了分页插件,不需要我们在手动添加依赖,不过我们需要添加分页插件的配置文件

@Configuration
public class MybatisPlusConfig {
    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
}

测试分页插件的使用

@Test
void testPage(){
    Page<Student> page = new Page<>(1,2);
    // 两个参数,一个Page(分页对象),一个QueryWrapper(查询条件)
    // selectPage()方法把查询的结果自动封装到Page对象中
    studentMapper.selectPage(page,null);
    System.out.println("总页数:"+page.getPages());
    System.out.println("总条数:"+page.getTotal());
    System.out.println("当前页记录:"+page.getRecords());
}

 运行结果:

(5)联表查询使用mp的分页

mybatis-plus是对单表操作的增强,不支持联表查询,我们需要在接口中自己定义联表查询的方法

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
//如果表名和实体类名不一致,使用该注解
@TableName("student")
public class Student {
    //标记该属性为主键,value标记列名和属性名对应
    /*AUTO(0),递增策略,如果使用该策略必须要求数据表的列也是递增。
      NONE(1),
      INPUT(2),没有策略,必须人为的输入id值
      ASSIGN_ID(3), 随机生成一个Long类型的值。该值一定是唯一。而且每次生成都不会相同。算法:雪花算法。 适合分布式主键。
      要求数据库中该列的类型为bigint,实体类中的数据类型为long类型
      ASSIGN_UUID(4); 随机产生一个String类型的值。该值也是唯一的。*/
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    //如果属性名和列名不一致使用该注解
    @TableField(value = "name")
    private String name;
    private Integer age;
    private String address;
    //标记该字段为逻辑字段,删除时修改该字段
    @TableLogic
    @TableField(fill = FieldFill.INSERT)
    private Boolean isdeleted;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;

    //标记该列数据库中没有
    @TableField(exist = false)
    private Clazz clazz;

    public Student(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

dao层:

@Mapper
public interface StudentMapper extends BaseMapper<Student> {
    IPage<Student> selectByCross(IPage<Student> page,@Param("ew") Wrapper<Student> queryWrapper);
}

映射文件:

<?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.gjx.dao.StudentMapper">
    <resultMap id="resultMap" type="com.gjx.entity.Student" autoMapping="true">
        <id property="id" column="id"/>
        <association property="clazz" javaType="com.gjx.entity.Clazz" autoMapping="true">
            <id property="clazzid" column="clazzid"/>
        </association>
    </resultMap>
    <select id="selectByCross" resultMap="resultMap">
        select * from student s join clazz c on s.clazzid=c.clazzid where s.isdeleted=0 and c.isdeleted=0
        <if test="ew!=null">
            and ${ew.sqlSegment}
        </if>
    </select>
</mapper>

 测试:

@Test
void testCross(){
    Page<Student> page = new Page<>(1,2);
    IPage<Student> page1 = studentMapper.selectByCross(page,null);
    System.out.println(page1.getRecords());
}

 运行结果:

7、mybatis-plus的代码生成器

(1)引入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.2</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>

(2)编写代码生成器

public class CodeGenerator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://192.168.1.29:3306/stu?serverTimezone=Asia/Shanghai", "root", "root")
                .globalConfig(builder -> {
                    builder.author("gjx") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir("./src/main/java"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com") // 设置父包名
                            .moduleName("gjx") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "./src/main/resources/mapper/")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("student") // 设置需要生成的表名
                            .addInclude("clazz");
                            //.addTablePrefix("t_", "c_"); // 设置过滤表前缀
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

    }
}

然后直接运行就可以生成自己所需的文件了。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值