一、SqlMapConfig.xml
(一)properties(属性)
将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
db.properties配置文件内容
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
SqlMapConfig.xml中配置
<!-- 加载属性文件 -->
<properties resource="config/db.properties"></properties>
SqlMapConfig.xml中通过${参数名}
引用db.properties文件中配置的参数
<property name="driver" value="${jdbc.driver}" />
(二)settings(全局配置参数)
主要的配置参数有如下这些,作用于整个 Mybatis :
在SqlMapConfig.xml中配置
<!-- 全局配置参数 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
(三)typeAliases(类型别名)
在 Mapper.xml 中需要定义很多的 Statement,如果在指定类型时输入类型全路径,不方便进行开发,可以针对 parameterType 或 resultType 指定的类型定义一些别名,在 SqlMapConfig.xml 中通过别名定义,方便开发。
其中 Mybatis 提供了一些默认别名的定义:
当然我们还可以自定义别名单个别名定义和批量定义
<!-- 定义别名 -->
<typeAliases>
<!-- 针对单个别名定义 -->
<typeAlias type="com.po.User" alias="user"/>
</typeAliases>
引用单个别名的定义
<insert id="insertUser" parameterType="user">
<selectKey keyProperty="id" order="AFTER" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(USERNAME,SEX,BIRTHDAY,ADDRESS) VALUES(#{username},#{sex},#{birthday},#{address})
</insert>
<!-- 定义别名 -->
<typeAliases>
<!-- 针对批量别名定义,别名就是类名(首字母大小写都可以) -->
<package name="com.po"/>
</typeAliases>
批量定义的别名的引用和单个定义的是一样的,建议使用批量别名定义各pojo的别名,提高开发效率。
(四)typeHandlers(类型处理器)
Mybatis 中通过 typeHandlers 完成 jdbc 类型和 java 类型的转换。通常情况下,Mybatis 提供的类型处理器满足日常需要,不需要自定义,如果需要定义,如下:
<!-- 类型处理器 ,不需要自定义-->
<typeHandlers>
<typeHandler handler="" javaType="" jdbcType=""/>
</typeHandlers>
Mybatis 支持类型处理器:
(五)objectFactory(对象工厂)
MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。
6. plugins(插件)
简单理解为拦截器,既然是拦截器说白了一般都是动态代理来实现对目标方法的拦截,在前后做一些操作。 在mybatis将这种东西,称之为plugin,配置在SqlMapConfig.xml 配置文件中,通过 plugins 标签配置。在Mybatis中,可以被拦截的目标主要是:
1. StatementHandler(SQL语句处理器);
2. ParameterHandler(参数处理器 );
3. ResultSetHandler(结果集处理器 );
4. Executor(执行器 );
(七) environments(环境集合属性对象)
MyBatis 可以配置多种环境。但每个数据库对应一个 SqlSessionFactory。
- environment(环境子属性对象)
<!-- 和Spring整合后environments配置将废除 -->
<environments default="development">
<environment id="development">
</environment>
</environments>
- transactionManager(事务管理)
<!-- 使用JDBC事务管理,事务控制由mybatis管理 -->
<transactionManager type="JDBC" />
- dataSource(数据源)
<!-- 数据库连接池,由mybatis管理 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
将这三个合一块就是:
<!-- 和Spring整合后environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC事务管理,事务控制由mybatis管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
(八)mappers(映射器)
Mappers 标签是用来加载映射文件的,可通过下列四种方式加载映射文件
(1)通过resource加载单个mapper
<!-- 通过resource加载 -->
<mapper resource="config/sqlmap/User.xml" />
(2)通过使用完全限定路径
<!-- 通过url加载 -->
<mapper url="config/sqlmap/User.xml" />
(3)通过mapper接口加载单个mapper
<!-- 通过mapper接口加载,但需要将接口名和映射文件名保存一致,且在同一目录 -->
<mapper class="com.dao.UserDao"/>
(4)批量加载mapper(推荐使用)
<!-- 批量加载 -->
<package name="com.po"/>
二、Mapper.xml
映射文件 Mapper.xml 是 Mybatis 的核心,映射文件中需要定义操作数据库的SQL语句,每个SQL就是一个statement。
1. insert、update、delete
三个的属性差不多,意思也一样。下面以insert为例。在实际使用过程中并不需要都进行配置,可根据自己的需要删除部分配置项。
<insert
<!-- 1. id (必须配置)
id是命名空间中的唯一标识符,可被用来代表这条语句。
一个命名空间(namespace) 对应一个dao接口,
这个id也应该对应dao里面的某个方法(相当于方法的实现),因此id 应该与方法名一致 -->
id="addUser"
<!-- 2. parameterType (可选配置, 默认为mybatis自动选择处理)
将要传入语句的参数的完全限定类名或别名, 如果不配置,mybatis会通过ParameterHandler 根据参数类型默认选择合适的typeHandler进行处理
parameterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象) -->
parameterType="user"
<!-- 3. flushCache (可选配置,默认配置为true)
将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句) -->
flushCache="true"
<!-- 4. statementType (可选配置,默认配置为PREPARED)
STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 -->
statementType="PREPARED"
<!-- 5. keyProperty (可选配置, 默认为unset)
(仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
keyProperty=""
<!-- 6. keyColumn (可选配置)
(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 -->
keyColumn=""
<!-- 7. useGeneratedKeys (可选配置, 默认为false)
(仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。 -->
useGeneratedKeys="false"
<!-- 8. timeout (可选配置, 默认为unset, 依赖驱动)
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。 -->
timeout="20" >
<!--
将插入的主键返回到user对象中(这里用的是自增主键MySQL数据库)
SELECT LAST_INSERT_ID():得到将insert进去的记录的主键值,只适用与自增主键
keyProperty:将查询到的主键设置到parameterType指定的对象的哪个属性
order:SQL语句执行的顺序,BEFORE或AFTER
-->
<selectKey keyProperty="id" order="AFTER" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(USERNAME,SEX,BIRTHDAY,ADDRESS) VALUES(#{username},#{sex},#{birthday},#{address})
</insert>
在insert时,如果数据库的主键不能自增,可以使用下面的配置来实现相同的功能:
<insert id="insertUser" parameterType="com.dy.entity.User">
<!-- 可根据其id生成策略,先获取id,在进行插入 -->
<selectKey keyProperty="id" order="BEFORE" resultType="int">
select SEQ_USER_ID.nextval as id from dual
</selectKey>
INSERT INTO USER(ID,USERNAME,SEX,BIRTHDAY,ADDRESS) VALUES(#{id},#{username},#{sex},#{birthday},#{address})
</insert>
2. select
在实际使用过程中并不需要都进行配置,可根据自己的需要删除部分配置项。
<select
<!-- 1. id (必须配置)
id是命名空间中的唯一标识符,可被用来代表这条语句。
一个命名空间(namespace) 对应一个dao接口,
这个id也应该对应dao里面的某个方法(相当于方法的实现),因此id 应该与方法名一致 -->
id="findUserById"
<!-- 2. parameterType (可选配置, 默认为mybatis自动选择处理)
将要传入语句的参数的完全限定类名或别名, 如果不配置,mybatis会通过ParameterHandler 根据参数类型默认选择合适的typeHandler进行处理
parameterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象) -->
parameterType="int"
<!-- 3. resultType (resultType 与 resultMap 二选一配置)
resultType用以指定返回类型,指定的类型可以是基本类型,可以是java容器,也可以是javabean -->
resultType="user"
<!-- 4. resultMap (resultType 与 resultMap 二选一配置)
resultMap用于引用我们通过 resultMap标签定义的映射类型,这也是mybatis组件高级复杂映射的关键 -->
resultMap="userResultMap"
<!-- 5. flushCache (可选配置)
将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false -->
flushCache="false"
<!-- 6. useCache (可选配置)
将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true -->
useCache="true"
<!-- 7. timeout (可选配置)
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)-->
timeout="10000"
<!-- 8. fetchSize (可选配置)
这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)-->
fetchSize="256"
<!-- 9. statementType (可选配置)
STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED-->
statementType="PREPARED"
<!-- 10. resultSetType (可选配置)
FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)-->
resultSetType="FORWARD_ONLY">
SELECT * FROM USER WHERE ID = #{id}
</select>
3. resultType 和 resultMap
在实际使用过程中并不需要都进行配置,可根据自己的需要删除部分配置项。
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
<select id="findUserByName" parameterType="java.lang.String"
resultType="user">
SELECT * FROM USER WHERE USERNAME LIKE '%${value}%'
</select>
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。步骤:
1、定义resultMap
2、使用resultMap作为statement的输出映射类型
<!-- 定义查询订单及关联用户信息结果的resultMap -->
<resultMap type="com.po.Orders" id="OrdersResultMap">
<!-- 配置映射的订单信息 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
</resultMap>
<!-- 使用resultMap -->
<select id="findOrdersUserResultMap" resultMap="OrdersResultMap">
SELECT
ORDERS.*
FROM
ORDERS,
USER u
WHERE
ORDERS.user_id = u.ID
</select>
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
4. resultType 和 resultMap 的区别
resultType:实现简单,查询出来的列名不包含在POJO中需增加列名对应的属性才能完成映射。如果没有查询结果的特殊要求建议使用resultType。
resultMap:需单独定义resultMap,实现麻烦,但如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。
resultMap可实现延迟加载,而 resultType无法实现。
[1] Mybatis中Mapper映射文件详解 https://blog.csdn.net/majinggogogo/article/details/72123185