热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MyBatis全局配置

全局配置中的属性非常多,主要有如下几方面:properties(属性)settings(全局配置参数

全局配置中的属性非常多,主要有如下几方面:


  • properties(属性)
  • settings(全局配置参数)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境集合属性对象)
  • environment(环境子属性对象)
  • transactionManager(事务管理)
  • dataSource(数据源)
  • mappers(映射器)

properties

properties 可以用来引入一个外部配置,最近常见的例子就是引入数据库的配置文件,例如我们在 resources 目录下添加一个 db.properties 文件作为数据库的配置文件,文件内容如下:

db.username=root
db.password=123
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql:///test01?serverTimezone=Asia/Shanghai

然后,利用 mybatis-config.xml 配置文件中的 properties 属性,引入这个配置文件,然后在 DataSource 中使用这个配置文件,最终配置如下:

<configuration><properties resource&#61;"db.properties">properties><environments default&#61;"development"><environment id&#61;"development"><transactionManager type&#61;"JDBC"/><dataSource type&#61;"POOLED"><property name&#61;"driver" value&#61;"${db.driver}"/><property name&#61;"url" value&#61;"${db.url}"/><property name&#61;"username" value&#61;"${db.username}"/><property name&#61;"password" value&#61;"${db.password}"/>dataSource>environment>environments><mappers><package name&#61;"com.antonio.hello.mybatis.mapper"/>mappers>
configuration>

settings


Setting(设置)Description&#xff08;描述&#xff09;Valid Values(验证值组)Default(默认值)
cacheEnabled在全局范围内启用或禁用缓存配置任何映射器在此配置下true or falseTRUE
lazyLoadingEnabled在全局范围内启用或禁用延迟加载。禁用时&#xff0c;所有查询将热加载true or falseTRUE
aggressiveLazyLoading启用时&#xff0c;有延迟加载属性的对象将被完全加载后调用懒惰的任何属性。否则&#xff0c;每一个属性是按需加载。true or falseTRUE
multipleResultSetsEnabled允许或不允许从一个单独的语句&#xff08;需要兼容的驱动程序&#xff09;要返回多个结果集。true or falseTRUE
useColumnLabel使用列标签&#xff0c;而不是列名。在这方面&#xff0c;不同的驱动有不同的行为。参考驱动文档或测试两种方法来决定你的驱动程序的行为如何。true or falseTRUE
useGeneratedKeys允许 JDBC 支持生成的密钥。兼容的驱动程序是必需的。此设置强制生成的键被使用&#xff0c;如果设置为 true&#xff0c;一些驱动会不兼容性&#xff0c;但仍然可以工作。true or falseFALSE
autoMappingBehavior指定 MyBatis 应如何自动映射列到字段/属性。NONE自动映射。 PARTIAL 只会自动映射结果没有嵌套结果映射定义里面。 FULL 会自动映射的结果映射任何复杂的&#xff08;包含嵌套或其他&#xff09;。NONE, PARTIAL, FULLPARTIAL
defaultExecutorType配置默认执行人。SIMPLE执行人确实没有什么特别的。 REUSE执行器重用准备好的语句。 BATCH执行器重用语句和批处理更新。SIMPLE REUSE BATCHSIMPLE
defaultStatementTimeout设置驱动程序等待一个数据库响应的秒数。Any positive integerNot Set (null)
safeRowBoundsEnabled允许使用嵌套的语句RowBounds。true or falseFALSE
mapUnderscoreToCamelCase从经典的数据库列名 A_COLUMN 启用自动映射到骆驼标识的经典的 Java 属性名 aColumn。true or falseFALSE
localCacheScopeMyBatis的使用本地缓存&#xff0c;以防止循环引用&#xff0c;并加快反复嵌套查询。默认情况下&#xff08;SESSION&#xff09;会话期间执行的所有查询缓存。如果 localCacheScope&#61;STATMENT 本地会话将被用于语句的执行&#xff0c;只是没有将数据共享之间的两个不同的调用相同的 SqlSession。SESSION or STATEMENTSESSION
dbcTypeForNull指定为空值时&#xff0c;没有特定的JDBC类型的参数的 JDBC 类型。有些驱动需要指定列的 JDBC 类型&#xff0c;但其他像 NULL&#xff0c;VARCHAR 或 OTHER 的工作与通用值。JdbcType enumeration. Most common are: NULL, VARCHAR and OTHEROTHER
lazyLoadTriggerMethods指定触发延迟加载的对象的方法。A method name list separated by commasequals,clone,hashCode,toString
defaultScriptingLanguage指定所使用的语言默认为动态SQL生成。A type alias or fully qualified class name.org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver
callSettersOnNulls指定如果setter方法或地图的put方法时&#xff0c;将调用检索到的值是null。它是有用的&#xff0c;当你依靠Map.keySet&#xff08;&#xff09;或null初始化。注意原语&#xff08;如整型&#xff0c;布尔等&#xff09;不会被设置为null。true or falseFALSE
logPrefix指定的前缀字串&#xff0c;MyBatis将会增加记录器的名称。Any StringNot set
logImpl指定MyBatis的日志实现使用。如果此设置是不存在的记录的实施将自动查找。SLF4J or LOG4J or LOG4J2 or JDK_LOGGING or COMMONS_LOGGING or STDOUT_LOGGING or NO_LOGGINGNot set
proxyFactory指定代理工具&#xff0c;MyBatis将会使用创建懒加载能力的对象。CGLIBJAVASSIST

