3.config

isea533 edited this page Mar 24, 2018 · 7 revisions

三、配置介绍

由于数据库存在各种各样的差异,因此有些时候要做一些必要的配置。

此外通用 Mapper 还提供了一些控制参数和一些和主键策略相关的参数。

文档提供的参数基于 4.0 及以后的版本

有些参数仍然存在,但是由于不推荐使用,这里不会介绍(如 UUID)。

提醒:看配置前,一定要看第二章的对象关系映射,否则不会明白这些参数的用途。

参数的配置方式在第一章中,针对不同的集成环境都写了详细的文档。

通用 Mapper 提供了下面这些参数:

  1. mappers
  2. IDENTITY
  3. ORDER(别名: order, before)
  4. catalog
  5. schema
  6. notEmpty
  7. style
  8. enableMethodAnnotation
  9. useSimpleType
  10. usePrimitiveType
  11. simpleTypes
  12. enumAsSimpleType
  13. wrapKeyword
  14. checkExampleEntityClass
  15. safeDelete
  16. safeUpdate
  17. useJavaType

下面分别对这些参数进行介绍。

3.1 mappers

在 4.0 以前这是一个非常重要的参数,当时只有通过 mappers 配置过的接口才能真正调用,由于很多人不注意看文档,通用 Mapper 90% 的问题都出在这个参数上。

4.0 之后,增加了一个 @RegisterMapper 注解,通用 Mapper 中提供的所有接口都有这个注解,有了该注解后,通用 Mapper 会自动解析所有的接口,如果父接口(递归向上找到的最顶层)存在标记该注解的接口,就会自动注册上。因此 4.0 后使用通用 Mapper 提供的方法时,不需要在配置这个参数。

当你自己扩展通用接口时,建议加上该注解,否则就要配置 mappers 参数。

3.2 IDENTITY

取回主键的方式,可以配置的值如 2.3.2 中所列的数据库类型:

  • DB2: VALUES IDENTITY_VAL_LOCAL()
  • MYSQL: SELECT LAST_INSERT_ID()
  • SQLSERVER: SELECT SCOPE_IDENTITY()
  • CLOUDSCAPE: VALUES IDENTITY_VAL_LOCAL()
  • DERBY: VALUES IDENTITY_VAL_LOCAL()
  • HSQLDB: CALL IDENTITY()
  • SYBASE: SELECT @@IDENTITY
  • DB2_MF: SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
  • INFORMIX: select dbinfo('sqlca.sqlerrd1') from systables where tabid=1

配置时,写为:

IDENTITY=MYSQL

这个参数配置的同时,还经常伴着 3.2 中的 ORDER 参数。

3.3 ORDER(别名: order, before)

<selectKey>中的order属性,可选值为BEFOREAFTER

后来为了方便在 Spring Boot 中配置该参数,符合 Boot 的规范,增加了 orderbefore 两个别名。

在 3.1 的配置以及 2.3.2 和 2.3.3 中都提到了这个参数。

在支持主键递增,满足 2.3.2 中的情况时,配置如下:

//Properties 方式配置时
ORDER=AFTER
//还可以
order=AFTER
//或
before=false

//Spring Boot 中,比上面多个前缀,并且 ORDER 不能使用
mapper.order=AFTER
//或者(Spring Boot)
mapper.before=false

在类似Oracle序列或者通用的 UUID 时,配置如下:

//Properties 方式配置时
ORDER=BEFORE
//还可以
order=BEFORE
//或
before=true

//Spring Boot 中,比上面多个前缀,并且 ORDER 不能使用
mapper.order=BEFORE
//或者(Spring Boot)
mapper.before=true

上面示例中有多种写法,使用时按照需要选择一种即可,切勿同时配置!

3.4 catalog

数据库的catalog,如果设置该值,查询的时候表名会带catalog设置的前缀。

3.5 schema

catalogcatalog优先级高于schema

3.6 notEmpty

insertSelectiveupdateByPrimaryKeySelective 中,是否判断字符串类型 !=''

配置方式:

notEmpty=true

3.7 style

实体和表转换时的默认规则,在 2.2 和 2.2.1 中都提到了这个参数,可选值如下:

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

配置方式如下:

style=camelhumpAndUppercase

3.8 enableMethodAnnotation

可以控制是否支持(getter 和 setter)在方法上使用注解,默认false

配置方式如下:

enableMethodAnnotation=true

启用后,可以按照下面方式使用:

private String name;

@Column(name = "user_name")
public void setName(String name){
  this.name = name;
}

3.9 useSimpleType

默认 true,启用后判断实体类属性是否为表字段时校验字段是否为简单类型,如果不是就忽略该属性,这个配置优先级高于所有注解。

