Tk.Mybatis的使用


一 序言:

      不知各位程序君在开发过程中, 是否依旧在Mapper.xml中追加不同where的select语句的道路上痛苦前行 ? 是否还在因手动编写select语句因字段名写错或者逗号等手残问题造成项目报错而烦恼吗 ? 是否还在一个个手动创建实体类而挑灯夜战熬夜加班嘛 ? 各位亲接下来本猿将为大家带来一个终极智能好帮手来解决上述苦苦煎熬广大小伙伴的开发问题 !

二 tk.mybatis插件的使用 :

      注意: 本文主要讲解如何在springboot项目中使用tk.mybatis来简化 service和dao层的单表操作,达到在service和dao层的单表操作零代码实现,以及自动创建实体类 !

1. 在项目的pom.xml文件中引入 mapper-spring-boot-starter 依赖,该依赖会自动引入 MyBaits 相关依赖

<dependency>

        <groupId>tk.mybatis</groupId>

        <artifactId>mapper-spring-boot-starter</artifactId>

        <version>2.0.2</version>

    </dependency>

2. 在pom.xml 中添加mybatis-generator-maven-plugin 插件

该插件是 MyBatis 的 Maven 插件用于自动生成实体类,Mapper接口和mapper.xml文件

<build>

    <plugins>

        <plugin>

            <groupId>org.mybatis.generator</groupId>

            <artifactId>mybatis-generator-maven-plugin</artifactId>

            <version>1.3.5</version>

            <configuration>

                <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>

                <overwrite>true</overwrite>

                <verbose>true</verbose>

            </configuration>

            <dependencies>

                <dependency>

                    <groupId>mysql</groupId>

                    <artifactId>mysql-connector-java</artifactId>

                    <version>${mysql.version}</version>

                </dependency>

                <dependency>

                    <groupId>tk.mybatis</groupId>

                    <artifactId>mapper</artifactId>

                    <version>3.4.4</version>

                </dependency>

            </dependencies>

        </plugin>

    </plugins>

</build>

3. 设置 mybatis-generator-maven-plugin 插件自动生成代码配置

在  src/main/resources下新建generator目录,然后在generator目录下在新建一个generatorConfig.xml文件,然后在该文件中配置自动生成代码的相关详情 --- 注意该配置文件中的数据库连接池配置根据个人项目实际情况去配置,本人这里使用的是国产数据库金仓,

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE generatorConfiguration

        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"

        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!-- 引入数据库连接配置 -->

    <context id="KingbaseES8" targetRuntime="MyBatis3Simple" defaultModelType="flat">

        <property name="beginningDelimiter" value="`"/>

        <property name="endingDelimiter" value="`"/>

        <!-- 配置 tk.mybatis 插件 -->

        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">

            <property name="mappers" value="com.beyondbit.ias.bclproject.common.MyMapper"/>

        </plugin>

        <!-- 配置数据库连接 -->

        <jdbcConnection

                driverClass="com.kingbase8.Driver"

                connectionURL="jdbc:kingbase8://31.0.37.96:54321/DBIT_XH"

                userId="system"

                password="System#1234">

        </jdbcConnection>

        <!-- 配置实体类存放路径 -->

        <javaModelGenerator targetPackage="com.beyondbit.ias.bclproject.entity" targetProject="src/main/java">

            <!--  for MyBatis3/MyBatis3Simple

          自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter;

      -->

            <property name="constructorBased" value="false"/>

            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->

            <property name="enableSubPackages" value="true"/>

            <!-- for MyBatis3 / MyBatis3Simple

                是否创建一个不可变的类,如果为true,

                那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类

            -->

            <property name="immutable" value="false"/>

            <!-- 设置一个根对象,

                如果设置了这个根对象,那么生成的keyClass或者recordClass会继承这个类;在Table的rootClass属性中可以覆盖该选项

                注意:如果在key class或者record class中有root class相同的属性,MBG就不会重新生成这些属性了,包括:

                    1,属性名相同,类型相同,有相同的getter/setter方法;

            -->

            <property name="BaseEntity" value="com.beyondbit.ias.bclproject.entity"/>

            <!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->

            <property name="trimStrings" value="true"/>

        </javaModelGenerator>

        <!-- 配置 XML 存放路径 -->

        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>

        <!-- 配置 DAO 存放路径 -->

        <javaClientGenerator

                targetPackage="com.beyondbit.ias.bclproject.dao"

                targetProject="src/main/java"

                type="XMLMAPPER">

            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->

            <property name="enableSubPackages" value="true"/>

        </javaClientGenerator>

        <!-- 配置需要指定生成的数据库和表,% 代表所有表 -->

        <table catalog="DBIT_XH" tableName="OA_%">

            <!-- 默认为false,如果设置为true,在生成的SQL中,table名字不会加上catalog或schema; -->

            <property name="ignoreQualifiersAtRuntime" value="false"/>

        </table>

    </context>

