mybatis配置
MyBatis是一个基于Java的数据持久层(ORM)框架。把实体类和SQL语句之间建立了映射关系,是一种半自动化的ORM实现。
ORM
ORM 对象关系映射,是一种数据持久化技术
O:Object 对象----java里的实体类(对象)
R:Relation 关系----关系型数据库(表)
M:Mapping 映射----提供一种机制,实现映射
Mybatis核心配置文件
核心配置文件 mybatis-config.xml,配置文件会影响 mybatis 的行为设置和属性信息.
在配置文件里面添加这些配置,要按顺序来添加,不然会报错.
MyBatis 配置文档的顶层结构如下:
1.configuration(配置)
2.properties(属性)
3.property(属性信息)
4.settings(设置)
5.typeAliases(类型别名)
6.typeHandlers(类型处理器)
7.objectFactory(对象工厂)
8.plugins(插件)
9.environments(环境配置)
10.environment(环境变量)
11.transactionManager(事务管理器)
12.dataSource(数据源)
13.property(属性信息)
14.databaseIdProvider(数据库厂商标识)
15mappers(映射器)
${}与#{}的区别
#{}是预编译处理,$ {}是字符串替换
#{}:相当于占位符 ?
$ {}:相当于字符拼接
具体说明:
properties(属性)
2.properties(属性)用来加载配置文件或声明属性信息的
有两种书写方式:
如:
<properties>
<properties resource="db.properties">
<property name="username" value="dev_user"/>
</properties>
settings(设置)
4.settings(设置)
settings 是最复杂的配置,它能深刻影响 MyBatis 底层的运行,但是在大部分情况下使用默认值便可以运行,所以在大部分情况下不需要大量配置它,只需要修改一些常用的规则即可
配置项 | 作用 | 配置选项 | 默认值 |
---|---|---|---|
cacheEnabled | 该配置影响所有映射器中配置缓存的全局开关 | true|false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。在特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态 | true|false | false |
aggressiveLazyLoading | 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载 | true|false | 版本3.4.1 (不包含) 之前 true,之后 false |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动) | true|false | true |
useColumnLabel | 使用列标签代替列名。不同的驱动会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果 | true|false | true |
useGeneratedKeys | 允许JDBC 支持自动生成主键,需要驱动兼容。如果设置为 true,则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby) | true|false | false |
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射。 PARTIAL 表示只会自动映射,没有定义嵌套结果集和映射结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套) | NONE PARTIAL FULL | PARTIAL |
autoMappingUnkno wnColumnBehavior | 指定自动映射当中未知列(或未知属性类型)时的行为。 默认是不处理,只有当日志级别达到 WARN 级别或者以下,才会显示相关日志,如果处理失败会抛出 SqlSessionException 异常 | NONE WARNING FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 是普通的执行器;REUSE 会重用预处理语句(prepared statements);BATCH 执行器将重用语句并执行批量更新 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数 | 任何正整数 | Not Set (null) |
defaultFetchSize | 设置数据库驱动程序默认返回的条数限制,此参数可以重新设置 | 任何正整数 | Not Set (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds)。如果允许,设置 false | true|false | false |
safeResultHandlerEnabled | 允许在嵌套语句中使用分页(ResultHandler)。如果允许,设置false | true|false | true |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射 | true|false | false |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速联复嵌套査询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlScssion 的不同调用将不会共享数据 | SESSION|STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER | NULL VARCHAR OTHER | OTHER |
lazyLoadTriggerMethods | 指定哪个对象的方法触发一次延迟加载 | — | equals clone hashCode toString |
defaultScriptingLanguage | 指定动态 SQL 生成的默认语言 | — | org.apache.ibatis.script.ing.xmltags.XMLDynamicLanguageDriver |
callSettersOnNulls | 指定当结果集中值为 null 时,是否调用映射对象的 setter(map 对象时为 put)方法,这对于 Map.kcySet() 依赖或 null 值初始化时是有用的。注意,基本类型(int、boolean 等)不能设置成 null | true|false | false |
logPrefix | 指定 MyBatis 增加到日志名称的前缀 | 任何字符串 | Not set |
loglmpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动査找 | SLF4J LOG4J LOG4J2 JDK_LOGGING COMMONS_LOGGING STDOUT_LOGGING NO_LOGGING | Not set |
proxyFactory | 指定 MyBatis 创建具有延迟加栽能力的对象所用到的代理工具 | CGLIB|JAVASSIST | JAVASSIST (MyBatis 版本为 3.3 及以上的) |
vfsImpl | 指定 VFS 的实现类 | 提供 VFS 类的全限定名,如果存在多个,可以使用逗号分隔 | Not set |
useActualParamName | 允许用方法参数中声明的实际名称引用参数。要使用此功能,项目必须被编译为 Java 8 参数的选择。(从版本 3.4.1 开始可以使用) | true|false | true |
typeAliases(类型别名)
5.typeAliases(类型别名)
类型别名可为 Java 类型设置一个缩写名字。它仅用于 XML 配置,意在降低冗余的全限定类名书写。
mybatis 核心配置文件中配置优先级最高,开启包扫描后,如果还有另外配置注解,则以注解为准
Java类型的别名,如果在前面加下划线_,映射的是基本类型,如果没有加下划线,映射的是包装类型。
设置完别名后使用名字时需要用别名
里面有两种写法:单个和整个包
如:
<typeAliases>
<typeAlias alias="User" type="com.xxx.domain.User"/>
<package name="com.xxx.domain"/>
</typeAliases>
typeHandlers(类型处理器)
6.typeHandlers(类型处理器)
typeHandlers(类型处理器)标签是用来重写或者自定义类型处理器的。
由于Java 类型和数据库的 JDBC 类型不是一一对应的(比如 String 与 varchar),
所以我们把 Java 对象转换为数据库的值,和把数据库的值转换成 Java 对象,需要经过 一定的转换,这两个方向的转换就要用到 TypeHandler。
MyBatis 中已经内置了很多 TypeHandler,因此我们平时没有做任何关于 TypeHandler 的配置也可以保存成数据库里面的 varchar 字段或者保存成 char 字段。
objectFactory(对象工厂)
7.objectFactory(对象工厂)
当我们把数据库返回的结果集转换为实体类的时候,需要创建对象的实例,由于我 们不知道需要处理的类型是什么,有哪些属性,所以不能用 new 的方式去创建。
在 MyBatis 里面,它提供了一个工厂类的接口,叫做 ObjectFactory,专门用来创建对象的实例。
typeHandlers(类型处理器)标签是用来重写或者自定义类型对象工厂的。
plugins(插件)
8.plugins(插件)
MyBatis 可以使用第三方的插件来对功能进行扩展,比如分页助手 PageHelper 是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据。
如:
<!--配置分页助手插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"></property>
</plugin>
</plugins>
environments(环境配置)
9.environments(环境配置)
mybatis 可以配置多套环境使用,但是尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境
属性:
default为默认使用的环境
在其标签内部使用environment进行配置对应的环境
属性:
id:development环境的唯一标识,写在default里表示使用该环境
transactionManager :事务管理器,有两种配置: type=“[JDBC|MANAGED]”
JDBC:使用了 JDBC 的提交和回滚设施。
MANAGED : 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。
dataSource:数据源,有三种类型:type=“[UNPOOLED|POOLED|JNDI]”
UNPOOLED – 这个数据源的实现会每次请求时打开和关闭连接。
POOLED – 这种数据源的实现利用“池”的概念将 JDBC连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。默认的是这个。
JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用
例如:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
databaseIdProvider(数据库厂商标识)
14.databaseIdProvider(数据库厂商标识)
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。
MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。
如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。
为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:
<databaseIdProvider type="DB_VENDOR" />
如:
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
mappers(映射器)
15mappers(映射器)
映射器就是告诉 MyBatis 到哪里去找到这些语句。
有四种方式:
方式一:使用相对于类路径的资源引用
方式二:使用完全限定资源定位符(URL)
方式三:映射单个文件(XXXMapper.xml文件),注意:1.接口和mapper文件必须同名2.接口和mapper文件在同一个包下
方式四:将包内的映射器接口实现全部注册为映射器
例如:
方式一:使用相对于类路径的资源引用
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
</mappers>
方式二:使用完全限定资源定位符(URL)
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
</mappers>
方式三:引用单个文件,注意:1.接口和mapper文件必须同名2.接口和mapper文件在同一个包下
<!-- 映射单个文件 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
</mappers>
方式四:将包内的映射器接口实现全部注册为映射器
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
Mybatis常用动态sql标签
if、
where、
choose、when、otherwise(选择)
trim
foreach
sql\include
resultmap
mybatis特殊符号的处理
符号 | 转义字符 | 描述 |
---|---|---|
< | < | 小于 |
<= | <= | 小于等于 |
> | > | 大于 |
>= | >= | 大于等于 |
& | & | 和 |
’ | ’ | 单引号 |
‘’ | " | 双引号 |
解决方法: | ||
使用<![CDATA[]]>标签,包裹在外面 | ||
如: |
<if test="age != null">
<![CDATA[
age < #{age}
]]>
</if>
详细:
if 标签
if 标签 :满足 test中的条件时,拼接执行 if 中的sql语句
就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。
如:
<if test="ename!=null">
and ename like concat('%','${ename}','%')
</if>
where 标签
where 标签:相当于sql语句中的where,常结合if使用
说明:
若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的 and去掉
where标签不能去掉条件最后多余的and
会在写入where元素的地方输出一个where,
不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的处理
如果所有的条件都不满足,那么MyBatis就会查出所有的记录如果输出后是and开头的,MyBatis会把第一个and忽略
如果所有的条件都不满足,那么MyBatis就会查出所有的记录如果输出后是和开头的,MyBatis会把第一个and和忽略
如果是or开头的,MyBatis也会把它忽略
在where标签中不需要考虑空格的问题,MvBatis会智能的加上
如:
<where>
<if test="ename!=null">
and ename like '%${ename}%'
</if>
<if test="sal!=null">
and sal <![CDATA[<=]]>#{sal}
</if>
<if test="deptno!=null">
and deptno=#{deptno}
</if>
</where>
choose+when+otherwise标签
choose+when+otherwise(选择)
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。
针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
choose标签
choose标签:
按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则choose 结束。
当choose 中所有when的条件都不满则时,则执行otherwise 中的sql。
类似于Java 的switch语句,choose 为switch,when 为case,otherwise则为default。
如:
<choose>
<when test="sal !=null ">
sal <![CDATA[ <= ]]>#{sal}
</when>
<when test="ename != null">
and ename like concat('%',#{ename},'%')
</when>
<otherwise>
deptno=#{deptno}
</otherwise>
</choose>
trim标签
trim+if标签-实现添加功能
trim标签的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;
可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverides.和suffixOverrides
用于去掉或添加标签中的内容 常用属性:
prefix:在trim标签中的内容的前面添加某些内容
prefixOverrides:在trim标签中的内容的前面去掉某些内容
suffix:在trim标签中的内容的后面添加某些内容
suffixOverrides:在trim标签中的内容的后面去掉某些内容
如:
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="ename!=null">
ename,
</if>
<if test="mgr!=null">
mgr,
</if>
<if test="sal!=null">
sal,
</if>
<if test="deptno!=null">
deptno,
</if>
</trim>
set标签
set标签
set标签主要是用在更新操作的时候,它的功能和where标签差不多。
当update语句中没有使用if标签时,如果有一个参数为null,都会导致错误。
当在update语句中使用if标签时,如果前面的if没有执行,则会导致逗号多余错误。
使用set标签可以在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略。
如:
update emp
<set>
<if test="ename!=null">
ename= #{ename},
</if>
<if test="mgr!=null">
mgr= #{mgr},
</if>
<if test="sal!=null">
sal= #{sal},
</if>
<if test="deptno!=null">
deptno= #{deptno},
</if>
</set>
foreach标签-构建in条件
foreach标签-构建in条件
foreach标签主要用在构建in条件中,它可以在SQL语句中进行迭代个集合。
foreach标签的属性主要有item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置
open表示该语句以什么开始
separator表示在每次进行迭代之间以什么符号作为分隔符
close表示以什么结束
foreach标签的collection属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有以下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的参数是多个的时候,需要把它们封装成一个Map,当然单参数也可以封装成Map
实际上如果在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,
Map的key就是参数名,所以这个时候collection属性值就是传入的List或Array对象在自己封装的Map里面的key
如:
select * from emp where (empno=123 or empno=234 or empno=345)
<select id="selectEmpsByList" parameterType="java.util.List" resultType="emp">
select * from emp
<where>
<foreach collection="list" open="(" close=")" item="no" separator="or">
empno=#{no}
</foreach>
</where>
</select>
sql片段
sql片段
在实际开发中,存在大量的重复的SQL代码,通过SQL代码片段,实现SQL代码重用。
sql标签:
属性:id :sql的唯一标识
include标签
include标签
属性:refid :其值对应sql的唯一标识id
<!-- 提取相同sql代码: -->
<sql id="selectid">
select * from emp
</sql>
使用时:
<include refid="selectid"/>
多表联查
两种方案:
1.返回值用resultMap----需要在对应的实体类里面加上联查的属性
2.返回值用resultType
第1中方案需要使用resultMap标签进行自定义映射
resultMap:设置自定义映射 属性:
属性:
id:表示自定义映射的唯一标识
type:查询的数据要映射的实体类的类型 子标签:
resultMap标签内部标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
association:设置多对一的映射关系 ,即查询接结果对象中的某一个参数是另一个java对象时使用嵌套映射;
collection:设置一对多的映射关系 ,即查询接结果对象中的某一个参数是另一个java对象的list集合时使用映射;
属性:
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名
例如:
<resultMap id="uiod" type="user">
<id property="uid" column="uid"/>
<result property="address" column="address"/>
<collection property="ordersList" ofType="com.jr.entity.Orders">
<id property="oid" column="oid" />
<result property="note" column="note"/>
<collection property="orderdetailList" ofType="orderdetail">
<id property="odid" column="odid"/>
<result property="ordersid" column="orderside"/>
<association property="items" javaType="items">
<id property="iid" column="iid"/>
<result property="name" column="name"/>
</association>
</collection>
</collection>