国人开发的Mybatis小工具-通用Mapper和PageHelper

通用Mapper

通用Mapper与Pagehelper是一位国内大神写的简化Mybatis开发的两项技术,通用Mapper配合ORM映射注解可以做到不写sql语句和mapper方法,而Pagehelper可以简化分页操作。

作者的github: https://github.com/abel533

作者的博客: https://blog.csdn.net/isea533

本文参考于作者提供的使用文档。

使用

依赖:

<!-- 通用mapper -->
<dependency>
  <groupId>tk.mybatis</groupId>
  <artifactId>mapper-spring-boot-starter</artifactId>
  <version>2.1.5</version>
</dependency>
<!-- Mybatis-starter -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- JPA注解 -->
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0</version>
    <scope>compile</scope>
</dependency>
  • 为所有的mapper接口添加@Mapper注解
  • 配置类添加@MapperScan注解

例如:直接在启动类上标注Mapper扫描包

@MapperScan(basePackages = {"com.rhett.dao"})
public class GoodsApplication {
    public static void main(String[] args) {
        SpringApplication.run(GoodsApplication.class, args);
    }
}

ORM映射注解

通用 Mapper 使用一部分 JPA 注解和自己提供的注解来实现对象关系映射

Id

最简单的情况下,只需要一个 @Id 标记字段为主键即可。数据库中的字段名和实体类的字段名是完全相同的,这中情况下实体和表可以直接映射。

假设有一数据库表:

CREATE TABLE `country` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `countryname` varchar(255) DEFAULT NULL COMMENT '名称',
  `countrycode` varchar(255) DEFAULT NULL COMMENT '代码',
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=10011 DEFAULT CHARSET=utf8 COMMENT='国家信息';

对应java实体类:

public class Country {
    @Id
    private Integer id;
    private String  countryname;
    private String  countrycode;

    //省略 getter 和 setter
}

NameStyle

@NameStyle在类上进行配置,表示字段名的映射风格,它的取值在Style中枚举,共有:

  • normal 原值
  • camelhump 驼峰转下划线
  • uppercase 转换为大写
  • lowercase 转换为小写
  • camelhumpAndUppercase 驼峰转下划线大写形式
  • camelhumpAndLowercase 驼峰转下划线小写形式

例:

@NameStyle(Style.camelhumpAndUppercase)
public class Country

Table

指定对应的表名,没配置时按类名自动转换

例:

@Table(name = "sys_user")
public class User

Column

指定对应的字段映射名,没配置时默认和字段名相同

例:

@Column(name = "user_name")
private String name;

Transient

一般情况下,实体中的字段和数据库表中的字段是一一对应的,但是也有很多情况我们会在实体中增加一些额外的属性,这种情况下,就需要使用 @Transient 注解来告诉通用 Mapper 这不是表中的字段。

默认情况下,只有简单类型会被自动认为是表中的字段。

这里的简单类型不包含 Java 中的8种基本类型:

byte,short,int,long,float,double,char,boolean

这是因为在类中,基本类型会有默认值,而 MyBatis 中经常会需要判断属性值是否为空,所以不要在类中使用基本类型,否则会遇到莫名其妙的错误。

对于类中的复杂对象,以及 Map,List 等属性不需要配置这个注解。

使用Mapper

则先写一个Mapper接口,要继承tk.mybatis.mapper.common.Mapper,该类有很多代表数据库操作的方法:

import tk.mybatis.mapper.common.Mapper;

public interface CountryMapper extends Mapper<Country> {
}

从 MyBatis 中获取该接口后就可以直接使用:

//从 MyBatis 或者 Spring 中获取 countryMapper,然后调用 selectAll 方法
List<Country> countries = countryMapper.selectAll();
//根据主键查询
Country country = countryMapper.selectByPrimaryKey(1);
//或者使用对象传参,适用于1个字段或者多个字段联合主键使用
Country query = new Country();
query.setId(1);
country = countryMapper.selectByPrimaryKey(query);

自定义方法实现

如果想要增加自己写的方法,可以直接在 CountryMapper 中增加。

纯接口注解方式

import org.apache.ibatis.annotations.Select;
import tk.mybatis.mapper.common.Mapper;

public interface CountryMapper extends Mapper<Country> {
    @Select("select * from country where countryname = #{countryname}")
    Country selectByCountryName(String countryname);
}

如果使用 XML 方式,需要提供接口对应的 XML 文件

例如提供了 CountryMapper.xml 文件,内容如下:

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tk.mybatis.sample.mapper.CountryMapper">
    <select id="selectByCountryName" resultType="tk.mybatis.model.Country">
        select * from country where countryname = #{countryname}
    </select>
</mapper>

在接口中添加对应的方法:

import tk.mybatis.mapper.common.Mapper;

public interface CountryMapper extends Mapper<Country> {
    Country selectByCountryName(String countryname);
}

在接口中添加其他方法的时候和只用 MyBatis 是完全一样的,但是需要注意,在对应的 XML 中,不能出现和继承接口中同名的方法!

PageHelper

介绍

PageHelper是基于Mybatis的插件机制开发的,Mybatis支持编写拦截器,在Mybatis的底层方法中进行拦截,如打印执行的SQL语句日志,做一些权限控制,分页等功能。

PageHelper就是通过拦截了Mybatis中Executor的query方法的执行,来实现查询时分页逻辑的添加。

拦截器部分源码:

@Intercepts(
{
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
}
)
public class PageInterceptor implements Interceptor {
    private volatile Dialect dialect;
    private String countSuffix = "_COUNT";
    protected Cache<String, MappedStatement> msCountMap = null;
    private String default_dialect_class = "com.github.pagehelper.PageHelper";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
    //...
    }

PageHelper的使用

引入依赖:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.13</version>
</dependency>

使用:

//第一个参数为页数,第二个参数为单页的条数
//第三个参数这里是根据stu_id降序排序
PageHelper.startPage(1,5,"stu_id desc");
//在startPage后面紧跟一个查询集合方法
List<Student> list = studentMapper.selectAll();

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/%e5%9b%bd%e4%ba%ba%e5%bc%80%e5%8f%91%e7%9a%84mybatis%e5%b0%8f%e5%b7%a5%e5%85%b7-%e9%80%9a%e7%94%a8mapper%e5%92%8cpagehelper/