5 ,SqlMapConfig.xml
mybatis的全局配置文件SqlMapConfig.xml,配置内容如下,
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
tpeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environment s(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mapper(映射器)
5.1 propertie属性
需求:
将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。
<!-- 加载属性文件 -->
<properties resource="db.properties">
<!-- properties中还可以配置一些属性名和属性值 -->
<!-- <property name="" value=""/> -->
</properties>
在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在db.properties中,方便对参数进行统一管理,其他的xml可以引用该db.properties.
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
jdbc.username=root
jdbc.password=
properties特性:
注意:Mybatis将按照下面的顺序来加载属性:
1.在properties 元素体内resource或url加载的属性,它会覆盖已读取的同名属性。
2,然后会取properties元素中resource中或url加载的属性,它会覆盖已读的同名属性
3,最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
因此,通过parameterType传递的属性具有最高优先级,resource或url加载的属性此致,最低优先级是properties元素体内定义你的属性。
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名有一定特殊性,比如xxxx.xxxx.
5.2 setting全局参数配置
mybatis框架在运行时可以调整一些运行参数。
比如:开启二级缓存,开启延迟加载。。
5.3 typeAliases(别名)重点
5.3.1需求
在mapper.xml中,定义很多statement,statement需要parameterType指定输入参数的类型,需要resultType指定输出结果的类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
5.3.3自定义别名
5.3.3.1 单个别名的定义
<!-- 针对单个别名定义
type:类型呢路径
alias:别名
-->
<typeAlias type="cn.itcast.po.User" alias="user"/>
5.3.3.2 引用别名
<select id="findUserById" parameterType="int" resultType="user">
select * from users where uid=#{id}
</select>
5.3.3.4 批量定义(常用)
<!-- 批量别名定义
指定包名,mybatis自动扫描包中欧冠的po类,自动定义别名,别名就是类名(首字母大写或小写都可以) -->
<package name="cn.itcast.po"/>
</typeAliases>
5.4 typeHandlers(类型处理器)
mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
5.5 mapper(映射配置)
5.5.1 通过resource加载单个映射文件
<!-- 加载映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
5.5.2 通过mapper接口加载
<!-- 通过mapper接口加载单个映射文件
通过一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中,(结构中,将config/mapper/UserMapper.xml移动到了cn.itcast.mybatis.mapper下)
上边规范的前提是,使用mapper代理方法 -->
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
按照上边的规范,将mapper.java和mapper.xml放在一个目录,且同名。
5.5.3 批量加载mapper(常用)
<!-- 批量加载mapper
指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载,
遵循一些规范,需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中,
上边规范的前提是:使用mapper代理方法 -->
<package name="cn.itcast.mybatis.mapper"/>
6输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型
6.1 传递pojo的包装对象
6.1.1 需求
完成用户信息的综合查询,需要传入查询条件(肯能包括用户信息,其他信息,比如商品、订单的信息)
6.1.2 定义包装类型pojo
针对上边的额需求,建议使用自定义的包装类型的pojo。
在包装类型的pojo中将复杂的查询条件包装进去。
package cn.itcast.po;
import java.util.List;
public class UserQueryVo {
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
//用户查询条件
private UserCustom userCustom;
public UserCustom getUserCustom() {
return userCustom;
}
public void setUserCustomer(UserCustom userCustom) {
this.userCustom = userCustom;
}
//可以扩展包装其他查询条件,订单,商品
}
6.1.3 mapper.xml
在UserMapper.xml中定义用户信息综合查询(查询条件,通过高级查询进行复杂关联查询)。
<!-- 用户信息综合查询
#{userCustomer.password}:取出pojo包装类对象中password值
${}
-->
<select id="findUserList" parameterType="cn.itcast.po.UserQueryVo"
resultType="cn.itcast.po.UserCustom">
select * from users<!--select * from users where password=#{userCustom.password} and username like '%${userCustom.username}%' -->
<!-- where可以自动去掉条件中的第一个and -->
<where>
<!-- 引用 调用sql片段的id,如果refid指定的id不再本mapper文件中,需要前边加namespace-->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其他sql片段 -->
</where>
</select>
6.1.4 mapper.java
// 用户信息的综合查询
@Test
public void testFindUserList()throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);//重点
/* 创建包装对象,设置查询条件*/
UserQueryVo userQueryVo =new UserQueryVo();
UserCustom userCustom = new UserCustom();
//由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
//userCustom.setUsername("AsaA");
userCustom.setPassword("666");
//传入多个id
List<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
//将ids传入statement中
userQueryVo.setIds(ids);
userQueryVo.setUserCustomer(userCustom);
//调用UserMapper的方法
List<UserCustom> list=userMapper.findUserList(userQueryVo);
sqlSession.close();
System.out.println(list);
}
7 输出映射
7.1 resutlType
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象,只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
7.1.1 输出简单类型
7.1.1.1需求用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。
7.1.1.2 mapper.xml
<!-- 用户信息综合查询总数
parameterType:指定输入类型和findUserList一样
resultType:输出的结果类型
-->
<select id="findUserCount" parameterType="cn.itcast.po.UserQueryVo" resultType="int">
<!-- select count(*) from users where password=#{userCustom.password} and username like '%${userCustom.username}%' -->
select count(*) from users
<where>
<if test="userCustom!=null">
<if test="userCustom.password!=null and userCustom.password!=''">
users.password=#{userCustom.password}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
users.username=#{userCustom.username}
</if>
</if>
</where>
</select>
7.1.1.3 mapper.java
//用户信息综合查询总数
public int findUserCount(UserQueryVo userQueryVo)throws Exception;
7.2 resultMap
mybatis中使用resultMap完成高级输出结果映射
7.2.1 resultMap使用方法
如果查询出来的额列名和pojo属性名不一致,通过定义一个resultMap对列和pojo属性名之间作一个映射关系。
1,定义resultMap
2,使用resultMap作为statement的输出映射类型
7.2.2 将下边的sql使用User完成映射
select uid uid_,username username_,from users where uid=#{value}
user类中属性名和上边查询列名不一致。
7.2.2.1 定义resultMap
<!--定义resultMap
将select uid _uid,username username_ from users 和Userr类中的属性作一个映射关系
type:resultMap最终映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap type="user" id="userResultMap">
<!-- id表示查询结果集中唯一标识
column:查询出来的列名
property:type所指定的pojo类型中的属性名
最终resultMap对column和property作一个映射关系(对应关系)
-->
<id column="uid_" property="uid"/>
<!-- result:对普通名映射定义
column:查询出来的列名
property:type所指定的pojo类型中的属性名
最终resultMap对column和property作一个映射关系(对应关系)
-->
<result column="username_" property="username"/>
</resultMap>
7.2.2.2 使用resultMap作为statement的输出映射类型
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
select uid uid_, username username_,password from users where uid=#{id}
</select>
7.3 小结
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功,如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系。
8 动态sql
8.1 什么是动态sql
mybatis 核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活凭借,组装。
8.2 需求
用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
对查询条件进行判断,如果输入参数不为空才进行
8.3 mapper.xml
<select id="findUserList" parameterType="cn.itcast.po.UserQueryVo"
resultType="cn.itcast.po.UserCustom">
select * from users<!--select * from users where password=#{userCustom.password} and username like '%${userCustom.username}%' -->
<!-- where可以自动去掉条件中的第一个and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.password!=null and userCustom.password!=''">
users.password=#{userCustom.password}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
users.username=#{userCustom.username}
</if>
</if>
</where>
</select>
8.4.1测试代码
// 用户信息的综合查询
@Test
public void testFindUserList()throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);//重点
/* 创建包装对象,设置查询条件*/
UserQueryVo userQueryVo =new UserQueryVo();
UserCustom userCustom = new UserCustom();
//由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
//userCustom.setUsername("AsaA");
userCustom.setPassword("666");
//传入多个id
List<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
//将ids传入statement中
userQueryVo.setIds(ids);
userQueryVo.setUserCustomer(userCustom);
//调用UserMapper的方法
List<UserCustom> list=userMapper.findUserList(userQueryVo);
sqlSession.close();
System.out.println(list);
}
8.5 sql片段
8.5.1需求
将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其他statement中就可以引用sql片段。
8.5.2 定义sql片段
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.password!=null and userCustom.password!=''">
users.password=#{userCustom.password}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
users.username=#{userCustom.username}
</if>
</if>
8.5.3 引用sql片段
在mapper.xml中定义的statement中引用sql片段。
<!-- 用户信息综合查询
#{userCustomer.password}:取出pojo包装类对象中password值
${}
-->
<select id="findUserList" parameterType="cn.itcast.po.UserQueryVo"
resultType="cn.itcast.po.UserCustom">
select * from users<!--select * from users where password=#{userCustom.password} and username like '%${userCustom.username}%' -->
<!-- where可以自动去掉条件中的第一个and -->
<where>
<!-- 引用 调用sql片段的id,如果refid指定的id不再本mapper文件中,需要前边加namespace-->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其他sql片段 -->
</where>
</select>
8.6 foreach
向sql传递数组或list,mybatis使用foreach解析,如下:
8.6.1 需求
在用户查询列表和查询总数的statement中增加多个id输入查询。
sql语句如下
两种方法:
select * from users where id=1 or id=2 or id =3
select * form users where id in(1,2,3)
8.1.2 在输入参数类型中添加List<Integer> ids传入多个id
package cn.itcast.po;
import java.util.List;
public class UserQueryVo {
//传入多个id
private List<Integer> ids;
//在这里包装需要的查询条件,包装类型
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
//用户查询条件
private UserCustom userCustom;
public UserCustom getUserCustom() {
return userCustom;
}
public void setUserCustomer(UserCustom userCustom) {
this.userCustom = userCustom;
}
//可以扩展包装其他查询条件,订单,商品
}
8.1.3 修改mapper.xml
where id=1 or id=2 or id=3
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.password!=null and userCustom.password!=''">
users.password=#{userCustom.password}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
users.username=#{userCustom.username}
</if>
</if>
<if test="ids!=null">
<!-- 使用foreacch遍历传入的id -->
<!-- 使用foreach遍历传入的ids
collection:指定输入对象中集合属性
item:每个遍历生成的对象
open:开始遍历时拼接串
close:结束遍历时拼接的串
separator:遍历的两个对象中间需要拼接的串
and (id=1 or id=2 or id=3)
-->
<!-- 使用实现下边的sql拼接 -->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每个遍历需要拼接的串 -->
uid=#{user_id}
</foreach>
</if>
</sql>
8.1.4 测试代码
// 用户信息的综合查询
@Test
public void testFindUserList()throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建UserMapper对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);//重点
/* 创建包装对象,设置查询条件*/
UserQueryVo userQueryVo =new UserQueryVo();
UserCustom userCustom = new UserCustom();
//由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
//userCustom.setUsername("AsaA");
userCustom.setPassword("666");
//传入多个id
List<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
//将ids传入statement中
userQueryVo.setIds(ids);
userQueryVo.setUserCustomer(userCustom);
//调用UserMapper的方法
List<UserCustom> list=userMapper.findUserList(userQueryVo);
sqlSession.close();
System.out.println(list);
}
另一个sql的实现
<!-- 实现 and id in (1,2,3) 拼接 -->
<!-- <foreach collection="ids" item="user_id" open="AND id in (" close=")" separator=",">
每个遍历需要拼接的串
#{user_id}