@mapper注解的使用_Spring Boot 整合 MyBatis 通用 Mapper(TkMybatis)

aa1dbd29868b80b4c0f414b58c2307d0.gif

学习在 Spring Boot 中整合 MyBatis 通用 Mapper(TkMybatis)。通用 Mapper 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及 Example 相关的单表操作。通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。

1 概述

通用 Mapper 都可以极大的方便开发人员。可以随意的按照自己的需要选择通用方法,还可以很方便的开发自己的通用方法。

极其方便的使用 MyBatis 单表的增删改查。

支持单表操作,不支持通用的多表联合查询。

使用通用 Mapper 可以无 xml 文件实现数据库操作,只需要继承 TkMybatis 中相关的 Mapper 接口即可。但如果有特殊需求,可以自定义 XXXMapper.xml 文件,实现复杂 sql 语句的操作。

为什么需要通用 Mapper ?

我个人最早用 MyBatis 时,先是完全手写,然后用上了 MyBatis 代码生成器(简称为 MBG),在使用 MBG 过程中,发现一个很麻烦的问题,如果数据库字段变化很频繁,就需要反复重新生成代码,并且由于 MBG 覆盖生成代码和追加方式生成 XML,导致每次重新生成都需要大量的比对修改。除了这个问题外,还有一个问题,仅仅基础的增删改查等方法,就已经产生了大量的 XML 内容,还没有添加一个自己手写的方法,代码可能就已经几百行了,内容多,看着比较碍事。

因为很多人都在使用 MBG,MBG 中定义了很多常用的单表方法,为了解决前面提到的问题,也为了兼容 MBG 的方法避免项目重构太多,在 MBG 的基础上结合了部分 JPA 注解产生了通用 Mapper。通用 Mapper 可以很简单的让你获取基础的单表方法,也很方便扩展通用方法。使用通用 Mapper 可以极大的提高你的工作效率。

说明:我们也可以改造 MBG ,比如自动生成一套基本的 model/mapper/service 等,与表对应,不去做修改,自定义的都写在对应的另一个子类上,这样,当表字段修改后,只需全部重新生成上述基本的那些文件,再手动修改自定义的文件(如果有需要)即可。

2 基本使用

  1. 创建项目,引入依赖

创建 Spring Boot 项目 spring-boot-mybatis-tkmybatis ,添加 Web/MySQL Driver 依赖,如下:

b1db7be6ac38dafc4952bd54be56f131.png

之后手动在 pom 文件中添加 Druid/ 依赖(Spring Boot 版本),最终的依赖如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>druid-spring-boot-starterartifactId>
        <version>1.1.10version>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <scope>runtimescope>
        <version>5.1.27version>
    dependency>
    <dependency>
        <groupId>tk.mybatisgroupId>
        <artifactId>mapper-spring-boot-starterartifactId>
        <version>2.1.5version>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintagegroupId>
                <artifactId>junit-vintage-engineartifactId>
            exclusion>
        exclusions>
    dependency>
dependencies>

接着在 application.properties 配置文件中添加数据库相关信息的配置,如下:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=000000
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cxy35?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&autoReconnectForPools=true

  1. 新建实体类

手动新建或用代码生成器生成 User 实体类,并增加相关注解,如下:

@Table(name = "t_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "JDBC")
    private Integer id;
    private String username;
    private String password;
    private Boolean enabled;
    private Boolean locked;
    // @Column(name = "c_address")
    private String address;
    private String nickName;
    private Date createTime;
    private Date updateTime;

    // getter/setter
}

注解说明:

  • @Table:指定该实体类对应的表名,如果表名为 t_user ,类名为 TUser ,则可以不需要此注解(默认驼峰命名规则)。
  • @Column:指定该属性对应的列名,如果列名为 create_time ,属性名为 createTime ,则可以不需要此注解(默认驼峰命名规则)。
  • @Id:标识该字段对应数据库表的主键 id 。
  • @GeneratedValue:指定主键 id 生成规则,其中 strategy 表示使用数据库自带的主键生成策略, generator 配置为"JDBC",在数据插入完毕之后,会自动将主键id填充到实体类中,类似普通 mapper.xml 中配置的 selectKey 标签。

  1. 新建 Mapper 接口
public interface UserMapper extends Mapper<User> {
}

这里继承 TkMybatis 中最基本的一个通用 Mapper 接口,这样就自动拥有了这个 Mapper 中的一些接口,不用写 XXXMapper.xml 文件。

相关接口如下:

5341b7f95edf3ca8747a8162bf5b8dfb.png

除了 Mapper 接口,官方还提供了一些几个好用的通用 Mapper 接口,都可以用来继承使用,汇总如下:

  • Mapper 接口:
9669f844f41f6cec1522be10fdd10b31.png

IdsMapper 接口:

19fe9b59d0f2a60b1820f24f21aca0a1.png

ConditionMapper 接口:

377dd82449acb61998605b078e1c19b8.png
  • MySqlMapper 接口:
004135901bdf90e43463e96c82477b78.png
  • SqlServerMapper 接口:
ed7c4a0827541f8152875e68b4aabcce.png