typeAliases

这个是 MyBatis 中定义的别名&#xff0c;分两种&#xff0c;一种是 MyBatis 自带的别名&#xff0c;另一种是我们自定义的别名。


MyBatis 自带的别名


别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal

本来&#xff0c;我们在 Mapper 中定义数据类型时&#xff0c;需要写全路径&#xff0c;如下&#xff1a;

<select id&#61;"getUserCount" resultType&#61;"java.lang.Integer">select count(*) from user ;
select>

但是&#xff0c;每次写全路径比较麻烦。这种时候&#xff0c;我们可以用类型的别名来代替&#xff0c;例如用 int 做 Integer 的别名&#xff1a;

<select id&#61;"getUserCount" resultType&#61;"int">select count(*) from user ;
select>

自定义别名

我们自己的对象&#xff0c;在 Mapper 中定义的时候&#xff0c;也是需要写全路径&#xff1a;

<select id&#61;"getAllUser" resultType&#61;"com.antonio.hello.mybatis.entity.User">select * from user;
select>

这种情况下&#xff0c;写全路径也比较麻烦&#xff0c;我们可以给我们自己的 User 对象取一个别名&#xff0c;在 mybatis-config.xml 中添加 typeAliases 节点&#xff1a;

<configuration><properties resource&#61;"db.properties">properties><typeAliases><typeAlias type&#61;"com.antonio.hello.mybatis.entity.User" alias&#61;"user"/>typeAliases><environments default&#61;"development"><environment id&#61;"development"><transactionManager type&#61;"JDBC"/><dataSource type&#61;"POOLED"><property name&#61;"driver" value&#61;"${db.driver}"/><property name&#61;"url" value&#61;"${db.url}"/><property name&#61;"username" value&#61;"${db.username}"/><property name&#61;"password" value&#61;"${db.password}"/>dataSource>environment>environments><mappers><package name&#61;"com.antonio.hello.mybatis.mapper"/>mappers>
configuration>

这里&#xff0c;我们给 User 对象取了一个别名叫 user&#xff0c;然后&#xff0c;我们就可以在 Mapper 中直接使用 user 来代替 User 对象了&#xff1a;

<select id&#61;"getAllUser" resultType&#61;"user">select * from user;
select>

但是&#xff0c;这种一个一个去枚举对象的过程非常麻烦&#xff0c;我们还可以批量给对象定义别名&#xff0c;批量定义主要是利用包扫描来做&#xff0c;批量定义默认的类的别名&#xff0c;是类名首字母小写&#xff0c;例如如下配置&#xff1a;

<typeAliases><package name&#61;"com.antonio.hello.mybatis.entity"/>
typeAliases>

这个配置就表示给 com.antonio.hello.mybatis.entity 包下的所有类取别名&#xff0c;默认的别名就是类名首字母小写。这个时候&#xff0c;我们在 Mapper 中&#xff0c;就可以利用 user 代替 User 全路径了&#xff1a;

<select id&#61;"getAllUser" resultType&#61;"user">select * from user;
select>

在最新版中&#xff0c;批量定义的别名&#xff0c;类名首字母也可以不用小写&#xff0c;在实际开发中&#xff0c;我们一般使用第二种方式&#xff08;批量定义的方式&#xff09;


typeHandlers

在 MyBatis 映射中&#xff0c;能够自动将 Jdbc 类型映射为 Java 类型。默认的映射规则&#xff0c;如下&#xff1a;


