本次主要来了解:
- MyBatis数据库配置文件SqlMapConfig.xml
- SQL映射配置中输入映射的配置
- SQL映射配置中输出映射的配置
- SQL映射配置中动态SQL语句的配置
1. SqlMapConfig配置文件详解
主要来配置MyBatis的一些核心信息。
配置名称 | 配置含义 | 配置简介 |
---|---|---|
configuration | 包裹所有配置标签 | 整个配置文件的顶级标签 |
properties | 属性 | 该标签可以引入外部配置的属性,也可以自己配置。该配置标签所在的同一个配置文件中的其他配置均可引用次配置中的属性 |
setting | 全局配置参数 | 用来配置一些改变运行时行为的信息。例如是否使用缓存机制,是否使用延迟加载,是否使用错误处理机制等。并且可以设置最大并发请求数量、最大并发事务数量,以及是否启用命名空间等。 |
typeAliases | 类型别名 | 用来设置一些别名来替代Java的长类型声明(如: java.lang.int变为int),减少配置编码的冗余 |
typeHandlers | 类型处理器 | 将SQL中返回的数据库类型转换为相应的Java类型的处理器配置 |
objectFactory | 对象工厂 | 实例化目标类的工厂类配置 |
plugins | 插件 | 可以通过插件修改MyBatis的核心行为,例如对语句执行的某一点进行拦截调用 |
environments | 环境集合属性对象 | 数据库环境配置的详细配置 |
environment | 环境子属性对象 | 数据库环境的配置信息 |
transactionManager | 事务管理 | 指定MyBatis的事务管理器 |
dataSource | 数据源 | 使用其中的type指定数据源的连接类型,在标签对中可以使用property属性指定数据库连接池的其他信息 |
mappers | 映射器 | 配置SQL映射文件的位置,告知MyBatis去哪里加载SQL映射配置 |
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--配置一个全部参数的样例-->
<configuration>
<!--1. properties属性引入外部配置文件-->
<properties resource="jdbc.properties">
<!--property里面的属性全局均可使用-->
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>
<!--2. 全局配置参数-->
<settings>
<!--设置是否启用缓存-->
<setting name="cacheEnabled" value="true"/>
<!--设置是否启用懒加载-->
<setting name="lazyLoadingEndbled" value="true"/>
</settings>
<!--3.别名设置-->
<typeAliases>
<typeAlias alias="user" type="cn.com.mybatis.po.User"/>
<typeAlias alias="integer" type="java.lang.Integer"/>
</typeAliases>
<!--4.类型转换器-->
<typeHandlers>
<!--一个简单的类型转换器-->
<typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>
</typeHandlers>
<!--5.对象工厂-->
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<!--对象工厂注入的参数-->
<property name="someProperty" value="100"/>
</objectFactory>
<!--6.插件-->
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
<!--7.environments数据库环境配置-->
<!--和Spring整合后environments配置将被废除-->
<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>
<!--加载映射文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/OtherMapper.xml"/>
</mappers>
</configuration>
关于SqlMapConfig.xml各个配置名称的详细说明请访问
:MyBatis配置文件详解
2. Mapper映射文件
Mapper映射文件,主要就是用来配置SQL映射语句的,根据不同的SQL语句性质,要使用不同的标签来包裹。
Mapper配置文件标签:
标签名称 | 标签作用 |
---|---|
insert | 用来映射插入语句 |
update | 用来映射更新语句 |
delete | 用来映射删除语句 |
select | 用来映射查询语句 |
resultMap | 用来将从数据库结果集取出的数据映射到相应的实体对象的相应字段中 |
sql | 配置可以被其他语句引用的SQL语句块 |
cache | 给定命名空间的缓存配置 |
cache-ref | 其他命名空间缓存配置的引用 |
parameterMap | 参数映射,该配置现已被抛弃 |
select、insert、delete、update样例:
<!--跟据用户id进行查找-->
<select id="findUserById" parameterType="int" resultType="cn.com.mybatis.po.User">
SELECT * FROM USER WHERE id=#{id}
</select>
<!--根据用户姓名进行模糊查询-->
<select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.com.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}'
</select>
<!--在表中新增数据信息-->
<insert id="insertUser" parameterType="cn.com.mybatis.po.User">
INSERT INTO USER(username, password, gender, birthday, email, province, city)
VALUE (#{username}, #{password}, #{gender}, #{birthday,jdbcType=DATE}, #{email}, #{province}, #{city})
</insert>
<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM USER WHERE id=#{id}
</delete>
<!--修改用户-->
<update id="updateUserName" parameterType="cn.com.mybatis.po.User">
UPDATE USER SET username=#{username} where id=#{id}
</update>
关于mapper.xml各个配置文件的详细说明请访问
:Mapper XML文件详解
3. Mapper配置动态SQL语句
- 在Mapper配置文件中,有时候需要根据一些查询条件来选择不同的SQL语句,或者将一些使用频率极高的SQL语句单独配置,在需要的地方引用。MyBatis提供了一种可以根据条件动态配置SQL语句,以及单独配置SQL语句块的机制。
- 当查询语句的查询条件由于输入参数的不同而无法确切定义时,可以使用“<where>”标签对来包裹需要动态指定的SQL查询条件,而在“<where>”标签对中,可以使用“<if test=”…”>”条件来分情况设置SQL查询条件。
下面的样例设置了,当输入参数的Java包装类中含有的条件不同时,查询条件可动态变化:
<select id="findUserList" parameterType="cn.com.mybatis.po.UserQueryVo" resultType="cn.com.mybatis.po.User">
SELECT * FROM USER
<where>
<if test="UserQueryVo != null">
<if test="UserQueryVo.gender != null and UserQueryVo.gender != ''">
AND user.gender = #{UserQueryVo.gender}
</if>
<if test="UserQueryVo.username != null and UserQueryVo.username != ''">
AND user.username LIKE '%${UserQueryVo.username}%'
</if>
</if>
</where>
</select>
上面的输入参数为封装了查询条件的包装类,在查询条件中使用了动态配置,当性别gender、username不为空时,将其作为查询条件之一,若其中一个为空,不将其作为查询条件。值得注意的是,当使用“<where>”标签对包裹if条件语句时,将会忽略查询条件中的第一个“and”(这样才能组成一个可执行的SQL语句)。
另外,可以将复用性比较强的SQL语句封装成SQL片段,在需要使用该SQl片段的映射配置中声明一下,即可引入该SQL语句。声明如下:
<sql id="query_user_where">
<!--要复用的SQL语句-->
</sql>
其中id是SQL片段的唯一标识,是不可重复的。SQL片段支持动态SQL语句,但不支持“<where>”标签。
下面示例将上面的SQL语句的查询条件封装为一个“SQL片段”,然后可供所有的SQL映射配置使用:
<!--用户信息综合查询-->
<select id="findUserList" parameterType="cn.com.mybatis.po.UserQueryVo" resultType="cn.com.mybatis.po.User">
SELECT * FROM USER
<where>
<include refid="query_user_where"></include>
<!--在这里可能还要引用其他的SQL片段-->
</where>
</select>
<!--用户信息综合查询总数-->
<select id="findUserCount" parameterType="cn.com.mybatis.po.UserQueryVo" resultType="int">
SELECT COUNT(*) FROM USER
<where>
<include refid="query_user_where"></include>
<!--在这里可能还要引用其他的SQL片段-->
</where>
</select>
这里的<include>标签还可以引用外部mapper.xml文件的SQL片段,refid只需写成该文件的namespace.sql_id (如:test.query_user_where)
语句包含多个查询信息情况(如查询id为2、4、6的User用户)
SELECT * FROM USER WHERE id=2 OR id=4 OR id=6
<!--或者如下格式-->
SELECT * FROM USER WHERE id IN (2,4,6)
而此时如果在Mapper文件中配置这样的语句,则需要向SQL配置传递一个数组或者List类型的输入参数,然后MyBatis使用“<foreach>”标签去遍历并解析这些数组或List中的值。
示例:
首先输入参数是一个Java包装类,其属性为一个包含多个id信息的List集合:
pubic class UserQueryVo{
//多个id
private List<Integer> ids;
public List<Integer> getIds(){
return ids;
}
public void setIds(List<Integer> ids){
this.ids = ids;
}
}
在Mapper中配置一个包含foreach查询条件的动态SQL片段,并在查询SQL映射中引入它:
<sql id="query_user_where">
<if test="ids != null">
<!--实现SQL拼接 where (id=1 or id=3 or id=5)-->
<foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
<!--每次遍历要拼接的串-->
id=#{user_id}
</foreach>
</if>
</sql>
<!--用户信息综合查询-->
<select id="findUserList" parameterType="cn.com.mybatis.po.UserQueryVo" resultType="cn.com.mybatis.po.User">
SELECT * FROM USER
<where>
<include refid="query_user_where"></include>
<!--在这里可能还要引用其他的SQL片段-->
</where>
</select>
上面示例使用foreach遍历传入的ids查询参数,在foreach标签中:
- collection指定输入对象中的集合属性;
- item为每次遍历生成的对象名;
- open为开始遍历时要拼接的串;
- close为结束遍历时要拼接的串;
- separator为遍历的两个对象中间需要拼接的串。
上面示例拼出的效果为:“where (id=2 or id=4 or id=6)”
当然,实现“where id in (2,4,6)” 效果的配置与此类似,只要将拼接前缀open属性改成“and id in(”,separator改为“,”,标签对中的标签改为“#{user_id}”,即可:
<foreach collection="ids" item="user_id" open="and id in(" close=")" separator=",">
<!--每次遍历要拼接的串-->
#{user_id}
</foreach>
注: 在SQL片段里的“and”用来拼接已有一个或多个查询条件的语句,当此语句为第一个查询条件是,会因为“<where>”的存在而屏蔽第一个“and”。