欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

枚举类型用法_Mybatis-plus常见用法总结三

发布时间:2023/12/20 编程问答 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 枚举类型用法_Mybatis-plus常见用法总结三 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前面已经介绍了Mybatis-plus基本用法,今天为大家分享一些Mybatis-plus高级应用

  • 逻辑删除
  • 自动注入
  • 枚举类型处理
  • Sql注入器
  • 多租户
  • 表结构

    CREATE TABLE `sys_role` ( `id` varchar(64) NOT NULL COMMENT '主键', `code` varchar(64) NOT NULL DEFAULT '' COMMENT '角色编码', `name` varchar(64) NOT NULL DEFAULT '' COMMENT '角色名', `type` char(2) NOT NULL COMMENT '角色类型,1:管理员,2:普通', `tenant_code` varchar(64) NOT NULL DEFAULT '' COMMENT '租户编码', `create_user` varchar(64) NOT NULL DEFAULT '' COMMENT '创建用户', `create_time` datetime NOT NULL COMMENT '创建时间', `update_user` varchar(64) NOT NULL DEFAULT '' COMMENT '更新用户', `update_time` datetime NOT NULL COMMENT '更新时间', `is_del` char(1) NOT NULL DEFAULT '0' COMMENT '是否删除,0:未删除,1:删除', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色';

    逻辑删除

    全局配置

    在配置文件中增加如下配置

    mybatis-plus: global-config:   db-config:     logic-delete-field: isDel#全局逻辑删除字段值 3.3.0开始支持,详情看下面。     logic-delete-value: 1 # 逻辑已删除值(默认为 1)     logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

    局部配置

    在实体类删除字段上增加@TableLogic注解

    /** 是否删除,0:未删除,1:删除 */@TableLogicprivate String isDel;

    全局配置和局部配置实现的结果是一样的,下面针对局部配置做一下测试

    @Autowiredprivate RoleMapper roleMapper;@Testpublic void logicDel() {    roleMapper.deleteById("1");}

    从结果可以看出角色id为1数据的is_del被设置为1

    使用Mybatis-plus自带方法删除、更新和查找都会where条件后面加上删除字段

    以查询为例看一下效果

    @Test void loginDel2() {    roleMapper.selectList(null);}

    从打印的sql中可以看出,在where后面添加了is_del='0'限定,所以要查询所有数据可以采用自定义sql实现

    自动填充

    在项目开发中,表中经常会定义一些公共的字段,例如:修改人,创建人。这时候我们可以采用 MyBatis-Plus 中

    的字段自动填充功能去实现。

  • 在实体类属性上增加@TableField(fill = FieldFill.INSERT_UPDATE)注解,如下所示
  • @Data@TableName("sys_role")public class Role {    /** 创建人 */    @TableField(fill = FieldFill.INSERT)    private String createUser;    /** 创建时间 */    @TableField(fill = FieldFill.INSERT)    private Date createTime;    /** 更新人 */    @TableField(fill = FieldFill.INSERT_UPDATE)    private String updateUser;    /** 更新时间 */    @TableField(fill = FieldFill.INSERT_UPDATE)    private Date updateTime;    /** 是否删除,0:未删除,1:删除 */    @TableLogic    private String isDel;}

    TableField默认有四个

    • DEFAULT:默认不处理
    • INSERT:插入时填充字段
    • UPDATE:更新时填充字段
    • INSERT_UPDATE:插入和更新时填充字段
  • 定义处理器
  • @Componentpublic class MyMetaObjectHandler implements MetaObjectHandler {​   public static String CREATEUSER_NAMEINBEAN = "createUser";    public static String CREATETIME_NAMEINBEAN = "createTime";    public static String UPDATEUSER_NAMEINBEAN = "updateUser";    public static String UPDATETIME_NAMEINBEAN = "updateTime";    @Override    public void insertFill(MetaObject metaObject) {        boolean createUser = metaObject.hasSetter(CREATEUSER_NAMEINBEAN);        if (createUser) {            this.strictInsertFill(metaObject, CREATEUSER_NAMEINBEAN, String.class, "admin");       }        boolean createTime = metaObject.hasSetter(CREATETIME_NAMEINBEAN);        if (createTime) {            this.strictInsertFill(metaObject, CREATETIME_NAMEINBEAN, LocalDateTime.class, LocalDateTime.now());       }        boolean updateUser = metaObject.hasSetter(UPDATEUSER_NAMEINBEAN);        if (updateUser) {            this.strictInsertFill(metaObject, UPDATEUSER_NAMEINBEAN, String.class, "admin");       }        boolean updateTime = metaObject.hasSetter(UPDATETIME_NAMEINBEAN);        if (updateTime) {            this.strictInsertFill(metaObject, UPDATETIME_NAMEINBEAN, LocalDateTime.class, LocalDateTime.now());       }   }​    @Override    public void updateFill(MetaObject metaObject) {        boolean updateUser = metaObject.hasSetter(UPDATEUSER_NAMEINBEAN);        if (updateUser) {            this.strictInsertFill(metaObject, UPDATEUSER_NAMEINBEAN, String.class, "amdin");       }        boolean updateTime = metaObject.hasSetter(UPDATETIME_NAMEINBEAN);        if (updateTime) {            this.strictInsertFill(metaObject, UPDATETIME_NAMEINBEAN, LocalDateTime.class, LocalDateTime.now());       }   }}​
  • 测试
  • @Testvoid update() { // 更新id为2角色的名字为测试2 Role role = new Role(); role.setName("测试2"); role.setId("2"); roleMapper.updateById(role);}

    在执行更新操作时自动加上更新人和更新时间

    枚举类型处理器

    自mybatis3.1.0开始,如果你无需使用原生枚举,可配置默认枚举来省略扫描通用枚举配置 默认枚举配置

  • 定义枚举类,主要有两种方式
  • 方法一:采用继承IEnum实现

    @Getter@AllArgsConstructorpublic enum RoleType implements IEnum { ADMIN("1"), COMMON("2"); private String type; @Override public Serializable getValue() { return type; }}

    方法二:注解方式,在枚举类需要解析的属性上增加@EnumValue注解

    @Getter@AllArgsConstructorpublic enum RoleType { ADMIN("1"), COMMON("2"); @EnumValue//标记数据库存的值是type private String type;}
  • 定义实体类
  • @Data@TableName("sys_role")public class Role { /** 角色类型 */ private RoleType type;}
  • 配置扫描的枚举包路径
  • mybatis-plus: typeEnumsPackage: com.yanyu.spring.mybatisplus.enums

    从结果可以看出查询出的角色类型自动转换成了枚举ADMIN

    Sql注入

    当Mybatis-plus自带的原生方法不能满足我们的需求,我们可以利用sql注入器自定义sql

    实现步骤:

  • 创建自定义的类
  • public class DeleteByCodeMethod extends AbstractMethod { @Override public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) { // 执行的slq String sql = "delete from "+ tableInfo.getTableName() +" where code = #{code}"; // Mapper接口方法名 String method = "deleteByCode"; SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return addDeleteMappedStatement(mapperClass, method, sqlSource); }}
  • 创建注入器
  • @Componentpublic class MySqlInject extends DefaultSqlInjector { @Override public List getMethodList(Class> mapperClass) { List methodList = super.getMethodList(mapperClass); methodList.add(new DeleteByCodeMethod()); return methodList; }}
  • 在Mapper中加入自定义方法
  • public interface RoleMapper extends BaseMapper { int deleteByCode(@Param("code") String code);}
  • 测试
  • @Testvoid deleteByCode() { // 删除编码为code的角色 roleMapper.deleteByCode("test");}

    从结果看,我们自定义的根据编码删除数据执行成功

    Mybatis-plus官方为我们提供了三种自定义类

    • InsertBatchSomeColumn:批量新增数据,自选字段insert
    • AlwaysUpdateSomeColumnById:根据id更新固定字段
    • LogicDeleteByIdWithFill:根据id逻辑删除,并带字段填充功能

    以InsertBatchSomeColumn为例,简单的演示一下怎么使用

  • 在注入器中加入InsertBatchSomeColumn自定义类
  • @Componentpublic class MySqlInject extends DefaultSqlInjector { @Override public List getMethodList(Class> mapperClass) { List methodList = super.getMethodList(mapperClass); methodList.add(new DeleteByCodeMethod()); /** * 不是逻辑删除的字段包括在内 */ methodList.add(new InsertBatchSomeColumn(t -> !t.isLogicDelete())); return methodList; }}
  • 在Mapper中加入自定义方法
  • public interface RoleMapper extends BaseMapper { int insertBatchSomeColumn(List list);}
  • 测试
  • @Testvoid insertBatchSomeColumn() { // 测试批量插入角色1和角色2 Role role1 = new Role(); role1.setCode("ROLE_1"); role1.setName("角色1"); role1.setType(RoleType.ADMIN); Role role2 = new Role(); role2.setCode("ROLE_2"); role2.setName("角色2"); role2.setType(RoleType.ADMIN); List roles = new ArrayList<>(Arrays.asList(role1,role2)); roleMapper.insertBatchSomeColumn(roles);}

    多租户

    租户实现

    Mybatis-plus多租户依赖于分页插件,下面我们将简单介绍如何实现租户解析

  • 定义租户解析器
  • @Beanpublic PaginationInterceptor paginationInterceptor() throws IOException { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); TenantSqlParser tenantSqlParser = new TenantSqlParser(); tenantSqlParser.setTenantHandler(new TenantHandler() { @Override public Expression getTenantId(boolean select) { return new StringValue("00000"); } @Override public String getTenantIdColumn() { return "tenant_code"; } @Override public boolean doTableFilter(String tableName) { /** * 是否加租户信息,false->加,true->不加 */ return false; } }); paginationInterceptor.setSqlParserList(Arrays.asList(tenantSqlParser)); return paginationInterceptor;}
  • 测试
  • @Testpublic void tenant() { // 查询id为1的角色 roleMapper.selectById("1");}

    从结果看,sql执行时在查询条件中自动为我们加上了租户判断

    特定sql过滤

    在开发中有的方法不需要限定租户标识,实现方式有两种

  • 方式一:通过在分页插件中自定义过滤器,具体实现如下所示
  • @Beanpublic PaginationInterceptor paginationInterceptor() throws IOException { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); TenantSqlParser tenantSqlParser = new TenantSqlParser(); tenantSqlParser.setTenantHandler(new TenantHandler() { @Override public Expression getTenantId(boolean select) { return new StringValue("00000"); } @Override public String getTenantIdColumn() { return "tenant_code"; } @Override public boolean doTableFilter(String tableName) { /** * 是否加租户信息,false->加,true->不加 */ return false; } }); paginationInterceptor.setSqlParserList(Arrays.asList(tenantSqlParser)); paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() { /** * true 不增加,false 增加 * @param metaObject * @return */ @Override public boolean doFilter(MetaObject metaObject) { MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject); if("具体方法".equals(ms.getId())) { return true; } return false; } }); return paginationInterceptor;}
  • 方式二:在不需要限定租户的方法上加入
  • public interface RoleMapper extends BaseMapper { @SqlParser(filter = true) int getByCode(String code);}

    如果有哪里写得不对的,还请各位小友指正,只有不断试错,才能慢慢提高。如果你觉得对你有帮助,请点赞+关注,谢谢!!!!!!

    总结

    以上是生活随笔为你收集整理的枚举类型用法_Mybatis-plus常见用法总结三的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。