本文共 12118 字,大约阅读时间需要 40 分钟。
引入 mybatis generator
5.1.44 1.3.5 1.3.1 3.4.4 org.mybatis.generator mybatis-generator-maven-plugin ${mybatis.generator.version} src/main/resources/generatorConfig.xml true true mysql mysql-connector-java ${mysql.connector.version} org.mybatis.generator mybatis-generator-core ${mybatis.generator.version} com.github.oceanc mybatis3-generator-plugin 0.4.0 src/main/java **/*.xml src/main/resources true **/*.*
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
自动生成代码的核心配置文件 generatorConfig.xml
的路径mysql-connector-java
生成哪种数据库的代码,不可省略com.github.oceanc
引入第三方的 jar
,能够生成常用的查询语法resources
标签配置是为了将 mybatis 语法 xml 文件
打包进 war
包,缺少 xml
文件代码是无法执行的org.mybatis.generator
自动生成可执行代码的核心 jar
,不可缺少model
中 equals
和 hashCode
方法,这对比两个对象的值是否相等很在意义。这个重写可以通过 Intellj
自带的帮助方法解决,ALT+Insert
-->equals() and hashCode()
。各处统一使用相同的生成方法即可withXxx()
方法,可以简洁的赋值 new MyDomain().withFoo("Test").withBar(4711);
。这个功能可以通过 Intellj
的插件 InnerBuilder
实现,使用 Builder
模式。MyBatis 3.x
框架使用的配置文件。感觉没有什么用处,生成的配置文件也没有生成什么有用的东西mybatis
默认生成的查询类是以 Example
结尾,往往都使用如下配置改成 Criteria
结尾iBATIS 2.x
框架使用的配置文件。感觉没有什么用处,生成的配置文件也没有生成什么有用的东西model
中 toString
方法。这个可以通过 Intellj
完成,ALT+insert
--> toString()
mybatis
有部分方法不会生成,配置几个虚拟的主键,即使在数据库中并不是主键也可以配置。配置方案受sql dialect的限制,多数plugin目前仅支持 Mysql 5.x
在 Maven Central 上最新的发布版本是:
com.github.oceanc mybatis3-generator-plugin 0.4.0
mybatis3-generator-plugins目前提供了如下可用插件:
在中添加你需要用到的<plugin>
元素:
为了举例,假设我们创建一张简单的账户表,并命名为Account
。DDL如下:
CREATE TABLE `Account` ( `id` bigint(16) NOT NULL, `create_time` timestamp NOT NULL, `name` varchar(64) DEFAULT NULL, `age` tinyint(3) DEFAULT NULL, `version` int(11) NOT NULL, PRIMARY KEY (`id`))ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
如果使用了 SliceTablePlugin
,为了其产生的作用始终有效,推荐将其放置在自定义 <plugin>
声明的第一条,如上例所示。这么做的原因是,其他 plugin(BatchInsertPlugin、MinMaxPlugin、和SumSelectivePlugin)
会通过检测 SliceTablePlugin
是否应用,来适配其效果。
当数据库单表数据量过大时,可以通过水平拆分把单表分解为多表。例如,若 Account
表中的预期数据量过大时(也许5、6亿),可以把一张 Account
表分解为多张 Account
表。SliceTablePlugin并不会自动创建和执行拆分后的DDL,因此必须手工创建DDL并按下述约定修改表名。
SliceTablePlugin
目前支持两种分表命名方式:
原表名_N
。如:Account_0、Account_1、Account_3 ......原表名_yyyyMM
。如:Account_201501、Account_201502 ...... Account_201512Account
表的 id
字段做分表,计划拆分为 97
张表。在 的 <table>
元素中添加两个 <property>
sliceMod
指按取模方式分表,97
是取模的模数sliceColumn
指取模所使用的列,id
是具体列名Account
表的 create_time
字段做拆分:sliceMonth
指按自然月分表,1
指按单个自然月。Note:目前只支持按单月分表,此处的值 1 无实际意义 sliceColumn
指时间类型的列,create_time
是具体列名AccountMapper mapper = ...Account record = new Account();record.setAge(33);record.setId(101);record.setCreateTime(new Date());mapper.insert(record);// or mapper.insertSelective(record)
setId
并传入合适的参数通过自然月分表时,必须调用 setCreateTime
并传入合适的参数
AccountMapper mapper = ...AccountExample example = new AccountExample();example.partitionFactorId(id).createCriteria().andAgeEqualTo(33);// or example.partitionFactorCreateTime(new Date()).createCriteria().andAgeEqualTo(33);Listas = mapper.selectByExample(example);
partitionFactorId
方法表示分表因子是 Id
字段,必须调用该方法并传入合适的参数通过自然月分表时,partitionFactorCreateTime
方法表示分表因子是 createTime
字段,必须调用该方法并传入合适的参数
AccountMapper mapper = ...Account record = new Account();record.setAge(33);AccountExample example = new AccountExample();example.partitionFactorId(id).createCriteria().andAgeEqualTo(33);// or example.partitionFactorCreateTime(new Date()).createCriteria().andAgeEqualTo(33);mapper.updateByExampleSelective(record, example);
上例的用法和read操作一样,在example对象上必须调用 partitionFactorId
或 partitionFactorCreateTime
方法。
AccountMapper mapper = ...Account record = new Account();record.setCreateTime(new Date());record.setId(101);// or record.setCreateTime(new Date());AccountExample example = new AccountExample();example.createCriteria().andAgeEqualTo(33);mapper.updateByExampleSelective(record, example);
由于在record对象调用了setId
或setCreateTime
,就无须在example对象指定分表因子。
AccountMapper mapper = ...AccountExample example = new AccountExample();example.partitionFactorId(id).createCriteria().andAgeEqualTo(33);// or example.partitionFactorCreateTime(new Date()).createCriteria().andVersionEqualTo(0);mapper.deleteByExample(example);
partitionFactorId
方法表示分表因子是Id字段,必须调用该方法并传入合适的参数通过自然月分表时,partitionFactorCreateTime
方法表示分表因子是createTime字段,必须调用该方法并传入合适的参数
record.setTableNameSuffix(...)
取代record.setId(...)
或 record.setId(...)
example.setTableNameSuffix(...)
取代 example.partitionFactorId(...)
WARNING:由于 setTableNameSuffix
的参数是 String
类型,在 Mybatis3
的 mapper xml
中生成 ${}
变量,这种变量不会做 sql
转义,而直接嵌入到 sql
语句中。如果以用户输入作为 setTableNameSuffix
的参数,会导致潜在的 SQL Injection
攻击,需谨慎使用。
该 plugin
是为了增加批量 insert
的功能。特别适用于初始化数据、或迁移数据。
AccountMapper mapper = ...Listas = new ArrayList<>();as.add(...)mapper.batchInsert(as);
如果使用了 SliceTablePlugin
,则需要对 List
中每一个 Account
实例设置分表因子:
AccountMapper mapper = ...Listas = new ArrayList<>();for (Account account : accounts) { account.setId(...); // or account.setCreateTime(...);}mapper.batchInsert(as);
setId
并传入合适的参数setCreateTime
并传入合适的参数该 plugin
是为生成的 model
类添加的 @JsonProperty
、@JsonIgnore
、 和 @JsonFormat
注解。若使用此插件,需要额外依赖jackson 2.5 +
。(这个插件没有什么必要啊,手工添加更加方便)
在的 <table>
元素中添加四个 <property>
(可选的):
jacksonColumns
指需要添加 @JsonProperty
注解的列,由 ,
分割的列名组成。该 <property>
必须和 jacksonProperties
成对出现jacksonProperties
指 @JsonProperty
注解所需的参数值,由 ,
分割,这些值的数量和顺序必须和 jacksonColumns
的值一一对应。该 <property>
必须和 jacksonColumns
成对出现jacksonFormats
指需要添加 @JsonFormat
注解的列,值由 ,
分割的键值对组成,键值对由 @
分割,键为列名,值为 @JsonFormat
所需参数jacksonIgnores
指需要添加 @JsonIgnore
注解的列,值由 ,
分割的列名组成public class Account implements Serializable { @JsonIgnore private Long id; @JsonProperty("nickName") private String name; @JsonProperty("realAge") private Integer age; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; @JsonIgnore private Long version;}
该 plugin
是为生成的 model
类添加 toJson
方法。toJson
方法的实现依赖于。若使用此插件,需要额外依赖jackson 2.5 +
。(这个插件没有必要使用,并且会有性能的问题,因为生成的 toJson
方法每次被调用都重新 new ObjectMapper
。ObjectMapper
是线程安全的,完全可以做一个全局的变量)
public class Account implements Serializable { public String toJson() throws IOException { ... ... }}
该 plugin
是为生成的 model
类添加注解,避免了 java bean
中繁琐的 setter
和 getter
。生成的代码看起来也更干净、紧凑。若使用此插件,需要额外依赖 lombok
。(这个插件可用,可不用,因为手工添加几个注解也是简单的)
org.projectlombok lombok 1.16.8
@Datapublic class Account implements Serializable { private Long id; ... ...}
在 的 <table>
元素中添加两个 <property>
(可选的)。(这个支持不好,生成的方法名称不友好,以逗号分隔没有起到作用)
minColumns
是可进行min操作的列,值由,
分割的列名组成maxColumns
是可进行max操作的列,值由,
分割的列名组成AccountMapper mapper = ...AccountExample example = new AccountExample();example.createCriteria().andAgeEqualTo(33);long min = mapper.minIdByExample(example);long max = mapper.maxIdByExample(example);
如果使用了 SliceTablePlugin
,别忘了对分表因子赋值:example.partitionFactorCreateTime(...)
在处理并发写操作时,如果数据竞争较低,通常会采用乐观锁,避免并发问题的同时获得较好的性能。实现乐观锁的一般方式是在数据中添加版本信息,就像 Account
表中的 version
列。当写操作成功时,版本信息也相应递增。该 plugin
就是解决 version
自动递增问题的,可以避免手动对 version+1
。
在的 <table>
元素中添加一个 <property>
optimisticLockColumn
指具有版本信息语义的列,version
是具体的列名AccountMapper mapper = ...Account record = new Account();record.setName("tom");// record.setVersion(1) 无须手工对version进行赋值AccountExample example = new AccountExample();example.createCriteria().andAgeEqualTo(33);mapper.updateByExampleSelective(record, example);
如果使用了 SliceTablePlugin
,别忘了对分表因子赋值:example.partitionFactorId(...)
这个与 org.mybatis.generator.plugins.RowBoundsPlugin
的功能是类似的
AccountMapper mapper = ...AccountExample example = new AccountExample();example.page(0, 2).createCriteria().andAgeEqualTo(33);Listas = mapper.selectByExample(example);
如果使用了 SliceTablePlugin
,别忘了对分表因子赋值:example.partitionFactorCreateTime(...)
AccountMapper mapper = ...AccountExample example = new AccountExample();example.sumAge().createCriteria().andVersionEqualTo(0);long sum = mapper.sumByExample(example);
如果使用了 SliceTablePlugin
,别忘了对分表因子赋值:example.partitionFactorCreateTime(...)
AccountMapper mapper = ...Account record = new Account();record.setUpdateSql("version = version + 1")record.setAge(33);AccountExample example = new AccountExample();example.createCriteria().andAgeEqualTo(22);mapper.updateByExampleSelective(record.setAge, example);
如果使用了 SliceTablePlugin
,别忘了对分表因子赋值:example.partitionFactorCreateTime(...)
setUpdateSql
的参数是 String
类型,在 Mybatis3
的 mapper xml
中生成 ${}
变量,这种变量不会做 sql
转义,而直接嵌入到 sql
语句中。如果以用户输入作为 setUpdateSql
的参数,会导致潜在的 SQL Injection
攻击,需谨慎使用。 AccountMapper mapper = ...int v = 1;AccountExample example = new AccountExample();example.createCriteria().andAgeEqualTo(33).addConditionSql("version =" + v + " + 1");Listas = mapper.selectByExample(example);
如果使用了 SliceTablePlugin
,别忘了对分表因子赋值:example.partitionFactorCreateTime(...)
setUpdateSql
的参数是 String
类型,在 Mybatis3
的 mapper xml
中生成 ${}
变量,这种变量不会做 sql
转义,而直接嵌入到 sql
语句中。如果以用户输入作为 setUpdateSql
的参数,会导致潜在的 SQL Injection
攻击,需谨慎使用。 本篇博客主要来自:,其他部分内容来自官网:
转载地址:http://clvta.baihongyu.com/