⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 网络 「网易工程师-倪骏」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

什么是通用Mapper?

它是一个可以方便的使用Mybatis进行单表的增删改查优秀开源产品。它使用拦截器来实现具体的执行Sql,完全使用原生的Mybatis进行操作。在Github上标星5.9K!

为什么要用Mapper?

它提供了所有单表的基本增删改查方法,大大节省了我们书写基本mapper.xml的时间。尤其对于新工程和新表来说,极大的提高...

不客气的说,使用这个通用Mapper甚至能改变你对Mybatis单表基础操作不方便的想法,使用它你能简单的使用单表的增删改查,包含动态的增删改查。

同时,在代码结构合理的前提下,更换RDBMS也无须修改sql,只需修改部分配置即可实现。

如何使用Mapper?

先通过maven引入jar包:

<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>x.x.x</version>
</dependency>

添加配置文件:

配置方式分为Java编码方式和spring集成方式。

Java编码方式

MapperHelper mapperHelper = new MapperHelper();
//特殊配置
Config config = new Config();//具体支持的参数看后面的文档
config.setXXX(XXX);//设置配置
mapperHelper.setConfig(config);// 注册自己项目中使用的通用Mapper接口,这里没有默认值,必须手动注册
mapperHelper.registerMapper(Mapper.class);
//配置完成后,执行下面的操作
mapperHelper.processConfiguration(session.getConfiguration());
2). 纯Spring配置方式
<bean >
<property name="basePackage" value="com.isea533.mybatis.mapper"/>
<property name="properties">
<value>
mappers=tk.mybatis.mapper.common.Mapper </value>
</property>
</bean>

你没看错,就是这么配置的,注意这里是tk.mybatis.xxx,和MyBatis的唯一区别就是org.改成了tk.,方便修改和记忆。

通用Mapper的各项属性通过properties属性进行配置,如果默认配置就是一行mappers=tk.mybatis.mapper.common.Mapper时,可以不写,就会变成:

<bean >
<property name="basePackage" value="com.isea533.mybatis.mapper"/>
</bean>

继承通用Mapper接口(注意必须要加泛型):

@Repository
public interface MaterialDao extends Mapper<MaterialMeta>, InsertUseGeneratedKeysMapperr<MaterialMeta> {}
上图示例继承了Mapper和InsertUseGeneratedKeysMapper,则直接拥有了这2个接口的所有方法。

上图中实体类的写法示例:

@Table(name = "tb_helpcenter_material")
public class MaterialMeta {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String tags;
private Long classificationId;
private String platform;
private String lecturerName;
// Setters&Getters
}

实体类的规则:

1.表名默认使用类名,驼峰转下划线(只对大写字母进行处理),如UserInfo默认对应的表名为user_info。

2.表名可以使用@Table(name = "tableName")进行指定,对不符合第一条默认规则的可以通过这种方式指定表名.

3.字段默认和@Column一样,都会作为表字段,表字段默认为Java对象的Field名字驼峰转下划线形式.

4.可以使用@Column(name = "fieldName")指定不符合第3条规则的字段名

5.使用@Transient注解可以忽略字段,添加该注解的字段不会作为表字段使用.

6.建议一定是有一个@Id注解作为主键的字段,可以有多个@Id注解的字段作为联合主键.

7.默认情况下,实体类中如果不存在包含@Id注解的字段,所有的字段都会作为主键字段进行使用(这种效率极低).

8.实体类可以继承使用,可以参考测试代码中的tk.mybatis.mapper.model.UserLogin2类.

9.由于基本类型,如int作为实体类字段时会有默认值0,而且无法消除,所以实体类中建议不要使用基本类型.

10.@NameStyle注解,用来配置对象名/字段和表名/字段之间的转换方式,该注解优先于全局配置style,可选值:

另外,建议实体类的所有Field全部使用装箱类,不要使用基本类型。

id字段上的@GeneratedValue注解用来表示该表使用的主键策略类型。

