mybatis_plus

mybatis_plus

Mybatis-Plus简介

1、什么是mybatis_plus

MybatisPlus是一个 MyBatis (opens new window)的增强工具.

在 MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。

愿景是成为 MyBatis最好的搭档,就像魂斗罗中的 1P、2P,基友搭配,效率翻倍。2、

2、Mybatis-Plus的优势

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。

  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作。

  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求。

  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错。

  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题

  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作。

  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。

  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用。

  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询。

  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库。

  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。

  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作。

3、MybaisPlus的框架结构

在这里插入图片描述

SpringBoot整合Mybatis-Plus入门案例

构建springboot项目

1、pom文件中引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<!-- 数据库mysql驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

<!-- mybatis-plus 的场景启动器-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>

2、创建数据库表,并引用数据

#建表--user
CREATE TABLE user(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

#导入数据
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

3、构建实体类 User

实体类中编写get、set、toString方法,有参构造、无参构造

public class User {
    private String username;
    private Integer age;
    private String email;
    private Date birthday;
}

4、配置application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///mybatisplus?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456

logging:
  level:
    com:
      chenshuang: debug

5、编写Springboot启动类

添加注解:@MapperScan— 根据扫描的包中接口 生成代理类对象 然后交给spring容器管理

@SpringBootApplication
// 根据扫描的包中接口 生成代理类对象 然后交给spring容器管理
@MapperScan(basePackages = "com.chenshuang.mapper")
public class SpringbootMybaitsPlus01Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootMybaitsPlus01Application.class, args);
    }
}

6、编写mapper接口

继承 BaseMapper<>接口,泛型为实体类名称

public interface UserMapper extends BaseMapper<User> {
}

7、启动服务测试结果

@SpringBootTest
class SpringbootMybaitsPlus01ApplicationTests {

    @Resource
    private UserMapper userMapper;

    @Test
    public void testSelectUser() {

        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);

    }
}

控制台打印成功:

在这里插入图片描述

@TableId注解

  • 描述:主键注解
属性类型必须指定默认值描述
valueString“”主键字段名
typeEnumIdType.NONE主键类型
IdType
描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
@NoArgsConstructor
@AllArgsConstructor
@Data
@ToString
public class Employee {
//使用数据库自增策略
//@TableId(type=IdType.AUTO)
//默认使用雪花算法生成数字
@TableId  
private Long empId;
private String empName;
private String empGender;
private Integer age;
private String email;
}

@TableName注解

  • 描述:表名注解

    属性类型必须指定默认值描述
    valueString“”表名
    schemaString“”schema
    keepGlobalPrefixbooleanfalse是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
    resultMapString“”xml 中 resultMap 的 id
    autoResultMapbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)
    excludePropertyString[]{}需要排除的属性名(@since 3.3.1)
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    
     // 用来表示实体类和数据库表的映射关系,当实体类名称和表的名称不相同时一定加  @TableName
    @TableName(value = "tb_employee")
    public class Employee {
    private Long empId;
    private String empName;
    private String empGender;
    private Integer age;
    private String email;
    }
    

@TableField注解

描述:字段注解(非主键)

属性类型必须指定默认值描述
valueString“”数据库字段名
elString“”映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
existbooleantrue是否为数据库表字段
conditionString“”字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考
updateString“”字段 update set 部分注入, 例如:update=“%s+1”:表示更新时会set version=version+1(该属性优先级高于 el 属性)
insertStrategyEnumNDEFAULT举例:NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
updateStrategyEnumNDEFAULT举例:IGNORED: update table_a set column=#{columnProperty}
whereStrategyEnumNDEFAULT举例:NOT_EMPTY: where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
fillEnumFieldFill.DEFAULT字段自动填充策略
selectbooleantrue是否进行 select 查询
keepGlobalFormatbooleanfalse是否保持使用全局的 format 进行处理
jdbcTypeJdbcTypeJdbcType.UNDEFINEDJDBC类型 (该默认值不代表会按照该值生效)
typeHandlerClass<? extends TypeHandler>UnknownTypeHandler.class类型处理器 (该默认值不代表会按照该值生效)
numericScaleString“”指定小数点后保留的位数
@Data
public class Employee {
@TableId
private Long empId;
 //    当实体类中的属性名与数据库的字段名不一致的时候,可以使用 注解:@TableField 来表示映射关系
 @TableField("name")
private String name;
private String empGender;
private Integer age;
private String email;
//@TableField(exist = false) 表示 数据库表中没有该字段的情况,映射转换sql语句的时候不会拼接上此字段
@TableField(exist = false)
private  String remark;
}

Mybatis-Plus通用CRUD

BaseMapper接口方法介绍