当然,我们也可以根据自己的实际业务需求,抽取通用业务逻辑,自定义通用 Mapper 接口,参考 通用 Mapper 进阶实例:为什么好久都没更新了? 。

  1. 配置 Mapper 接口的扫描

可以在启动类上或自定义 MyBatis 的配置类上,通过 @MapperScan 注解配置。

@SpringBootApplication
@tk.mybatis.spring.annotation.MapperScan(basePackages = "com.cxy35.sample.springboot.mybatis.tkmybatis.mapper")
public class SpringBootMybatisTkmybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootMybatisTkmybatisApplication.class, args);
    }

}

  1. 测试

在测试类中注入 UserMapper 完成测试,如下:

@SpringBootTest
class SpringBootMybatisTkmybatisApplicationTests {

    @Autowired
    UserMapper userMapper;

    @Test
    public void insertSelective() {
        User user = new User();
        user.setUsername("zhangsan");
        user.setPassword("123456");
        user.setAddress("杭州");
        user.setNickName("zs");
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        userMapper.insertSelective(user);
    }

    @Test
    public void deleteByPrimaryKey() {
        userMapper.deleteByPrimaryKey(2);
    }

    @Test
    public void updateByPrimaryKeySelective() {
        User user = new User();
        user.setId(1);
        user.setUsername("zhangsan2");
        user.setPassword("654321");
        user.setNickName("zs2");
        user.setAddress("上海");
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Test
    public void selectAll() {
        List users = userMapper.selectAll();
        System.out.println(users);
    }@Testpublic void selectByExample() {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLike("username", "zhangsan%");
        criteria.andEqualTo("address", "杭州");
        List users = userMapper.selectByExample(example);
        System.out.println(users);
    }
}

3 自定义 XXXMapper.xml(非必须)

虽然大多数复杂的需求,都能通过 TkMyBatis 的组合完成操作。但如果有特殊需求,可以自定义 XXXMapper.xml 文件,实现复杂 sql 语句的操作,这里以联表查询为例。

UserMapper.java 所在包下新建 UserMapper.xml ,增加如下内容:

<?xml  version="1.0" encoding="UTF-8" ?>
mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.cxy35.sample.springboot.mybatis.tkmybatis.mapper.UserMapper">
    <select id="selectByRoleId" parameterType="java.lang.Integer" resultType="com.cxy35.sample.springboot.mybatis.tkmybatis.pojo.User">
        SELECT
            u.*
        FROM
            t_user u
        INNER JOIN t_user_role ur ON u.id = ur.user_id
        WHERE
            ur.role_id = #{roleId, jdbcType=INTEGER};
    select>
mapper>

上述 xml 文件与普通 xml 文件的不同之处在于:这里不需要使用 resultMap 进行字段的映射。当然,如果想在返回的 Map 中新增返回字段映射,直接添加新的字段即可。

注意:不要在 xml 文件中写 TkMyBatis 中已经有的一些基础方法,否则会报错,提示方法重复。

接着,修改 UserMapper.java ,增加对应的接口:

public interface UserMapper extends Mapper<User> {
    // 测试用,非必须
    List selectByRoleId(Integer roleId);
}

上述 UserMapper.xml 放在 UserMapper.java 所在的包下面,会被自动扫描到。但在项目打包时会被忽略掉,因此需要在 pom.xml 中配置 Maven 构建时的资源路径。

<build>
    <resources>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.xmlinclude>
            includes>
        resource>
        <resource>
            <directory>src/main/resourcesdirectory>
        resource>
    resources>
build>

关于 XXXMapper.xml 文件位置,还有其他方案,这里不再赘述,具体可参考 Spring Boot 整合 MyBatis 。

最后在测试类中增加方法,完成测试:

@Test
public void selectByRoleId() {
    List users = userMapper.selectByRoleId(2);
    System.out.println(users);
}

4 代码生成器插件

  • 通用 Mapper 插件:tk.mybatis.mapper.generator.MapperPlugin ,可以生成带 @Table/@Id/@Column 等注解的实体类,方便自动与数据库字段进行映射。
  • 通用代码生成器插件:tk.mybatis.mapper.generator.TemplateFilePlugin ,实际上是对 MyBatis Generator 的一个扩展,使用这个扩展可以很方便的使用 Freemarker 模板语言编写代码。

首先,在 pom.xml 中增加 MBG 的依赖(因为基于 MBG 插件)和通用 Mapper 的插件依赖,如下:

<dependency>
    <groupId>org.mybatis.generatorgroupId>
    <artifactId>mybatis-generator-coreartifactId>
    <version>1.3.7version>
dependency>
<dependency>
    <groupId>tk.mybatisgroupId>
    <artifactId>mapper-generatorartifactId>
    <version>1.1.5version>
dependency>

接着,在 src/main/resources 目录下新建 generatorConfig.xml 文件,用于配置代码生成器。

generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    
    <properties resource="application.properties"/>

    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <property name="javaFileEncoding" value="UTF-8"/>
        
        

        
        
        
        

        
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            
            <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
            
            <property name="caseSensitive" value="true"/>
            
