Mybatis - plus -----从 入门 到 精通-----

一 介绍

官网:https://baomidou.com/pages/24112f/

MyBatis-Plus简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

愿景:

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

1 特性

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

  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

2 框架结构

二 Springboot整合

1 创建数据库

CREATE TABLE `tb_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `tb_student`(`id`, `username`, `password`, `name`, `age`, `email`) VALUES (1, 'zhangsan', '123', '张三', 12, 'zhangsan@126.com');
INSERT INTO `tb_student`(`id`, `username`, `password`, `name`, `age`, `email`) VALUES (2, 'xiaogeng', '234', '小耿', 15, 'xiaogen@126.com');
INSERT INTO `tb_student`(`id`, `username`, `password`, `name`, `age`, `email`) VALUES (3, 'laofeng', '456', '老冯', 21, 'laofeng@126.com');
INSERT INTO `tb_student`(`id`, `username`, `password`, `name`, `age`, `email`) VALUES (5, 'laohan', '888', '老韩', 30, NULL);

 

2 导入依赖

<!--简化代码的工具包-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!--mybatis-plus的springboot支持-->
 <dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-boot-starter</artifactId>
     <version>3.1.1</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.1.1</version>
        </dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
</dependency>
# mybatis-plus配置
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.xinzhi.model
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
mybatis-plus.mapper-locations=classpath:mapper/*.xml
mybatis-plus.type-aliases-package=com.xinzhi.model
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.configuration.map-underscore-to-camel-case=true

3 Usermapper

public interface UserMapper extends BaseMapper<User> {
    
}

实体类上添加 @TableName()

package com.xinzhi.model;


import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName()
public class User {

    private int id;
    private String username;
    private String password;
    private String name;
    private int age;
    private String email;

}

4 测试类

package com.xinzhi;

import com.xinzhi.dao.UserMapper;
import com.xinzhi.model.User;
import com.xinzhi.service.IAccountService;
import com.xinzhi.service.IUserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application.xml"})
public class SmTest {

    @Autowired
    private IUserService userService;

    @Test
    public void testQueryAll(){
        List<User> users = userService.queryAll();
        System.out.println(users);
    }
}

5 结论

我们没有写过sql语句,但是我们可以直接使用BaseMapper中的方法,可以省去我们写sql的麻烦。

 

三 实体类注解

1 @TableName

加在实体类上的,@TableName(表名)

@TableId

在给数据库插入数据的时候,可以通过给实体类id字段添加注解实现id的自动插入。@TableId(type = IdType.AUTO),一般使用自增。type = IdType.AUTO

@TableField

1、对象中的属性名和字段名不一致的问题(非驼峰)

2、对象中的属性字段在表中不存在的问题

3、对象中的属性字段在表中不查询。

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField("username")
    private String username;
    @TableField(select = false)
    private String password;
    @TableField("name")
    private String name;
    @TableField("age")
    private Integer age;
    @TableField("email")
    private String email;
    @TableField(exist = false)
    private String address;
}

四 常用方法

如果我们使用mybatis-plus, 那么我们实体类的属性不能使用基本数据类型。

1.    int insert(T entity);

根据给定的属性插入数据,没有指定的属性为null, id不给定会自增

@Test
public void add() {
    User user = User.builder().username("laohan").name("老韩").password("888").age(30).build();
    int insert = userMapper.insert(user);
    System.out.println(insert>0?"成功":"失败");
}

2.    int updateById(@Param("et") T entity);

根据id修改,所以必须指定id的值,对象中没有指定的属性不修改。

 @Test
    public void testUpdateById(){
        User user = User.builder().id(2).age(22).build();
        if(userMapper.updateById(user)>0){
            System.out.println("OK");
        }else {
            System.out.println("error");
        }
    }

3.   int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

根据条件修改,QueryWrapper方法比较多,一会专门讲一下QueryWrapper。

@Test
    public void testUpdate(){
        User user = User.builder().username("laohan").age(22).build();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.ge("username", "老韩");
        if(userMapper.update(user,wrapper)>0){
            System.out.println("OK");
        }else {
            System.out.println("error");
        }
    }

4.    int deleteById(Serializable id);

根据id删除数据

@Test
public void deleteById() {
    int i = userMapper.deleteById(4);
    System.out.println(i>0?"成功":"失败");
}

5.    int deleteByMap(@Param("cm") Map<String, Object> columnMap);

将columnMap中的元素设置为删除的条件,多个之间为and关系

@Test
public void deleteByMap() {
    Map<String, Object> columnMap = new HashMap<>();
    columnMap.put("age", 30);
    columnMap.put("name", "老韩"); //将columnMap中的元素设置为删除的条件,多个之间为and关系
    int i = this.userMapper.deleteByMap(columnMap);
    System.out.println(i > 0 ? "成功" : "失败");
}

6.    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

根据id批量删除, 不存在的id不删除

@Test
public void deleteByIds() {
    List<Long> ids = Stream.of(1L, 2L, 3L,8L).collect(Collectors.toList());
    int i = userMapper.deleteBatchIds(ids);
    System.out.println(i);
}

7.   T selectById(Serializable id);

根据id查询

8.   List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

根据id列表查询

9.   List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

条件构造器

Wrapper

wrapper 条件 相当于我们sql语句中where后面的部分

如果wrapper有多个条件,默认使用and拼接

一般我们用QueryWrapper就可以了

  • allEq(Map<R, V> params)

 int delete(@Param("ew") Wrapper<T> wrapper);
 @Test
    public void deleteByCondition() {
        // 构建条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        // 构建map
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("age", 30);
        columnMap.put("name", "老韩");
        // 所有的条件都要满足才能删除
        wrapper.allEq(columnMap);
        int delete = userMapper.delete(wrapper);
        System.out.println(delete);
    }

eq 等于 =

 @Test
public void selectOne() {
    // 构建条件
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name", "老韩");
    User user = userMapper.selectOne(wrapper);
    System.out.println(user);
}

ne 不等于 <>

gt 大于 >

ge 大于等于 >=

lt 小于 < less

le 小于等于 <= less equals

between BETWEEN 值1 AND 值2

notBetween NOT BETWEEN 值1 AND 值2

in 字段 IN (value.get(0), value.get(1), ...)

notIn 字段 NOT IN (v0, v1, ...)

like LIKE '%值%' 例: like("name", "王") ---> name like '%王%'

notLike NOT LIKE '%值%

likeLeft LIKE '%值' 例: likeLeft("name", "王") ---> name like '%王'

likeRight LIKE '值%' 例: likeRight("name", "王") ---> name like '王%'

orderBy 排序:ORDER BY 字段, ...

orderByAsc 排序:ORDER BY 字段, ... ASC 例: orderByAsc("id", "name") ---> order by id ASC,name ASC

orderByDesc 排序:ORDER BY 字段, ... DESC 例: orderByDesc("id", "name") ---> order by id DESC,name DESC

or 拼接 OR 主动调用 or 表示紧接着下一个方法不是用 and 连接!(不调用 or 则默认为使用 and 连接)

and AND 嵌套

例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status

<> '活着')

六 自动填充

1.  实体类添加创建时间和修改时间字段,并且添加注解

@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

2.   新建handler文件夹,新建处理器

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);

    @Override
    public void insertFill(MetaObject metaObject) {
        LOGGER.info("start insert fill ....");
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        LOGGER.info("start update fill ....");
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

3.   测试添加和修改(不需要指定时间),可以看到数据有时间的变化

七 逻辑删除

1.   数据库添加字段deleted

2.   实体类添加属性

 3.   配置文件添加

4.   处理器中添加

 

 

八 代码生成器

使用mybatis-plus代码生成器生成代码是固定的格式,在测试类中执行以下代码

package com.xinzhi;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

/**
 * @author
 */
public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir("D:\\xinzhi66\\edu_parent\\service\\edu_service" + "/src/main/java");

        gc.setAuthor("laohan");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖

        //UserServie
        gc.setServiceName("%sService");	//去掉Service接口的首字母I

        gc.setIdType(IdType.ID_WORKER_STR); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://82.157.173.221:3306/guli?serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("xinzhi666");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("eduservice"); //模块名
        //包  com.atguigu.eduservice
        pc.setParent("com.xinzhi");
        //包  com.atguigu.eduservice.controller
        pc.setController("controller");
        pc.setEntity("model");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        strategy.setInclude("edu_teacher");

        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值