类型处理器Java类型JDBC类型
BooleanTypeHandlerBoolean&#xff0c;boolean任何兼容的布尔值
ByteTypeHandlerByte&#xff0c;byte任何兼容的数字或字节类型
ShortTypeHandlerShort&#xff0c;short任何兼容的数字或短整型
IntegerTypeHandlerInteger&#xff0c;int任何兼容的数字和整型
LongTypeHandlerLong&#xff0c;long任何兼容的数字或长整型
FloatTypeHandlerFloat&#xff0c;float任何兼容的数字或单精度浮点型
DoubleTypeHandlerDouble&#xff0c;double任何兼容的数字或双精度浮点型
BigDecimalTypeHandlerBigDecimal任何兼容的数字或十进制小数类型
StringTypeHandlerStringCHAR和VARCHAR类型
ClobTypeHandlerStringCLOB和LONGVARCHAR类型
NStringTypeHandlerStringNVARCHAR和NCHAR类型
NClobTypeHandlerStringNCLOB类型
ByteArrayTypeHandlerbyte[]任何兼容的字节流类型
BlobTypeHandlerbyte[]BLOB和LONGVARBINARY类型
DateTypeHandlerDate&#xff08;java.util&#xff09;TIMESTAMP类型
DateOnlyTypeHandlerDate&#xff08;java.util&#xff09;DATE类型
TimeOnlyTypeHandlerDate&#xff08;java.util&#xff09;TIME类型
SqlTimestampTypeHandlerTimestamp&#xff08;java.sql&#xff09;TIMESTAMP类型
SqlDateTypeHandlerDate&#xff08;java.sql&#xff09;DATE类型
SqlTimeTypeHandlerTime&#xff08;java.sql&#xff09;TIME类型
ObjectTypeHandler任意其他或未指定类型
EnumTypeHandlerEnumeration类型VARCHAR-任何兼容的字符串类型&#xff0c;作为代码存储&#xff08;而不是索引&#xff09;。

前面案例中&#xff0c;之所以数据能够接收成功&#xff0c;是因为有上面这些默认的类型处理器&#xff0c;处理基本数据类型&#xff0c;这些够用了&#xff0c;特殊类型&#xff0c;需要我们自定义类型处理器。

比如&#xff0c;我有一个用户爱好的字段&#xff0c;这个字段&#xff0c;在对象中&#xff0c;是一个 List 集合&#xff0c;在数据库中&#xff0c;是一个 VARCHAR 字段&#xff0c;这种情况下&#xff0c;就需要我们自定义类型转换器&#xff0c;自定义的类型转换器提供两个功能&#xff1a;


  1. 数据存储时&#xff0c;自动将 List 集合&#xff0c;转为字符串&#xff08;格式自定义&#xff09;
  2. 数据查询时&#xff0c;将查到的字符串再转为 List 集合

首先&#xff0c;在数据表中添加一个 favorites 字段。然后&#xff0c;在 User 对象中&#xff0c;添加相应的属性&#xff1a;

public class User {private Integer id;private String username;private String address;private List<String> favorites;// 省略 setter/getter
}

为了能够将 List 集合中的数据存入到 VARCHAR 中&#xff0c;我们需要自定义一个类型转换器&#xff1a;

&#64;MappedJdbcTypes(JdbcType.VARCHAR)
&#64;MappedTypes(List.class)
public class List2VarcharHandler implements TypeHandler<List<String>> {public void setParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {StringBuffer sb &#61; new StringBuffer();for (String s : parameter) {sb.append(s).append(",");}ps.setString(i, sb.toString());}public List<String> getResult(ResultSet rs, String columnName) throws SQLException {String favs &#61; rs.getString(columnName);if (favs !&#61; null) {return Arrays.asList(favs.split(","));}return null;}public List<String> getResult(ResultSet rs, int columnIndex) throws SQLException {String favs &#61; rs.getString(columnIndex);if (favs !&#61; null) {return Arrays.asList(favs.split(","));}return null;}public List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException {String favs &#61; cs.getString(columnIndex);if (favs !&#61; null) {return Arrays.asList(favs.split(","));}return null;}
}

