返回顶部
首页 > 资讯 > 精选 >tk.mybatis怎么扩展自己的通用mapper
  • 539
分享到

tk.mybatis怎么扩展自己的通用mapper

2023-06-15 11:06:10 539人浏览 八月长安
摘要

小编给大家分享一下tk.mybatis怎么扩展自己的通用mapper,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!tk.mybatis扩展自己的通用mapper目的:tk.mybatis 提供的通用mapper,虽然使用方

小编给大家分享一下tk.mybatis怎么扩展自己的通用mapper,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

tk.mybatis扩展自己的通用mapper

目的:tk.mybatis 提供的通用mapper,虽然使用方便,不过在有些sql还是不能满足我们的需要的,而且我们希望对于deleted语句进行管控(因为通用mapper提供的都是物理删除,有时我们对一些敏感数据只能进行逻辑删除),因此我们将基于原有的通用mapper进行自己的扩展

1 jar引入

 <!-- 非SpringBoot -->        <dependency>            <groupId>tk.mybatis</groupId>            <artifactId>mapper</artifactId>            <version>3.4.0</version>        </dependency>

springboot项目引这个包

  <!-- springboot -->             <dependency>                <groupId>tk.mybatis</groupId>                <artifactId>mapper-spring-boot-starter</artifactId>                <version>2.0.2</version>            </dependency>

springboot项目直接引这个包,本次我们将基于springboot进行开发,这里注意jar包版本,过低的版本将会出现问题,下面会介绍

2 编写配置类

