Mybatis-plus初识

初步体验

  • 安装

注:引入mybatis-plus后就无需再次引入mybatis

       <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
           <version>3.4.3.4</version>
        </dependency>
  • 创建数据

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL COMMENT '主键ID',
  `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int(11) NULL DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'Jone', 18, 'test1@baomidou.com');
INSERT INTO `user` VALUES (2, 'Jack', 20, 'test2@baomidou.com');
INSERT INTO `user` VALUES (3, 'Tom', 28, 'test3@baomidou.com');
INSERT INTO `user` VALUES (4, 'Sandy', 21, 'test4@baomidou.com');
INSERT INTO `user` VALUES (5, 'Billie', 24, 'test5@baomidou.com');

SET FOREIGN_KEY_CHECKS = 1;

  • appliaction.properties配置
#数据库配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis-plus-demo?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&interactiveClient=true&allowMultiQueries=true

#日志配置控制台打印SQL
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  • 创建User类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
  private long id;
  private String name;
  private long age;
  private String email;
}

  • 创建User类
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wf.mybatisplusdemo.pojo.User;
import org.springframework.stereotype.Repository;

/**
 1. 编写Mapper接口,此处将不在需要编写相应xml文件
 */
@Repository
public interface UserMapper extends BaseMapper<User> {
    
}
  • 配置注解扫描
@SpringBootApplication
@MapperScan("com.wf.mybatisplusdemo.mapper")
public class MybatisPlusDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusDemoApplication.class, args);
    }
}
  • 运行
import com.wf.mybatisplusdemo.mapper.UserMapper;
import com.wf.mybatisplusdemo.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class MybatisPlusDemoApplicationTests {
    @Autowired
    private UserMapper userMapper;


    @Test
    void contextLoads() {
        //此处的参数为查询条件,当前表示无条件查询
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

}
  • 运行结果

实体类注解(以下叙述中属性并不完整)

  • @TableName ---标注表名

value (属性) 作用:表名
resultMap (属性) 作用:xml 中 resultMap 的 id
excludeProperty (属性) 作用:需要排除的属性名

  • @TableId---标注主键

value (属性) 作用:主键字段名称
type (属性) 作用:主键类型 (默认IdType.NONE,即没有主键)
type可选值:
IdType.AUTO 数据库ID自增
IdType.NONE 没有主键
IdType.INPUT 手动输入
IdType.ASSIGN_ID 使用雪花算法分配ID(主键类型为Number(Long和Integer)或String)
IdType.ASSIGN_UUID 分配一个不包含下划线32位的UUID,主键类型为String

  • @TableField---字段注解(非主键)

value(属性) 作用:数据库字段名
el (属性)作用:映射为原生 #{ … } 逻辑,相当于写在 xml 里的 #{ … } 部分
fill (属性) 作用:字段自动填充策略,比如自动生成创建时间(默认FieldFill.DEFAULT,即,不处理)
FieldFill可选值:
DEFAULT 默认不处理
INSERT 插入时填充字段
UPDATE 更新时填充字段
INSERT_UPDATE 插入和更新时填充字段

注:在添加fill (自动填充属性后,需要自定义生成策略,否则将会为null)
例:
实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {

  @TableField(value="create_time",fill = FieldFill.DEFAULT)
  private Date createTime;

}

生成策略:


@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 新增时,自动填充规则
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //createTime 为需要生成策略的字段名称
        //new Date() 填充的值
       this.setFieldValByName("createTime",new Date(),metaObject);
    }

    /**
     * 修改时,自动填充规则
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {

    }
}
  • @Version ---乐观锁注解,标注在version字段上

乐观锁的作用:当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁的实现方式:取出记录时,获取当前version值,在执行更新操作时,带上这个version值 set version = newVersion where version = oldVersion 如果version不对,说明这条记录已经被别人更新过了,本次更新就应该失败

例:
1.数据库表新增version(版本号)字段,默认值为1

在这里插入图片描述
2.实体类新增version属性

import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
  @TableId(value = "id",type = IdType.ASSIGN_ID)
  private String id;
  private String name;
  private long age;
  private String email;

  @TableField(value="create_time",fill = FieldFill.INSERT)
  private Date createTime;

  /**
   * 标注为乐观锁
   */
  @Version
  private Integer version;
}

3.注册乐观锁组件

package com.wf.mybatisplusdemo.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement //自动管理事务
@Configuration
public class MybatisPlusConfig {

    /**
     * 注册乐观锁插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

4.测试结果

 /**
     * 测试乐观锁
     */
    @Test
    void testMybatisPlusInterceptor(){
        /**
         * 注:因为实体类中使用了version注解,所以此处无需为version字段赋值,mybatisPlus会自动跟新version
         */

        //查询user,数据1
        User user=userMapper.selectById(1);
        user.setName("第一");
        user.setAge(1);


        //查询user,数据2
        User user2=userMapper.selectById(1);
        user2.setName("第二");
        user2.setAge(2);

        //此处模拟多线程情况下,user2先被更新,然后user1再被跟新
        userMapper.updateById(user2);

        //此处的修改,就会失败,因为version已经不同了
        userMapper.updateById(user);


    }

在这里插入图片描述

  • @TableLogic ---表字段逻辑处理注解(逻辑删除)

value (属性) 作用:逻辑未删除值
delval (属性) 作用:逻辑删除值

逻辑删除

逻辑删除:通过数据库中的字段状态值来控制数据的有效性,比如,表中含有start字段,当该字段的值为0时,表示该数据有效,当值为1时,表示该数据已经被删除
注:使用逻辑删除后,在查询和修改时,都会将该字段值作为where条件,所以查询时就不会查询出删除的数据,更新也不会更新删除的数据,在删除时执行的将会是修改操作

  1. 数据库新增逻辑删除字段
    在这里插入图片描述
    2.实体类标注注解
 /**
   * 逻辑删除字段
   * 此处标注过value 和 delval 后,如果不存在全局逻辑删除字段,则无需步骤3中的内容
   */
  @TableLogic(value = "0",delval ="1")
  private Integer start;

3.全局逻辑删除配置(若不存在全局配置,而在@TableLogic注解中就已经标注了未删除值和,已删除值,这样也可以执行,就不需要以下配置了)

# 全局逻辑删除的实体字段名
mybatis-plus.global-config.db-config.logic-delete-field=flag
# 全局逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 全局逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0

4.测试

    /**
     * 测试逻辑删除
     */
    @Test
    void testDelete() {
        //根据ID删除
        userMapper.deleteById("2");
    }
---------------执行结果---------------------
==>  Preparing: UPDATE user SET start=1 WHERE id=? AND start=0
==> Parameters: 2(String)
<==    Updates: 1

条件查询

    /**
     * 测试条件查询
     */
    @Test
    void testSelect() {
        /**
         * 查询ID为1的用户
         */
        User user = userMapper.selectById(1);
        System.out.println(user);


        /**
         * 查询ID为0,或ID为1,或ID为3的用户
         */
        List<User> users = userMapper.selectBatchIds(Arrays.asList(0, 1, 3));
        users.forEach(System.out::println);


        /**
         * 使用map封装条件查询
         */
        Map<String,Object> queryMap=new HashMap<>();
        queryMap.put("name","第二");
        List<User> byMap = userMapper.selectByMap(queryMap);
        byMap.forEach(System.out::println);
    }

条件构造器查询

1.条件查询

 /**
     * 通过条件构造器查询
     */
    @Test
    void testWrapper() {
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper
                .ge("age",18)
                .isNotNull("name")
                .isNull("email")
                .likeLeft("name","1");
        userMapper.selectList(queryWrapper);
    }
    ------------------执行SQL------------------
    SELECT
	id,
	NAME,
	age,
	email,
	create_time,
	version,
    START 
FROM
   USER 
WHERE
	START = 0 
	AND ( age >= 18
	      AND NAME IS NOT NULL 
	      AND email IS NULL
	       AND NAME LIKE '%1'
	    )

2.子查询

 @Test
    void testWrapper() {
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.inSql("id","select ID from user where age>3");
        userMapper.selectList(queryWrapper);
    }
 ---------------------执行SQL-----------------------  
 SELECT
	id,
	NAME,
	age,
	email,
	create_time,
	version,
    START 
FROM
   USER 
WHERE
	START = 0 
	AND (
	id IN ( SELECT ID FROM USER WHERE age > 3 )) 

此处仅作实例,具体请参见官网

分页查询

1.注入分页拦截器


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement //自动管理事务
@Configuration
public class MybatisPlusConfig {

    /**
     * 注入插件
     *
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //注入乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //注入分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }


}

2.测试

   /**
     * 测试分页查询
     */
    @Test
    void testPage() {
        //创建分页对象,当前页码数为 1 ,每页展示 5 条数据
        Page<User> page=new Page<>(1,5);
        //不查询count
        page.setSearchCount(false);
        //查询结果
        userMapper.selectPage(page,null);
        //获取返回结果
        page.getRecords().forEach(System.out::println);
        //可分页页数
        System.out.println(page.getPages());
        //当前页码数
        System.out.println(page.getCurrent());
        //总记录条数
        System.out.println(page.getTotal());

    }

自定义SQl分页查询

  • 编写mapper
  <select id="selectUserList" resultType="User">
        SELECT
            id,
            NAME,
            age,
            email,
            create_time,
            version,
            START
        FROM
            USER
        where
        <if test="params.age !=null">
            AND age=#{params.age}
        </if>
    </select>
  • Mapper接口
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cn.test_plus.bean.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;


@Repository
public interface UserMapper {

    /**
     * 查询用户列表
     * @param page
     * @return
     */
    IPage<User> selectUserList(@Param("page") Page<User> page, @Param("params") Map<String, Object> params);

}
  • controller查询
 @Autowired
 private UserMapper userMapper;

  @PostMapping(value = "/queryList")
    public Page<User> queryUserList(@RequestBody Map<String, Object> pamram) {
        Integer page =(Integer)pamram.get("pageIndex");
        Integer size =(Integer)pamram.get("size");
        if (page != null && size != null) {
            //创建分页对象,当前页码数为 1 ,每页展示 10 条数据
            Page<AnswerRecord> result = new Page<>(page, size);
            //查询count
            result.setSearchCount(true);
            //查询用户列表
            userMapper.selectUserList(result, pamram);
            return result;
          }
          return null;
    }

条件删除

/**
     * 测试条件删除
     */
    @Test
    void testDelete() {
        //根据ID删除
        userMapper.deleteById("0");
        //根据map条件删除
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","zhangsna");
        userMapper.deleteByMap(map);
        //根据ID批量删除
        userMapper.deleteBatchIds(Arrays.asList(1,2,3));
    }

代码自动生成器

依赖:

       <!--mybatisPlus代码自动生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;
import java.util.List;

/**
 * 代码自动生成配置类
 */
public class CodeGenerator {

    public static void main(String[] args) {
        //创建代码生成器对象
        AutoGenerator mpg=new AutoGenerator();

        //1. 全局配置
        GlobalConfig gc=new GlobalConfig();
        //获取当前项目路径
        String projectPath = System.getProperty("user.dir");
        //设置文件生成路径
        gc.setOutputDir(projectPath+"/src/main/java");
        //设置作者
        gc.setAuthor("wf");
        //是否打开资源管理器,(就是打开文件夹)
        gc.setOpen(false);
        //是否覆盖当前文件
        gc.setFileOverride(false);
        //Service接口名称
        gc.setServiceName("Service");
        //设置表的主键生成策略为uuid
        gc.setIdType(IdType.ASSIGN_UUID);
        //设置日期类型
        gc.setDateType(DateType.ONLY_DATE);
        //是否配置swagger
        gc.setSwagger2(true);
        //注入全局配置
        mpg.setGlobalConfig(gc);

        //2.配置数据源
        DataSourceConfig dsc=new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus-demo?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&interactiveClient=true&allowMultiQueries=true");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        //设置连接的数据库类型
        dsc.setDbType(DbType.MYSQL);
        //注入数据源
        mpg.setDataSource(dsc);

        //3.配置包
        PackageConfig pc=new PackageConfig();
        //设置模块包名称
        pc.setModuleName("project");
        //设置包名
        pc.setParent("com.wf");
        //设置实体类包名称
        pc.setEntity("bean");
        //设置mapper包名称
        pc.setMapper("mapper");
        //设置service包名称
        pc.setService("service");
        //设置controller包名称
        pc.setController("controller");
        //注入包的配置
        mpg.setPackageInfo(pc);

        // 4.策略配置
        StrategyConfig strategy = new StrategyConfig();
        //映射的表,即,即要生成那个表,支持多个参数
        strategy.setInclude("user");
        //包名使用下划线转驼峰命名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //列名使用下划线转驼峰命名
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //是否使用lombock
        strategy.setEntityLombokModel(true);
        //设置逻辑删除字段名称
        strategy.setLogicDeleteFieldName("start");
        //字段配置自动填充策略
        TableFill tb=new TableFill("create_time", FieldFill.INSERT);
        List<TableFill>  fillList=new ArrayList<>();
        fillList.add(tb);
        strategy.setTableFillList(fillList);
        //设置乐观锁字段名称
        strategy.setVersionFieldName("version");
        //controller是否可以使用resultful风格
        strategy.setRestControllerStyle(true);
        //注入策略配置
        mpg.setStrategy(strategy);

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

生成结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

亿只王菜菜

各位爷,赏口饭吃吧

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

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

打赏作者

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

抵扣说明:

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

余额充值