mybatis-plus 相关

https://baomidou.com/guide

集成springboot

依赖

  • 核心依赖spring-boot-starter、lombo、mybatis-plus-boot-starter、mysql
  • 使用Mybatis-plus代替Mybatis的依赖
<dependencies>
		<!--核心 POM,包含自动配置支持、日志库和对 YAML 配置文件的支持-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<!--核心 POM,包含自动配置支持、日志库和对 YAML 配置文件的支持-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!--支持使用 JDBC 访问数据库-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<!-- springboot的启动依赖(集成tomcat)  -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!-- mysql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!-- mybatis plus -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.4.1</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-generator</artifactId>
			<version>3.4.1</version>
		</dependency>

		<!--Druid-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>

		<!--Junit-->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content implements Serializable{
    Long id;
    String author;
    String Content;
    String title;
    Integer category_id;
    Integer user_id;
    Date create_time;
}

Mapper

  • BaseMapper:泛型类,接受一个操作对象,实现该类的增删改查
@Repository
public interface ContentMapper extends BaseMapper<Content> {
}

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class ContentMapperTest {
    @Resource
    ContentMapper contentMapper;

    @Test
    public void list() throws Exception {
        List<Content> list = contentMapper.selectList(null);
        System.out.println("list = " + list);
    }
}

条件查询

  • orderByDesc: 排序
  • isNotNull:不为空
  • ge:匹配
  • eq:大于
    @Test
    public void select() {
        QueryWrapper<Content> wrapper = new QueryWrapper<>();
        wrapper.eq("author", "Tom")
                .isNotNull("title")
                .orderByDesc("create_time"); // 排序
        List<Content> contents = contentMapper.selectList(wrapper);
        System.out.println("contents = " + contents);
    }

修改自增策略

  • 默认雪花算法设置id的值
  • @TableId(type = IdType.AUTO):设置自增策略
  • 自增策略包括:自增id(AUTO)、UUID、手动输入(INPUT)、空(NONE)..
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content implements Serializable{
    @TableId(type = IdType.AUTO)
    Long id;
    String author;
    String Content;
    String title;
    Integer category_id;
    Integer user_id;
    Date create_time;
}

自动填充

在插入或更新时,填充字段值

  • @TableField(fill = FieldFill.INSERT):插入时填充
  • @TableField(fill = FieldFill.INSERT_UPDATE):插入更新时填充
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content implements Serializable{
    // 主键自增
    @TableId(type = IdType.AUTO)
    Long id;
    String author;
    String Content;
    String title;
    Integer category_id;
    Integer user_id;

    // 字段填充, 插入时填充
    @TableField(fill = FieldFill.INSERT)
    Date create_time;

    // 插入和更新时填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    Date update_time;
}

实现自定义类

  • 插入操作时调用insertFill方法,setFieldValByName设置属性值
    // 插入时填充
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("insertFill");
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }

    // 更新时填充
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("updateFill");
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }

测试

  @Test
    public void insert() {
        Content content = new Content();
        content.setAuthor("Tom");
        content.setTitle("Everyone and Everything");
        content.setContent("long long ago..");
        // 返回受影响的行数
        int insert = contentMapper.insert(content);
        System.out.println("insert = " + insert);
    }

乐观锁

乐观锁实现:当要更新一条记录的时候,希望这条记录没有被别人更新

  • @Version:标记为一个乐观锁字段

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content implements Serializable{
    // 主键自增
    @TableId(type = IdType.AUTO)
    Long id;

    String author;
    String Content;
    String title;
    Integer category_id;
    Integer user_id;

    // 乐观锁
    @Version
    Integer version;

    // 字段填充, 插入时填充
    @TableField(fill = FieldFill.INSERT)
    Date create_time;

    // 插入和更新时填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    Date update_time;
}

配置类配置乐观锁插件

/**
 * mybatis plus 配置类
 */