使用Mybatis-Generator来生成实体类:

使用方法参见:http://ks.netease.com/blog?id=8920

关于主键策略

主键策略主要用于insert场景。通常情况下,可以不用设置表对象的主键策略。不设置时,默认会使用JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键。

你也可以以@GeneratedValue(generator = “”)的形式来指定主键策略命令。如:@GeneratedValue(strategy = GenerationType.IDENTITY

,generator = “select last_insert_id()”)等。

同时,可以根据实际需要,在全局配置中指定主键策略的执行ORDER。

用Mybatis-Generator生成实体类,并创建一个继承了Mapper接口的dao以后,还要写什么呢?

答案是不用了,可以直接用了

就像这样:

MaterialMeta materialMeta = ReflectUtil.convertObj(MaterialMeta.class, material, false);
materialMeta.setPlatform(platformStr);
materialDao.insertSelective(materialMeta);

还有这样:

Example example = new Example(MaterialMeta.class);
example.createCriteria().andEqualTo("classificationId", material.getClassificationId()).andEqualTo("deleted",
false);
example.orderBy("sort").desc();
PageHelper.startPage(1, 1);
List<MaterialMeta> materialMetas = materialDao.selectByExample(example);

或者这样:

materialMeta.setStatus(MaterialStatus.online);
materialMeta.setPublishDate(new Date());
materialDao.updateByPrimaryKeySelective(materialMeta);

如此一来,一行sql都不需要写,mapper.xml文件也不需要了(特殊sql仍然需要手写)。

只是引入了原生的Mapper吗?有没有什么缺陷?我们做了什么改动?

fork的Mapper版本是3.4.2的,最新3.4.3还没有release。

像这样的通用框架,几乎支持了市面上所有主流的rdbms,但是大网易的DDB就呵呵哒了。

肿么办呢,当然是改啦。主要的问题是主键策略不支持。于是题主就给她新增了一种逐渐策略,名字就叫“DDB”。同样是通过拦截器修改mybatis的Configuration实现的。

同时新增了一个支持DDB批量Insert的Mapper,使用全局替换符的形式实现。

在对原生的Mapper做了这2个增强以后,就可以愉快的支持DDB的增删改查了。

使用时,请引入以下jar包:

<dependency>
<groupId>com.netease.pop.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.0.0</version>
</dependency>

同时,在配置文件中增加如下2行:

INDENTITY=DDB表示使用名称为DDB的主键策略(或者也可以在实体类的GeneratedValue注解中指定generator命令)

ORDER=BEFORE表示在insert命令前执行该主键策略(这是为了在insert前获取主键id值来使用)

其他

除了节省书写sql的时间外,配合另一个分页的开源插件PageHelper使用,可以事半功倍。使用上简单到可怕。

用法示例如下:

PageHelper.offsetPage(offset, limit);
Page<MaterialMeta> metas = (Page<MaterialMeta>) materialDao.selectByExample(example);

没错,就只有这么一行。。。

具体的接入方式可以参看以下文档:https://github.com/pagehelper/MybatisPageHelper/blob/master/README_zh.md

文章目录
  1. 1. 什么是通用Mapper?
  2. 2. 为什么要用Mapper?
  3. 3. 如何使用Mapper?
  4. 4. Java编码方式
  5. 5. 继承通用Mapper接口(注意必须要加泛型):
  6. 6. 实体类的规则:
    1. 6.1. 使用Mybatis-Generator来生成实体类:
    2. 6.2. 使用方法参见:http://ks.netease.com/blog?id=8920
  7. 7. 关于主键策略
    1. 7.1. 如此一来,一行sql都不需要写,mapper.xml文件也不需要了(特殊sql仍然需要手写)。
  8. 8. 只是引入了原生的Mapper吗?有没有什么缺陷?我们做了什么改动?
  9. 9. 其他
avascript"> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-107572620-1', 'auto'); ga('send', 'pageview');