package com.example.configuration;import com.example.common.mapper.commonMapper.CommonMapper;import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;import org.springframework.boot.autoconfigure.AutoConfigureAfter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import tk.mybatis.spring.mapper.MapperScannerConfigurer;import java.util.Properties;@Configuration@AutoConfigureAfter(MybatisAutoConfiguration.class)public class MyBatisConfiguration {    @Bean    public MapperScannerConfigurer mapperScannerConfigurer() {        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");        mapperScannerConfigurer.setBasePackage("com.example.dao.mapper");        Properties properties = new Properties();        properties.setProperty("mappers", CommonMapper.class.getName());        properties.setProperty("notEmpty", "false");        properties.setProperty("identity", "MYSQL");        properties.setProperty("order","BEFORE");        mapperScannerConfigurer.setProperties(properties);        return mapperScannerConfigurer;    }}

这里要注意两点:

1>CommonMapper这个是我们自己定义的通用mapper,它放置一个单独的包下面。也就是说这个包下面只有这个一个mapper,否则我们在实用泛型时会出现类型转换的问题。(我在这里纠结了好久)

2>这里我们配置了自定义mapper的扫描路径。注意springboot项目一定要注意jar包版本,版本过低的话,在配置类中的定义是没有用的。还是扫描不到,我之前使用的版本1.2.3就会出现这个问题,更换更高的版本就可以解决了。

3 常规方法接口整合到自己的自定义Mapper接口上

因为我们使用的是Mysql数据库,所以在使用通用功能的时候就选择性引入一些经常使用的方法,下面是自己定义的常用mapper类的整合(这里会抛弃一些不常用的类或不是mysql的方法类)。这些基类不要放在 BasePackage的路径下,这个路径下的mapper都是要指定明确的泛型类型的。

1 > 提供查询功能Mapper:

package com.example.common.mapper.basics;import tk.mybatis.mapper.common.Marker;import tk.mybatis.mapper.common.base.select.*;import tk.mybatis.mapper.common.condition.SelectByConditionMapper;import tk.mybatis.mapper.common.condition.SelectCountByConditionMapper;import tk.mybatis.mapper.common.example.SelectByExampleMapper;import tk.mybatis.mapper.common.ids.SelectByIdsMapper;public interface SelectMapper<T> extends Marker,        SelectOneMapper<T>,        tk.mybatis.mapper.common.base.select.SelectMapper<T>,        SelectAllMapper<T>,        SelectCountMapper<T>,        SelectByPrimaryKeyMapper<T>,        ExistsWithPrimaryKeyMapper<T>,        SelectByIdsMapper<T>,        SelectByConditionMapper<T>,        SelectCountByConditionMapper<T>,        SelectByExampleMapper<T> {}

2>提供新增功能mapper

package com.example.common.mapper.basics;import tk.mybatis.mapper.common.Marker;import tk.mybatis.mapper.common.MySqlMapper;import tk.mybatis.mapper.common.base.insert.InsertSelectiveMapper;public interface InsertMapper<T> extends Marker,        tk.mybatis.mapper.common.base.insert.InsertMapper<T>,        InsertSelectiveMapper<T>,        MySqlMapper<T>{}

3>提供更新功能mapper

package com.example.common.mapper.basics;import tk.mybatis.mapper.common.Marker;import tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeyMapper;import tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeySelectiveMapper;import tk.mybatis.mapper.common.condition.UpdateByConditionMapper;import tk.mybatis.mapper.common.condition.UpdateByConditionSelectiveMapper;import tk.mybatis.mapper.common.example.UpdateByExampleSelectiveMapper;public interface UpdateMapper<T> extends Marker,        UpdateByPrimaryKeyMapper<T>,        UpdateByPrimaryKeySelectiveMapper<T>,        UpdateByConditionMapper<T>,        UpdateByConditionSelectiveMapper<T>,        UpdateByExampleSelectiveMapper<T> {}

4>提供删除功能mapper

package com.example.common.mapper.basics;import com.example.common.mapper.defined.DeleteShamByIdsMapper;import tk.mybatis.mapper.common.Marker;import tk.mybatis.mapper.common.base.delete.DeleteByPrimaryKeyMapper;import tk.mybatis.mapper.common.condition.DeleteByConditionMapper;import tk.mybatis.mapper.common.ids.DeleteByIdsMapper;public interface DeleteMapper<T> extends Marker,        tk.mybatis.mapper.common.base.delete.DeleteMapper<T>,        DeleteByPrimaryKeyMapper<T>,        DeleteByConditionMapper<T>,        DeleteByIdsMapper<T>{}

5>提供增删改查的基类 CommonMapper

package com.example.common.mapper.commonMapper;import com.example.common.mapper.basics.DeleteMapper;import com.example.common.mapper.basics.InsertMapper;import com.example.common.mapper.basics.SelectMapper;import com.example.common.mapper.basics.UpdateMapper;public interface CommonMapper<T> extends        DeleteMapper<T>,        InsertMapper<T>,        SelectMapper<T>,        UpdateMapper<T> {}

6>实体对象

package com.example.dao.entity;import lombok.Data;import javax.persistence.Id;import javax.persistence.Table;import java.io.Serializable;@Table(name="user")@Datapublic class User implements Serializable {    @Id    private Integer id;    private String trueName;    private String userName;        private Integer isDeleted;}

7>让自定义mapper继承CommenMapper,就可以使用这些语句了

package com.example.dao.mapper;import com.example.common.mapper.commonMapper.CommonMapper;import com.example.dao.entity.User;public interface UserMapper extends CommonMapper<User> {}

接下来我们会对 CommonMapper中提供删除方法的DeleteMapper进行增强,来给他添加逻辑删除的语句

1>我们自定义的Provider需要去继承 MapperTemplate并覆写构造方法

这个是源码中的批量删除

//// Source code recreated from a .class file by IntelliJ idea// (powered by Fernflower decompiler)//package tk.mybatis.mapper.provider;import java.util.Set;import org.apache.ibatis.mapping.MappedStatement;import tk.mybatis.mapper.MapperException;import tk.mybatis.mapper.entity.EntityColumn;import tk.mybatis.mapper.mapperhelper.EntityHelper;import tk.mybatis.mapper.mapperhelper.MapperHelper;import tk.mybatis.mapper.mapperhelper.MapperTemplate;import tk.mybatis.mapper.mapperhelper.SqlHelper;public class IdsProvider extends MapperTemplate {    public IdsProvider(Class<?> mapperClass, MapperHelper mapperHelper) {        super(mapperClass, mapperHelper);    }    public String deleteByIds(MappedStatement ms) {        Class<?> entityClass = this.getEntityClass(ms);        StringBuilder sql = new StringBuilder();        sql.append(SqlHelper.deleteFromTable(entityClass, this.tableName(entityClass)));        Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);        if (columnList.size() == 1) {            EntityColumn column = (EntityColumn)columnList.iterator().next();            sql.append(" where ");            sql.append(column.getColumn());            sql.append(" in (${_parameter})");            return sql.toString();        } else {            throw new MapperException("继承 deleteByIds 方法的实体类[" + entityClass.getCanonicalName() + "]中必须只有一个带有 @Id 注解的字段");        }    }    public String selectByIds(MappedStatement ms) {        Class<?> entityClass = this.getEntityClass(ms);        this.setResultType(ms, entityClass);        StringBuilder sql = new StringBuilder();        sql.append(SqlHelper.selectAllColumns(entityClass));        sql.append(SqlHelper.fromTable(entityClass, this.tableName(entityClass)));        Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);        if (columnList.size() == 1) {            EntityColumn column = (EntityColumn)columnList.iterator().next();            sql.append(" where ");            sql.append(column.getColumn());            sql.append(" in (${_parameter})");            return sql.toString();        } else {            throw new MapperException("继承 selectByIds 方法的实体类[" + entityClass.getCanonicalName() + "]中必须只有一个带有 @Id 注解的字段");        }    }}

接下来我们对IdsProvider 进行扩展使他支持批量逻辑删除

1>创建IdsProvider的子类

package com.example.common.mapper.defined;import org.apache.ibatis.mapping.MappedStatement;import tk.mybatis.mapper.MapperException;import tk.mybatis.mapper.entity.EntityColumn;import tk.mybatis.mapper.mapperhelper.EntityHelper;import tk.mybatis.mapper.mapperhelper.MapperHelper;import tk.mybatis.mapper.mapperhelper.SqlHelper;import tk.mybatis.mapper.provider.IdsProvider;import java.util.Set;public class IdsProviderDefined extends IdsProvider {    public IdsProviderDefined(Class<?> mapperClass, MapperHelper mapperHelper) {        super(mapperClass, mapperHelper);    }    public String deleteShamByIds(MappedStatement ms) {        Class<?> entityClass = this.getEntityClass(ms);        StringBuilder sql = new StringBuilder();        sql.append(SqlHelper.updateTable(entityClass, this.tableName(entityClass)));        sql.append("<set> is_deleted='1' </set>");        Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);        if (columnList.size() == 1) {            EntityColumn column = (EntityColumn)columnList.iterator().next();            sql.append(" where ");            sql.append(column.getColumn());            sql.append(" in (${_parameter})");            return sql.toString();        } else {            throw new MapperException("继承 deleteByIds 方法的实体类[" + entityClass.getCanonicalName() + "]中必须只有一个带有 @Id 注解的字段");        }    }}

deleteShamByIds就是我们门批量逻辑删除的方法,这个方法其实就是再拼装sql,tk中提供了很多帮助我们拼装sql,和参数的类(SqlHelper,EntityHelper),我们可以使用

2>创建DeleteShamByIdsMapper接口

package com.example.common.mapper.defined;import org.apache.ibatis.annotations.DeleteProvider;public interface DeleteShamByIdsMapper<T> {    @DeleteProvider(            type = IdsProviderDefined.class,            method = "dynamicSQL"    )    int deleteShamByIds(String var1);    //这里的抽象方法的名称必须和IdsProviderDefined 中的方法一致}

3>在DeleteMapper中继承我们自定义的逻辑删除接口DeleteShamByIdsMapper

package com.example.common.mapper.basics;import com.example.common.mapper.defined.DeleteShamByIdsMapper;import tk.mybatis.mapper.common.Marker;import tk.mybatis.mapper.common.base.delete.DeleteByPrimaryKeyMapper;import tk.mybatis.mapper.common.condition.DeleteByConditionMapper;import tk.mybatis.mapper.common.ids.DeleteByIdsMapper;public interface DeleteMapper<T> extends Marker,        tk.mybatis.mapper.common.base.delete.DeleteMapper<T>,        DeleteByPrimaryKeyMapper<T>,        DeleteByConditionMapper<T>,        DeleteByIdsMapper<T>,        DeleteShamByIdsMapper<T>{}

到这里我们自定义的批量逻辑删除就定义好了,我们可以通过这种方式扩展通用mapper。

TK mybatis插件通用mapper与oracle的几个坑

最近公司有几个项目的数据库用的oracle,有段时间没用,然后果断就掉坑里面了,记录几个比较有代表性的。

1:关于oracle的批量数据插入,我用TK通用mapper的insertList方法自动拼接出来的sql是这样的

insert  into table(column1,column2)values (value1,value2),(value3,value4)。。。

咋一看没啥问题啊,然后就一直报 sql未正确结束,出于对自己sql的过于自信,导致一直都在思考是否是参数问题,浪费了好几个小时,后来把sql拼好直接丢到数据库跑了跑才发现,这种sql确实是不能在oracle跑的,oracle批量插入的语法应该是:

INSERT ALL INTO A(field_1,field_2) VALUES (value_1,value_2) INTO A(field_1,field_2) VALUES (value_3,value_4) INTO A(field_1,field_2) VALUES (value_5,value_6)

粗略的瞅了下TK的代码,貌似确实没有校验数据库驱动就直接开始拼sql了

public String insertList(MappedStatement ms) {        Class<?> entityClass = this.getEntityClass(ms);        StringBuilder sql = new StringBuilder();        sql.append(SqlHelper.insertIntoTable(entityClass, this.tableName(entityClass)));        sql.append(SqlHelper.insertColumns(entityClass, true, false, false));        sql.append(" VALUES ");        sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" >");        sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");        Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);        Iterator var5 = columnList.iterator();        while(var5.hasNext()) {            EntityColumn column = (EntityColumn)var5.next();            if (!column.isId() && column.isInsertable()) {                sql.append(column.getColumnHolder("record") + ",");            }        }        sql.append("</trim>");        sql.append("</foreach>");        return sql.toString();    }

不过我觉得这种插件肯定是有兼容方案的,并且使用了这个插件跟使用源生mybatis并不冲突,所以实际对开发并没有影响,算是复习一下oracle的基础并提醒下自己,程序员还是老老实实先run起来,自以为是的经验有时候也很坑的。

2:关于oracle的比较符号(<> =)和null

先复习一下

一般数据库查询某某字段为空或者不为空的时候都是用is null或者is not null

如果查询条件使用=null或者<>null是查不出来数据的

但是赋值却可以用=null如

update BUS_PLATFORM.bus_trans set return_code = null where return_msg= 'tac验证通过';

这个是可以执行成功的,不过这个都是表外的值操作,那么当表内的数据有null时,又有啥坑呢,比如

select * from table1 where name <>'zhansan'

查询表中name字段不为zhangsan的数据,当表中有name为null的数据时,这些数据也是查不出来的.比如表中有100条数据,一条数据的name值为zhangsan ,九条数据的name值为null,那么这条sql只能查出90条数据,所以如果确切的需求要查询name值不为zhangsan的数据且包括name值为null的数据,sql应该为

select * from table1 where name <>'zhansan' or name is null

3:这个是mybatis的一个规范,基本是凑数的,不过也坑过我

先上内容:mybatis插入null值时需要指定该值的类型(jdbctype),不然会报错。

因为不指定类型的话mybatis会自己去适配匹配的数据库字段类型,null适配不了。搞不定就报错,很稳。不过一般使用xml配置sql的话一般都不会有这个问题,写的时候顺手都会写上。这个也是我使用TK的时候暴露出来的问题,在使用insert方法的时候有null就挂了,不过TK有个insertSelective方法做插入的时候会自动过滤掉空值。

看完了这篇文章,相信你对“tk.mybatis怎么扩展自己的通用mapper”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!

--结束END--

本文标题: tk.mybatis怎么扩展自己的通用mapper

本文链接: https://lsjlt.com/news/280087.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • tk.mybatis怎么扩展自己的通用mapper
    小编给大家分享一下tk.mybatis怎么扩展自己的通用mapper,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!tk.mybatis扩展自己的通用mapper目的:tk.mybatis 提供的通用mapper,虽然使用方...
    99+
    2023-06-15
  • tk.mybatis如何扩展自己的通用mapper
    tk.mybatis扩展自己的通用mapper 目的:tk.mybatis 提供的通用mapper,虽然使用方便,不过在有些sql还是不能满足我们的需要的,而且我们希望对于delet...
    99+
    2024-04-02
  • PHP怎么自定义扩展
    本篇内容主要讲解“PHP怎么自定义扩展”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PHP怎么自定义扩展”吧!利用源码工具自动生成扩展目录结构先进入php源码ext目录下执行下面命令/www/t...
    99+
    2023-06-22
  • tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新列怎么解决
    本篇内容介绍了“tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新列怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大...
    99+
    2023-06-21
  • ASP.NET Core扩展库之Http通用扩展库的使用详解
    目录一、开启服务端请求缓冲 二、请求头传递 三、请求头日志的记录 四、Http消息上的扩展方法 五、HttpClient上的扩展方法     ...
    99+
    2024-04-02
  • 怎么在ASP.NET中使用Http通用扩展库
    怎么在ASP.NET中使用Http通用扩展库?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。ASP.NET 是什么ASP.NET 是开源,跨平台,高性能,轻量级的 Web 应用构...
    99+
    2023-06-14
  • 怎么开通自己的小程序?
    怎么开通自己的小程序 创建自己小程序方法如下:微信版本升级后,打开微信,点击底部的“发现”这个菜单项,就会发现升级后的“发现”菜单里,增加了“小程序”这样一个功能。 第一步:百度“微信微信官方账号”,进入微信微信官方账号平台注册页面,点击...
    99+
    2023-10-07
    小程序 微信小程序 微信
  • jquery怎么扩展自定义方法
    要扩展自定义方法,可以使用jQuery的`$.fn`命名空间。下面是一个简单的示例:```javascript// 扩展自定义方法$...
    99+
    2023-08-12
    jquery
  • 使用cluster 将自己的Node服务器扩展为多线程服务器
    用nodejs的朋友都有了解,node是单线程的,也就是说跑在8核CPU上,只能使用一个核的算力。 单线程一直是node的一个诟病,但随着0.6版本中引入cluster之后,这个情况则得到了改变,开发人员可...
    99+
    2022-06-04
    自己的 服务器 多线程
  • Eclipse扩展点怎么用
    小编给大家分享一下Eclipse扩展点怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Eclipse中提供了几个扩展点,方便扩展重构功能。基本的重构功能有,R...
    99+
    2023-06-17
  • 怎么使用Laravel World的扩展
    本篇内容介绍了“怎么使用Laravel  World的扩展”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Laravel World...
    99+
    2023-06-25
  • tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新列的解决办法
    tk.mybatis是一个很好用的通用插件,把CRUD这些基本的数据操作全都用动态SQL语句自动生成了,mapper和xml里十分清爽,但是昨天发现有一个小坑,记录在此: 有一张表,...
    99+
    2024-04-02
  • Linux下怎么通过Gogs搭建自己的Github
    随着Github的逐渐普及,越来越多的人会选择在其中建立自己的项目,也就是在Github上发表自己的代码。然而,Github限制了单个账户上能建立的私人库的数量,所以一些高频使用者可能需要通过其他途径来建立自己的代码库。在这个时候,自己搭建...
    99+
    2023-10-22
  • 怎么自定义一个jQuery扩展接口
    这篇文章给大家介绍怎么自定义一个jQuery扩展接口,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。jQuery是一款很优秀的轻量级JavaScript框架,有其独特的优点。很多Web开...
    99+
    2024-04-02
  • 怎么使用Kotlin来扩展
    今天小编给大家分享一下怎么使用Kotlin来扩展的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。实际上客户早在去年年初的时候便...
    99+
    2023-06-17
  • 怎么开发一个MyBatis通用Mapper的轮子
    本篇内容介绍了“怎么开发一个MyBatis通用Mapper的轮子”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!需求通用Mapper起码应该包...
    99+
    2023-07-04
  • CSS的扩展选择器怎么用
    这篇文章主要介绍了CSS的扩展选择器怎么用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇CSS的扩展选择器怎么用文章都会有所收获,下面我们一起来看看吧。1、关联选择器<d...
    99+
    2024-04-02
  • 怎么使用PHP中的runkit扩展
    小编给大家分享一下怎么使用PHP中的runkit扩展,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一起学习PHP的runkit扩展如何使用在 PHP 运行的时候,...
    99+
    2023-06-15
  • ECMAscrip函数的扩展怎么使用
    本篇内容主要讲解“ECMAscrip函数的扩展怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ECMAscrip函数的扩展怎么使用”吧!1.函数参数的默认值1.1函数参数指定默认值在ECM...
    99+
    2023-06-21
  • 轻松掌握PHP扩展开发技巧:创建你自己的PHP模块
    准备工作 在开始开发PHP模块之前,你需要确保已经满足以下条件: 你已经安装了PHP开发环境。 你熟悉PHP语言。 你了解PHP扩展的原理。 创建PHP模块 创建一个PHP模块的步骤如下: 打开你的文本编辑器,创建一个新文件。 在...
    99+
    2024-02-11
    PHP模块 扩展开发 开发技巧
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作