/**
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * <p>这个 Mapper 支持 id 泛型</p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public interface BaseMapper<T> extends Mapper<T> {

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

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

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

    /**
     * 根据 entity 条件,删除记录
     * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

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

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

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

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

    /**
     * 查询(根据ID 批量查询)
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 查询(根据 columnMap 条件)
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,查询一条记录
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询总记录数
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     * <p>注意: 只返回第一个字段的值</p>
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录(并翻页)
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

基于上面配置的数据库表以及环境来测试方法

1、增加 insert方法
@Test
public void testUserMethods() {
    User user = new User( "李四1", 18, "676864750@gmail.cn");
    int i = userMapper.insert(user);
    if (i>0){
        System.out.println("=========  添加成功  ===============");
    }
}
2、修改 updateById方法

根据主键修改【可以修改任意字段】

【相当于mybatis中逆向工程中的updateByPrimaryKeySelective()】

@Test
public void updateUserById() {
    User user = new User( "晨晨晨", 100, "zxcvbnm.com");
    user.setId(1L);
    userMapper.updateById(user);
}
3、查询 selectById方法

根据主键查询

@Test
public void selectUser() {
    User user = userMapper.selectById(1);
    System.out.println(user);
}
4、查询 selectBatchIds方法

批量查询指多个id的记录集合

@Test
public void selectBatchIds() {
    List<Integer> list = Arrays.asList(1, 2, 3);
    List<User> userList = userMapper.selectBatchIds(list);
    System.out.println(userList);
}
5、查询 selectByMap方法

根据Map集合中传入的条件(数据库表中的字段)进行查询,每个条件都是and关系。

@Test
public void selectByMap() {
    HashMap<String, Object> map = new HashMap<>();
    map.put("age", 18);
    List<User> list = userMapper.selectByMap(map);
    list.forEach(System.out::println);
}
6、删除 deleteById方法

根据主键id删除

@Test
public void deleteById() {
    int rows = userMapper.deleteById(3);
    System.out.println("删除行数:"+rows);
}
7、删除 deleteBatchIds方法

根据传入List集合中的id进行批量删除

@Test
public void deleteBatchIds() {
    List<Long> list = Arrays.asList(1538799991693152264L, 1538799991693152262L);
    int rows = userMapper.deleteBatchIds(list);
    System.out.println("删除行数:"+rows);
}
8、删除 deleteByMap方法

根据Map中的条件(数据库表中的字段)进行删除,map中的条件在sql语句中是and关系。

@Test
public void deleteByMap() {
    HashMap<String, Object> map = new HashMap<>();
    map.put("age",10);
    int rows = userMapper.deleteByMap(map);
    System.out.println("删除行数:"+rows);
}

物理分页

selectPage方法

selectPage用于分页,在mybatis-plus中分页有两种一种是逻辑分页或叫内存分页,另一种是物理分页。

内存分页就是把数据全部查询出来放到内存中,返回你想要的一部分数据,当数据量非常庞大时这种方法就行不通了,因为太耗内存,所以一般采用物理分页。

配置分页拦截器

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//        指定使用的数据库类型
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

应用分页

    @Test
    public void testPage() {

//        Mybatis_Plus中构造分页模型 Page
        Page<User> page = new Page<>(1,2);
//        selectPage 分页查询方法 返回Page
        Page<User> userPage = userMapper.selectPage(page, null);

        System.out.println("当前页:"+ userPage.getCurrent());
        System.out.println("每页记录数:"+userPage.getSize());
        System.out.println("总记录数:"+userPage.getTotal());
        System.out.println("总页数:"+userPage.getPages());
        List<User> employeeList = userPage.getRecords();
        employeeList.forEach(System.out::println);

    }

Mybatis-Plus的Service封装

通用service简介

Mybatis-Plus除了通用的Mapper还有通用的Servcie层,这也减少了相对应的代码工作量,把通用的接口提取到公共。其实按照MP的这种思想,可以自己也实现一些通用的Controller。

案例

1、构建maven工程添加依赖
    <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.47</version>
     </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>

     <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.4.2</version>
     </dependency>

     <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.12</version>
     </dependency>
2、构建service接口

继承IService<>接口,内置在BaseMapper接口基础上封装好的CRUD方法

public interface UserService extends IService<User> {
    
}
3、构建service实现类

实现自身实体类的Service接口,然后继承ServiceImpl<自身实体类Mapper,实体类>

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
4、通用servcie测试

save() 保存方法

@Test
public void addUser() {
    User user = new User( "王五", 18, "676864750@gmail.cn");
    boolean b = userService.save(user);
    System.out.println("增加成功与否"+b);
}

saveOrUpdate()

表示既可以增加也可以修改,根据自增条件id来判断,当有id时,就修改。没有id就增加

  @Test
    public void testSaveOrUpdate(){
        // 传入实体没有自增id 所以增加
        User user = new User( "赵六", 48, "cc.com");
        boolean b = userService.saveOrUpdate(user);
        System.out.println("增加或者成功与否:"+b);

        // 传入实体有自增id 所以根据id修改
        User user1 = new User( "赵六", 48, "cc.com");
        user1.setId(4L);
        boolean b1 = userService.saveOrUpdate(user);
    }

getOne()查询方法,重写的selectOne

@Test
public void getUserOne() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","李三");
    //  getOne(queryWrapper,false)  false表示即使查到的值不唯一,也不报异常,只查询第一个即可
    User user = userService.getOne(wrapper,false);
    System.out.println(user);
}

d 所以增加
User user = new User( “赵六”, 48, “cc.com”);
boolean b = userService.saveOrUpdate(user);
System.out.println(“增加或者成功与否:”+b);

    // 传入实体有自增id 所以根据id修改
    User user1 = new User( "赵六", 48, "cc.com");
    user1.setId(4L);
    boolean b1 = userService.saveOrUpdate(user);
}

> getOne()查询方法,重写的selectOne

```java
@Test
public void getUserOne() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","李三");
    //  getOne(queryWrapper,false)  false表示即使查到的值不唯一,也不报异常,只查询第一个即可
    User user = userService.getOne(wrapper,false);
    System.out.println(user);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮卡丘不断更

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值