            <property name="forceAnnotation" value="true"/>
            
            <property name="generateColumnConsts" value="true"/>
            
            
            
            <property name="beginningDelimiter" value="`"/>
            <property name="endingDelimiter" value="`"/>
            
            
            
            
            
            
        plugin>

        
        
        

        
        

        
        <jdbcConnection driverClass="${spring.datasource.driver-class-name}"connectionURL="${spring.datasource.url}"userId="${spring.datasource.username}"password="${spring.datasource.password}">
            
            <property name="nullCatalogMeansCurrent" value="true" />
        jdbcConnection>

        
        <javaModelGenerator targetPackage="com.cxy35.sample.springboot.mybatis.tkmybatis.mbg.model" targetProject="spring-boot-dao/spring-boot-mybatis-tkmybatis/src/main/java"/>

        
        <javaClientGenerator targetPackage="com.cxy35.sample.springboot.mybatis.tkmybatis.mbg.mapper" targetProject="spring-boot-dao/spring-boot-mybatis-tkmybatis/src/main/java" type="XMLMAPPER"/>

        
        
        

        
        <table tableName="t_user">
            <generatedKey column="id" sqlStatement="JDBC"/>
        table>
        
    context>
generatorConfiguration>

最后,在 com.cxy35.sample.springboot.mybatis.tkmybatis 下新建 mbg 包,用来存放代码生成器相关配置代码和最终生成的业务代码。新建 Generator.java 如下:

public class Generator {

    public static InputStream getResourceAsStream(String path) {
        return Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
    }

    public static void main(String[] args) throws Exception {
        //MBG 执行过程中的警告信息
        List warnings = new ArrayList();//当生成的代码重复时,覆盖原代码boolean overwrite = true;//读取我们的 MBG 配置文件
        InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(is);
        is.close();
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);//创建 MBG
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);//执行生成代码
        myBatisGenerator.generate(null);//输出警告信息for (String warning : warnings) {
            System.out.println(warning);
        }
    }
}

运行上述 main 方法即可自动生成代码,分别如下:

  • TUser.java
@Table(name = "`t_user`")
public class TUser {
    /**
     * 主键id
     */
    @Id
    @Column(name = "`id`")
    @GeneratedValue(generator = "JDBC")
    private Integer id;

    /**
     * 用户名
     */
    @Column(name = "`username`")
    private String username;

    /**
     * 密码
     */
    @Column(name = "`password`")
    private String password;

    /**
     * 是否启用:1 启用;0 未启用
     */
    @Column(name = "`enabled`")
    private Boolean enabled;

    /**
     * 是否锁定:1 锁定;0 未锁定
     */
    @Column(name = "`locked`")
    private Boolean locked;

    /**
     * 地址
     */
    @Column(name = "`address`")
    private String address;

    /**
     * 昵称
     */
    @Column(name = "`nick_name`")
    private String nickName;

    /**
     * 创建时间
     */
    @Column(name = "`create_time`")
    private Date createTime;

    /**
     * 更新时间
     */
    @Column(name = "`update_time`")
    private Date updateTime;

    public static final String ID = "id";

    public static final String DB_ID = "id";

    public static final String USERNAME = "username";

    public static final String DB_USERNAME = "username";

    public static final String PASSWORD = "password";

    public static final String DB_PASSWORD = "password";

    public static final String ENABLED = "enabled";

    public static final String DB_ENABLED = "enabled";

    public static final String LOCKED = "locked";

    public static final String DB_LOCKED = "locked";

    public static final String ADDRESS = "address";

    public static final String DB_ADDRESS = "address";

    public static final String NICK_NAME = "nickName";

    public static final String DB_NICK_NAME = "nick_name";

    public static final String CREATE_TIME = "createTime";

    public static final String DB_CREATE_TIME = "create_time";

    public static final String UPDATE_TIME = "updateTime";

    public static final String DB_UPDATE_TIME = "update_time";

    // getter/setter
}
  • TUserMapper.java
public interface TUserMapper extends Mapper<TUser> {
}
  • TUserMapper.xml(非必须)
<?xml  version="1.0" encoding="UTF-8"?>
mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxy35.sample.springboot.mybatis.tkmybatis.mbg.mapper.TUserMapper">
  <resultMap id="BaseResultMap" type="com.cxy35.sample.springboot.mybatis.tkmybatis.mbg.model.TUser">
    
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="password" jdbcType="VARCHAR" property="password" />
    <result column="enabled" jdbcType="BIT" property="enabled" />
    <result column="locked" jdbcType="BIT" property="locked" />
    <result column="address" jdbcType="VARCHAR" property="address" />
    <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
  resultMap>
mapper>

扩展阅读:

  • Mybatis 通用 Mapper 代码生成器
  • 通用 Mapper 专用代码生成器
  • MyBatis Generator 详解

  • Spring Boot 教程合集(微信左下方阅读全文可直达)。
  • Spring Boot 教程合集示例代码:https://github.com/cxy35/spring-boot-samples
  • 本文示例代码:https://github.com/cxy35/spring-boot-samples/tree/master/spring-boot-dao/spring-boot-mybatis-tkmybatis
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值