注意:byte, short, int, long, float, double, char, boolean 由于存在默认值,这里不会作为简单类型对待!也就是默认情况下,这些字段不会和表字段进行映射。2.2.5 中也强调了这一点。

配置方式如下:

useSimpleType=true

3.10 usePrimitiveType

为了方便部分还在使用基本类型的实体,增加了该属性,只有配置该属性,并且设置为 true 才会生效,启用后,会扫描 8 种基本类型。

配置方式如下:

usePrimitiveType=true

3.11 simpleTypes

默认的简单类型在 SimpleTypeUtil 中,使用该参数可以增加额外的简单类型,通过逗号隔开的全限定类名添加。

配置方式如:

simpleTypes=xxx.GenderEnum,xxx.JobEnum

3.12 enumAsSimpleType

用于配置是否将枚举类型当成基本类型对待。

默认 simpleType 会忽略枚举类型,使用 enumAsSimpleType 配置后会把枚举按简单类型处理,需要自己配置好 typeHandler

配置方式如下:

enumAsSimpleType=true

3.13 wrapKeyword

配置后会自动处理关键字,可以配的值和数据库有关。

例如 sqlserver 可以配置为 [{0}],使用 {0} 替代原来的列名。

MySql 对应的配置如下:

wrapKeyword=`{0}`

使用该配置后,类似 private String order 就不需要通过 @Column 来指定别名。

3.14 checkExampleEntityClass

默认 false 用于校验通用 Example 构造参数 entityClass 是否和当前调用的 Mapper<EntityClass> 类型一致。

假设存在下面代码:

Example example = new Example(City.class);
example.xxx...;//设置条件的方法
countryMapper.selectByExample(example);

注意,这里使用 City 创建的 Example,本该使用 cityMapper 来调用,但是这里使用了 countryMapper,默认情况下会出现字段不匹配的错误,更特殊的情况下会正好匹配字段,但是却操作错了表!

配置该字段为 true 后就会对不匹配的情况进行校验!

配置如下:

checkExampleEntityClass=true

3.15 safeDelete

配置为 true 后,delete 和 deleteByExample 都必须设置查询条件才能删除,否则会抛出异常。

配置如下:

safeDelete=true

使用效果:

Caused by: tk.mybatis.mapper.MapperException: 通用 Mapper 安全检查: 当前操作的方法没有指定查询条件,不允许执行该操作!
	at tk.mybatis.mapper.util.OGNL.notAllNullParameterCheck(OGNL.java:91)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.apache.ibatis.ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:899)
	at org.apache.ibatis.ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1544)
	... 53 more

3.16 safeUpdate

配置为 true 后,updateByExample 和 updateByExampleSelective 都必须设置查询条件才能删除,否则会抛出异常(org.apache.ibatis.exceptions.PersistenceException)。

updateByPrimaryKey 和 updateByPrimaryKeySelective 由于要求必须使用主键,不存在这个问题。

配置如下:

safeUpdate=true

使用效果:

Caused by: tk.mybatis.mapper.MapperException: 通用 Mapper 安全检查: 当前操作的方法没有指定查询条件,不允许执行该操作!
	at tk.mybatis.mapper.util.OGNL.notAllNullParameterCheck(OGNL.java:91)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.apache.ibatis.ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:899)
	at org.apache.ibatis.ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1544)
	... 53 more

3.17 useJavaType

设置 true 时,参数中会增加 javaType 设置,如 {id, javaType=java.lang.Long}。在 <resultMap> 中也会设置 javaType 属性。

配置如下:

useJavaType=true

对于使用 User extends Pk<Long> 形式时,需要设置,否则 mybatis 低版本(<3.4.0) 无法识别类型。

建议升级到 mybatis 3.4.x 的最新版本

例如:

class Pk<T> {
  private T id;

  public T getId() {
    return id;
  }

  public void setId(T id) {
    this.id = id;
  }
}

class User extends Pk<Long> {
  private String name;
}

如果不设置 javaType,低版本的 MyBatis 会认为 id 的类型为 Object。升级 MyBatis 到 3.4.0+ 最好。

设置 useJavaType 只对通用 Mapper 自己方法有效,自己写的其他方法还需要自己指定。

特别注意

使用 useJavaType=true 后,调用 ByPrimaryKey 类的方法时,需要按照实体中对应的类型来指定,例如主键类型为 Long 时,必须 mapper.selectByPrimaryKey(1L)

不配置时,没有这个限制,可以使用 mapper.selectByPrimaryKey(1)mapper.selectByPrimaryKey("1") 等类型。

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.