</generatorConfiguration>

4. 在application.yml中配置mybatis

mybatis:

    type-aliases-package: //实体类的存放路径,如:com.beyondbit.ias.*.entity

    mapper-locations: classpath:mapper/*.xml 

    configuration:

      map-underscore-to-camel-case: true //开启驼峰功能

      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl //sql控制台打印

    configuration-properties: { dbSchema: DBIT_BCLPROJECT. } //配置数据库的模式

5. 创建一个通用的父级MyMapper接口

注意: 该父级Mapper接口包含了大部分的单表操作的方法,通过让dao层所有mapper接口继承该父级MyMapper接口,便可以让所有的dao层mapper接口自动继承来自MyMapper中的所有单表操作方法。这样我们就可以做到dao层接口单表操作的绝大部分场景零代码实现。---- 特别注意该接口千万不能被mapperScan扫描到

package com.funtl.utils;

import tk.mybatis.mapper.common.Mapper;

import tk.mybatis.mapper.common.MySqlMapper;

/**

* MyMapper 作为tk.mybatis提供的通用mapper父级接口

* 特别注意,该接口不能被@mapperScan注解的路径扫描到,否则会出错

* <p>Title: MyMapper</p>

* <p>Description: </p>

*

* @author wangchengkai

* @version 1.0.0

* @date 2020/11/25 0:17

*/

public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {

}

6. 利用插件执行自动生成代码 (实体类/mapper接口和mapper.xml代码)

(1) 方式一  :  打开idea或者eclipse的Terminal 终端输入的命令  mvn mybatis-generator:generate  回车

(2) 方式二 : 进入项目根目录文件然后cmd进入终端 输入命令 mvn mybatis-generator:generate  回车

(2) 方式三 : 利用idea的maven 插件通过双击 执行自动生成代码


代码自动生成成功----当出现BUILD SUCCESS时表示代码自动生成成功,这时你就可以看到项目中已经生成的实体类, mapper 接口和mapper.xml文件了



7. 在启动类中添加dao层接口的扫描路径 @MapperScan(basePackages = "com.xxx.*.dao")

注意: 该 @MapperScan import使用的是 import tk.mybatis.spring.annotation.MapperScan;

8. 在所有的实体类上的@Table注解中加入schema属性


9 . 创建通用的MyService接口和实现

通过上面的操作我们的所有实体类和mapper.xml以及dao层接口均已自动生成,并且dao层的所有接口均已继承MyMapper通用父级接口获取了所有单表操作的封装方法,此时我们的dao层单表操作既可以做到零代码实现了 !在spring mvc架构中我们知道控制器controller调用service,service调用mapper接口, 此时mapper接口以及通过父级MyMapper接口完成了统一的单表操作封装。 那么接下来我们就对service层做统一封装, 实现service层单表操作的零代码 。 ------ 在你项目的common(或者utils,亦或者service)的package新建一个MyService接口和MyServiceImpl实现类(类名根据个人爱好)

新建service层所有接口的父级service

packagecom.beyondbit.ias.bclproject.common;

importcom.github.pagehelper.PageInfo;

importtk.mybatis.mapper.entity.Example;

importjava.util.List;

/**

* BaseService 作为sevice层提供的通用service父级接口

* @author wangchengkai

* @version 1.0.0

* @date 2020/11/25 0:20

*/