  • 首先在这个自定义的类型转换器上添加 &#64;MappedJdbcTypes 注解指定要处理的 Jdbc 数据类型&#xff0c;另外还有一个注解是 &#64;MappedTypes 指定要处理的 Java 类型&#xff0c;这两个注解结合起来&#xff0c;就可以锁定要处理的字段是 favorites 了。
  • setParameter 方法看名字就知道是设置参数的&#xff0c;这个设置过程由我们手动实现&#xff0c;我们在这里&#xff0c;将 List 集合中的每一项&#xff0c;用一个 , 串起来&#xff0c;组成一个字符串。
  • getResult 方法&#xff0c;有三个重载方法&#xff0c;其实都是处理查询的。

接下来&#xff0c;修改插入的 Mapper&#xff1a;

<insert id&#61;"addUser" parameterType&#61;"com.antonio.hello.mybatis.entity.User">insert into user (username,address,favorites) values (#{username},#{address},#{favorites,typeHandler&#61;com.antonio.hello.mybatis.typehandler.List2VarcharHandler});
insert>

然后&#xff0c;在 Java 代码中&#xff0c;调用该方法&#xff1a;

public class Main2 {public static void main(String[] args) {SqlSessionFactory instance &#61; SqlSessionFactoryUtils.getInstance();SqlSession sqlSession &#61; instance.openSession();UserMapper mapper &#61; sqlSession.getMapper(UserMapper.class);User user &#61; new User();user.setUsername("风气");user.setAddress("上海");List<String> favorites &#61; new ArrayList<String>();favorites.add("足球");favorites.add("篮球");favorites.add("乒乓球");user.setFavorites(favorites);mapper.addUser(user);sqlSession.commit();}
}

这样&#xff0c;List 集合存入到数据库中之后&#xff0c;就变成一个字符串了。读取的配置&#xff0c;有两个地方&#xff0c;一个可以在 ResultMap 中做局部配置&#xff0c;也可以在全局配置中进行过配置&#xff0c;全局配置方式如下&#xff1a;

<configuration><properties resource&#61;"db.properties">properties><typeAliases><package name&#61;"com.antonio.hello.mybatis.entity"/>typeAliases><typeHandlers><package name&#61;"com.antonio.hello.mybatis.typehandler"/>typeHandlers><environments default&#61;"development"><environment id&#61;"development"><transactionManager type&#61;"JDBC"/><dataSource type&#61;"POOLED"><property name&#61;"driver" value&#61;"${db.driver}"/><property name&#61;"url" value&#61;"${db.url}"/><property name&#61;"username" value&#61;"${db.username}"/><property name&#61;"password" value&#61;"${db.password}"/>dataSource>environment>environments><mappers><package name&#61;"com.antonio.hello.mybatis.mapper"/>mappers>
configuration>

接下来去查询&#xff0c;查询过程中&#xff0c;就会自动将字符串转为 List 集合了。


Mapper

Mapper 配置的几种方法&#xff1a;

使用相对于类路径的资源&#xff0c;即 XML 的定位&#xff0c;从 classpath 开始写。如&#xff1a;

<mapper resource&#61;"mapping/User.xml" />

使用完全限定路径&#xff0c;相当于使用绝对路径&#xff0c;这种方式使用非常少。如&#xff1a;

<mapper url&#61;"file:///D:\demo\xxx\User.xml" />

使用 mapper 接口类路径&#xff0c;注意&#xff1a;此种方法要求 mapper 接口名称和 mapper 映射文件名称相同&#xff0c;且放在同一个目录中。如&#xff1a;

<mapper class&#61;"com.antonio.hello.mybatis.mapper.UserMapper"/>

注册指定包下的所有 mapper 接口。如&#xff1a;

<package name&#61;"com.antonio.hello.mybatis.mapper"/>

注意&#xff1a;此种方法要求 mapper 接口名称和 mapper 映射文件名称相同&#xff0c;且放在同一个目录中。实际项目中&#xff0c;多采用这种方式。


更多干货请移步&#xff1a;https://antoniopeng.com



推荐阅读
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Summarize function is doing alignment without timezone ?
    Hi.Imtryingtogetsummarizefrom00:00otfirstdayofthismonthametric, ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • charles3.11.1抓https包
    结论先行:用的是安卓测试机,没加固之前的生产环境的安装包,可以抓到https请求加固之后的包【也就是要上应用市场的包】,抓不到https请求电脑上的操作:1.安装证书【电脑上安装了 ... [详细]
  • 1.{#if}{#if|COND|}..{#elseif|COND|}..{#else}..{#if}Examples:{#if2*816}good{#else}fa ... [详细]
  • 本文涉及源码版本为2.6.9准备工作down一份Vue源码,从package.json入手,找我们需要的代码1、package.json中的scripts,build:nodesc ... [详细]
  • IDApro反编译exe时生成的C文件中#include的defs.h文件在IDA目录下plugins文件夹内*Thisfilecontainsdefinition ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 1.移除consol.log()的babel插件安装:npmibabel-plugin-transform-remove-console-D配置:babel.config.js:这 ... [详细]
  • Docker安装Rabbitmq(配合宝塔)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Docker安装Rabbitmq(配合宝塔)相关的知识,希望对你有一定的参考价值。一、事前准备 ... [详细]
  • npminstall-Dbabelcorebabelpreset-envbabelplugin-transform-runtimebabelpolyfillbabel-loader ... [详细]
  • 1、问题?项目打包报错;程序包com.sun.image.codec.jpeg不存在;2、原因尚不明确;由于jdk升级问题。才出现的,可能jdk6就不会出现;初步怀疑jdk的问题; ... [详细]
author-avatar
ze602
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有