@MapperScan("com.exp.dao")
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfiguration {

 /**
     * 注册乐观锁和分页插件(新版:3.4.0)
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁插件
        // DbType:数据库类型(根据类型获取应使用的分页方言)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 分页插件
        return interceptor;
    }
}

测试

    @Test
    public void lock() {
        // 查询时获取version
        Content content = contentMapper.selectById(126);
        content.setAuthor("Mark");
        // 更新时进行version比对,确定没有被人修改
        contentMapper.updateById(content);
    }
    /**
     *
     * SELECT id,author,content,title,category_id AS category_id,user_id AS user_id,version,create_time AS create_time,update_time AS update_time FROM content WHERE id=? 
     *
     * UPDATE content SET author=?, content=?, title=?, version=?, update_time=? WHERE id=? AND version=? 
     *
     */

测试更新操作被插队

  • update操作会判断version是否被更改,没有则执行更新,并将version递增
    @Test
    public void lock() {
        // 查询时获取version
        Content content = contentMapper.selectById(126);

        // 模拟更新操作被插队(可能时其他线程)
        Content content1 = contentMapper.selectById(126);
        content1.setAuthor("Link");
        contentMapper.updateById(content1); // 此处已经将version更新

        content.setAuthor("Nobita");
        // 更新时进行version比对,确定没有被人修改,再更新version
        contentMapper.updateById(content);
    }
    /**
     *
     * SELECT id,author,content,title,category_id AS category_id,user_id AS user_id,version,create_time AS create_time,update_time AS update_time FROM content WHERE id=?
     *
     * SELECT id,author,content,title,category_id AS category_id,user_id AS user_id,version,create_time AS create_time,update_time AS update_time FROM content WHERE id=?
     *
     * UPDATE content SET author=?, content=?, title=?, version=?, update_time=? WHERE id=? AND version=?
     *
     * UPDATE content SET author=?, content=?, title=?, version=?, update_time=? WHERE id=? AND version=?
     *
     */

分页插件

配置类

@MapperScan("com.exp.dao")
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfiguration {

     /**
     * 注册乐观锁和分页插件(新版:3.4.0)
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁插件
        // DbType:数据库类型(根据类型获取应使用的分页方言)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 分页插件
        return interceptor;
    }
}

测试

  • new Page<>(起始位置, 大小)
    /**
     * SELECT id,author,content,title,category_id AS category_id,user_id AS user_id,version,create_time AS create_time,update_time AS update_time FROM content LIMIT 0,1 
     */
    @Test
    public void page() {
        Page<Content> objectPage = new Page<>(1, 1);
        IPage<Content> contentIPage = contentMapper.selectPage(objectPage, null);

        contentIPage.getRecords().forEach(System.out::println);

        System.out.println(contentIPage.getTotal()); // 获取总页数
        System.out.println(contentIPage.getPages()); // 获取总数
        System.out.println(contentIPage.getSize());  // 分页大小
        System.out.println(contentIPage.getCurrent()); // 当前记录位置
    }

逻辑删除

实体类逻辑字段

  • @TableLogic:标记为一个逻辑字段

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content implements Serializable{
    // 主键自增
    @TableId(type = IdType.AUTO)
    Long id;

    String author;
    String Content;
    String title;
    Integer category_id;
    Integer user_id;

    // 乐观锁
    @Version
    Integer version;

    // 逻辑删除
    @TableLogic
    Integer deleted;

    // 字段填充, 插入时填充
    @TableField(fill = FieldFill.INSERT)
    Date create_time;

    // 插入和更新时填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    Date update_time;
}

配置文件

mybatis-plus:
  configuration:
    # 是否开启自动驼峰命名规则
    map-underscore-to-camel-case: true
  global-config:
    db-config:
      # 全局逻辑删除的实体字段名
      logic-delete-field: flag
      # 逻辑被删除时的值
      logic-delete-value: 1
      # 逻辑没有被删除的值
      logic-not-delete-value: 0
  mapper-locations: classpath:mapper/*.xml

测试

    /**
     * UPDATE content SET deleted=1 WHERE id=? AND deleted=0
     */
    @Test
    public void delete() {
        contentMapper.deleteById(126L);
    }

逆向工程

需要模板的依赖

		<!-- 模板引擎 -->
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity-engine-core</artifactId>
			<version>2.0</version>
		</dependency>
/**
 * 自动生成代码
 */
public class GeneratorCode {
    public static void main(String[] args) {
        // 生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();

        // 配置策略
        // 1.全局策略
        GlobalConfig config = new GlobalConfig();
        // 设置生成目录
        String userDir = System.getProperty("user.dir"); // 获取工作目录
        config.setOutputDir(userDir+"/src/main/java");
        config.setAuthor("xiongyungang");
        config.setFileOverride(false); // 覆盖原文件
        config.setOpen(false); // 资源管理器中打开
        config.setServiceName("%sService"); // 默认Service前缀I,使用正则去掉I前缀
        config.setIdType(IdType.ID_WORKER); // 默认主键策略,雪花
        autoGenerator.setGlobalConfig(config);

        // 2.设置数据源
        DataSourceConfig sourceConfig = new DataSourceConfig();
        sourceConfig.setUrl("jdbc:mysql://localhost:3306/nobitan?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
        sourceConfig.setDriverName("com.mysql.jdbc.Driver");
        sourceConfig.setPassword("123456");
        sourceConfig.setUsername("root");
        sourceConfig.setDbType(DbType.MYSQL);
        autoGenerator.setDataSource(sourceConfig);

        // 3. 包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setController("controller");
        packageConfig.setEntity("entity");
        packageConfig.setMapper("mapper");
        //packageConfig.setModuleName("nobitan");
        packageConfig.setService("service");
        packageConfig.setParent("top.xiongyungang");
        autoGenerator.setPackageInfo(packageConfig);

        // 4.策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("content"); // 设置的表名
        strategyConfig.setEntityLombokModel(true); // 自动添加Lombok
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); // _转驼峰
        strategyConfig.setLogicDeleteFieldName("deleted"); // 逻辑删除
        // 自动填充
        TableFill createTimeFill = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTimeFill = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        strategyConfig.setTableFillList(Arrays.asList(createTimeFill, updateTimeFill));
        // 乐观锁
        strategyConfig.setVersionFieldName("version");
        strategyConfig.setRestControllerStyle(true);
        strategyConfig.setControllerMappingHyphenStyle(true); // localhost/get_id_2
        autoGenerator.setStrategy(strategyConfig);


        // 执行生成器
        autoGenerator.execute();
    }
}

原文地址:https://www.cnblogs.com/xiongyungang/p/14091763.html