public interface MyService<T>{

/**

* 根据实体类中不为空的字段作为where语句的条件使用=号

* @param var1

* @return 返回查询列表

*/

List<T>select(Tvar1);

/**

* 根据实体类中不为空的字段作为where语句的条件使用=号

* @param var1

* @return 一个实体

*/

TselectOne(Tvar1);

/**

* 根据实体类中不为空的字段作为where语句的条件使用=号

* @param var1

* @return 按条件查询的统计条数

*/

intselectCount(Tvar1);

/**

* 根据实体类中的主键id作作为where语句的查询条件

* ---注意实体类中的主键必须加@ID注解此方法才生效

* @param var1

* @return 返回根据主键id查询到的实体

*/

TselectByPrimaryKey(Objectvar1);

/**

* 自定义条件查询

* @param example

* @return 返回根据自定义查询条件/排序/分组/分页/去重....等获取到的列表

*/

List<T>selectByExample(Exampleexample);

/**

* 查询表中的所有数据

* @param

* @return 返回表中的所有数据

*/

List<T>selectAll();

/**

* 分页查询表中的所有数据

* @param

* @return 返回分页查询到的表中的所有数据

*/

PageInfo<T>selectAllPage(IntegerpageNum,IntegerpageSize);

/**

* 根据主键查询该数据是否存在

* @param

* @return 存在true 不存在false

*/

booleanexistsWithPrimaryKey(Tvar1);


/**

* 根据主键作为where查询条件修改数据(此方法当实体类中的属性为null时会将数据库中队一个的字段也修改为null)

* 个人不怎么推荐使用本方法 ---注意实体类中的主键必须加@ID注解此方法才生效

* @param

* @return 存在true 不存在false

*/

intupdateByPrimaryKey(Tvar1);

/**

* 根据主键作为where查询条件修改数据(此方法只修改实体类中不为null属性所对应的字段)

* 个人强烈推荐使用本方法修改数据 ---注意实体类中的主键必须加@ID注解此方法才生效

* @param

* @return 存在true 不存在false

*/

intupdateByPrimaryKeySelective(Tvar1);

/**

* 插入数据(实体类中为null属性所对应的字段也设置为null不会使用默认值)

* @param

* @return 存在true 不存在false

*/

intinsert(Tvar1);

/**

* 插入数据(实体类中为null属性所对应的字段会使用默认值)

* 个人强烈推荐使用本方法新增数据

* @param

* @return 存在true 不存在false

*/

intinsertSelective(Tvar1);

/**

* 删除数据(实体类中属性非空字段作为where 查询的条件 用and 拼接)

* @param

* @return  

*/

intdelete(Tvar1);

/**

* 根据主键删除数据 ---注意实体类中的主键必须加@ID注解此方法才生效

* @param

* @return

*/

intdeleteByPrimaryKey(Tvar1);


PageInfo<T>selectPage(IntegerpageNum,IntegerpageSize,Tvar1);

}

 让service层所有的接口继承该父级BaseService

新建service层所有接口的父级接口

package com.beyondbit.ias.bclproject.common;

import com.github.pagehelper.PageHelper;

import com.github.pagehelper.PageInfo;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.transaction.annotation.Transactional;

import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.ParameterizedType;

import java.util.List;

/**

* BaseServiceImpl 作为sevice层提供的通用service实现类的父级类

* @author wangchengkai

* @version 1.0.0

* @date 2020/11/25 0:20

*/

public abstract class MyServiceImpl<T, E extends MyMapper<T>> implements MyService<T> {

    @Autowired

    private E dao;

    /**

    * 当前泛型真实类型的Class

    */

    private Class<T> modelClass;

    public MyServiceImpl() {

        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();

        modelClass = (Class<T>) pt.getActualTypeArguments()[0];

    }

    @Override

    public List select(T var1) {

        return dao.select(var1);

    }

    @Override

    public T selectOne(T var1) {

        return dao.selectOne(var1);

    }

    @Override

    public int selectCount(T var1) {

        return dao.selectCount(var1);

    }

    @Override

    public T selectByPrimaryKey(Object var1) {

        return dao.selectByPrimaryKey(var1);

    }

    @Override

    public List selectAll() {

        return dao.selectAll();

    }

    @Override

    public PageInfo<T> selectAllPage(Integer pageNum, Integer pageSize) {

        PageHelper.startPage(pageNum == null ? 0 : pageNum, pageSize == null ? 0 : pageSize);

        PageInfo<T> pageInfo = new PageInfo<T>(dao.selectAll());

        return pageInfo;

    }

    @Override

    public PageInfo<T> selectPage(Integer pageNum, Integer pageSize, T var1) {

        PageHelper.startPage(pageNum == null ? 0 : pageNum, pageSize == null ? 0 : pageSize);

        PageInfo<T> pageInfo = new PageInfo<T>(dao.select(var1));

        return pageInfo;

    }

    @Override

    public boolean existsWithPrimaryKey(Object var1) {

        return dao.existsWithPrimaryKey(var1);

    }

    @Override

    @Transactional

    public int updateByPrimaryKey(T var1) {

        return dao.updateByPrimaryKey(var1);

    }

    @Override

    @Transactional

    public int updateByPrimaryKeySelective(T var1) {

        return dao.updateByPrimaryKeySelective(var1);

    }

    @Override

    public List selectByExample(Example example) {

        return dao.selectByExample(example);

    }

    @Override

    @Transactional

    public int insert(T var1) {

        return dao.insert(var1);

    }

    @Override

    @Transactional

    public int insertSelective(T var1) {

        return dao.insertSelective(var1);

    }

    @Override

    @Transactional

    public int delete(T var1) {

        return dao.delete(var1);

    }

    @Override

    @Transactional

    public int deleteByPrimaryKey(Object var1) {

        return dao.deleteByPrimaryKey(var1);

    }

}

让service层所有的实现类继承该父级 MyServiceImpl 然后实现自己本身的service接口


10. 测试

11. 查询测试成功! 那么我们可以看一下service层和dao层的代码

12. tk.mybatis先关通用api详情


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容