这篇文章主要介绍了 mybatis映射文件实例详解,需要的朋友可以参考下
一、输入映射
parametertype
指定输入参数的java类型,可以使用别名或者类的全限定名。它可以接收简单类型、pojo、hashmap。
1、传递简单类型
根据用户id查询用户信息:
<select id="finduserbyid" parametertype="int" resulttype="com.itheima.mybatis.po.user">
select * from user where id =#{id}
</select>
2、传递pojo对象
添加用户:
<insert id="insertuser" parametertype="com.itheima.mybatis.po.user">
<selectkey keyproperty="id" resulttype="int" order="after">
select last_insert_id()
</selectkey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
3、传递pojo包装对象
开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),
这时可以使用包装对象传递输入参数。
3.1需求
综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。
3.2 定义包装对象
一般user.java类要和数据表表字段一致,最好不要在这里面添加其他字段,在mybatis的逆向工程时,会根据表结构,生成po类,
如果在po类中扩展字段,此时会被覆盖掉。
所以针对要扩展的po类,我们需要创建一个扩展类,来继承它。
public class userext extends user{
//这里可以定义user的一些扩展信息
}
定义pojo包装类:
public class userqueryvo {
//用户信息
private userext userext;
//商品id集合
private list<integer> idlist;
//商品信息
public list<integer> getidlist() {
return idlist;
}
public void setidlist(list<integer> idlist) {
this.idlist = idlist;
}
public userext getuserext() {
return userext;
}
public void setuserext(userext userext) {
this.userext = userext;
}
//订单信息
}
3.3编写mapper接口
//通过包装类来进行复杂的用户信息综合查询
public list<userext> finduserlist(userqueryvo userqueryvo);
3.4编写mapper映射文件
<!-- 通过包装类来进行复杂的用户信息综合查询 -->
<select id="finduserlist" parametertype="userqueryvo" resulttype="userext">
select * from user where sex=#{userext.sex} and username like '%${userext.username}%'
</select>
注意:入参的类型变为userqueryvo、结果集的类型变为userext,#{}里面的参数变为userqueryvo对象中的userext属性的sex和username子属性。
3.5编写测试代码
@test
public void finduserlisttest() {
// 创建sqlsession
sqlsession sqlsession = sqlsessionfactory.opensession();
// 通过sqlsession,获取mapper接口的动态代理对象
usermapper usermapper = sqlsession.getmapper(usermapper.class);
//构造userqueryvo对象
userqueryvo userqueryvo = new userqueryvo();
// 构造userext对象
userext userext = new userext();
userext.setsex("1");
userext.setusername("小明");
userqueryvo.setuserext(userext);
// 调用mapper对象的方法
list<userext> list = usermapper.finduserlist(userqueryvo);
system.out.println(list);
// 关闭sqlsession
sqlsession.close();
}
4、传递hashmap
同传递pojo对象一样,map的key相当于pojo的属性。
4.1映射文件
<!-- 传递hashmap综合查询用户信息 -->
<select id="finduserbyhashmap" parametertype="hashmap" resulttype="user">
select * from user where id=#{<span style="color:#ff0000;">id</span>} and username like '%${<span style="color:#ff0000;">username</span>}%'
</select>
上边红色标注的id和username是hashmap的key。
4.2测试代码
public void testfinduserbyhashmap()throws exception{
//获取session
sqlsession session = sqlsessionfactory.opensession();
//获限mapper接口实例
usermapper usermapper = session.getmapper(usermapper.class);
//构造查询条件hashmap对象
hashmap<string, object> map = new hashmap<string, object>();
map.put("id", 1);
map.put("username", "管理员");
//传递hashmap对象查询用户列表
list<user>list = usermapper.finduserbyhashmap(map);
//关闭session
session.close();
}
异常测试:
传递的map中的key和sql中解析的key不一致。
测试结果没有报错,只是通过key获取值为空。
二、输出映射
1、resulttype
(1)使用方法
使用resulttype进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功。
如果查询的列名和映射的pojo属性名全部不一致,那么映射的对象为空,不会创建pojo对象;
如果查询的列名和映射的pojo属性名有一个一致,那么映射的对象不为空,会创建pojo对象,但是只有映射正确的那一个属性才有值。
(2)输出简单类型
注意,对简单类型的结果映射也是有要求的,查询的列必须是一列,才能映射为简单类型。
当输出结果只有一列时,可以使用resulttype指定简单类型作为输出结果类型。
2.1需求
综合查询用户总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。
2.2mapper映射文件
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="finduserscount" parametertype="userqueryvo"
resulttype="int">
select count(1) from user where sex = #{userext.sex} and username like '%${userext.username}%'
</select>
2.3mapper接口
//综合查询用户信息总数。学习:resulttype输出简单类型
public int finduserscount(userqueryvo vo);
2.4测试代码
@test
public void testfinduserscount() {
// 创建sqlsession
sqlsession sqlsession = sqlsessionfactory.opensession();
// 通过sqlsession,获取mapper接口的动态代理对象
usermapper usermapper = sqlsession.getmapper(usermapper.class);
//构造userqueryvo对象
userqueryvo userqueryvo = new userqueryvo();
// 构造userext对象
userext userext = new userext();
userext.setsex("1");
userext.setusername("小明");
userqueryvo.setuserext(userext);
int count = mapper.finduserscount(userqueryvo);
system.out.println(count); // 关闭sqlsession
sqlsession.close();
}
(3)输出pojo单个对象和列表
注意:输出单个pojo对象和pojo列表(盛放pojo对象)时,mapper映射文件中的resulttype的类型是一样的,mapper接口的方法返回值不同。
3.1mapper映射文件
<select id="findusersbyname" parametertype="java.lang.string" resulttype="cn.itcast.mybatis.po.user">
select * from user where username like '%${value}%'
</select>
3.2mapper接口
1、输出单个pojo对象
//根据用户名称来模糊查询用户信息
public user findusersbyname(string username);
2、输出pojo列表
//根据用户名称来模糊查询用户信息列表
public list<user> findusersbyname(string username);
总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,
会根据返回值的类型,决定调用selectone方法还是selectlist方法。
2、resultmap
resultmap可以进行高级结果映射(一对一、一对多映射)。
(1)使用方法
如果查询出来的列名和属性名不一致,通过定义一个resultmap将列名和pojo属性名之间作一个映射关系。
1、 定义resultmap
2、 使用resultmap作为statement的输出映射类型。
(2)需求
把下面sql的输出结果集进行映射
select id id_,username username_,sex sex_from user where id = 1
(3)mapper映射文件
定义resultmap:
<!-- 定义resultmap -->
<!--
[id]:定义resultmap的唯一标识
[type]:定义该resultmap最终映射的pojo对象
[id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签
[result标签]:映射结果集的普通列
[column]:sql查询的列名,如果列有别名,则该处填写别名
[property]:pojo对象的属性名
-->
<resultmap type="user" id="userresultmap">
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="sex_" property="sex"/>
</resultmap>
定义statement:
<!-- 根据id查询用户信息(学习resultmap) -->
<select id="finduserbyidresultmap" parametertype="int" resultmap="userresultmap">
select id id_,username username_,sex sex_ from user where id = #{id}
</select>
(4)mapper接口定义
//根据id查询用户信息(学习resultmap)
public user finduserbyidresultmap(int id);<strong>
</strong>
定义statement使用resultmap映射结果集时,mapper接口定义方法的返回值类型为mapper映射文件中resultmap的type类型。
(5)测试代码
@test
public void finduserbyidresultmaptest() {
// 创建sqlsession
sqlsession sqlsession = sqlsessionfactory.opensession();
// 通过sqlsession,获取mapper接口的动态代理对象
usermapper usermapper = sqlsession.getmapper(usermapper.class);
// 调用mapper对象的方法
user user = usermapper.finduserbyidresultmap(1);
system.out.println(user);
// 关闭sqlsession
sqlsession.close();
}
三、动态sql
1、if和where
ø if标签:作为判断入参来使用的,如果符合条件,则把if标签体内的sql拼接上。
注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘';
ø where标签:会去掉条件中的第一个and符号。
(1)需求
用户信息综合查询列表和用户信息综合查询总数这两个statement的定义使用动态sql。
(2)映射文件
<!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="findusersbyqueryvo" parametertype="cn.itcast.mybatis.po.queryuservo"
resulttype="user">
select * from user
<where>
<if test="userext != null">
<if test="userext.sex != null and userext.sex != ''">
and sex = #{userext.sex}
</if>
<if test="userext.username != null and userext.username != ''">
and username like '%${userext.username}%'
</if>
</if>
</where>
</select>
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="finduserscount" parametertype="queryuservo"
resulttype="int">
select count(1) from user
<where>
<if test="userext != null">
<if test="userext.sex != null and userext.sex != ''">
and sex = #{userext.sex}
</if>
<if test="userext.username != null and userext.username != ''">
and username like '%${userext.username}%'
</if>
</if>
</where>
</select>
(3)mapper接口
//通过包装类来进行复杂的用户信息综合查询
public list<userext> finduserlist(userqueryvo userqueryvo);
//综合查询用户总数
public int finduserscount(userqueryvo userqueryvo);
(4)测试代码
不传用户名:
@test
public void testfinduserlist() throws exception{
// 创建usermapper对象
sqlsession sqlsession = sqlsessionfactory.opensession();
// 由mybatis通过sqlsession来创建代理对象
usermapper mapper = sqlsession.getmapper(usermapper.class);
queryuservo vo = new queryuservo();
user user = new user();
//此处使用动态sql,不传username参数
user.setsex("1");
// user.setusername("小明");
vo.setuser(user);
list<user> list = mapper.finduserlist(vo);
system.out.println(user);
sqlsession.close();
}
输出的sql如下(也不包含用户名):
通过测试可以得知,打印出的sql语句确实会随着条件的满足情况而不一样。
2、sql片段
mybatis提供了sql片段的功能,可以提高sql的可重用性。
2.1定义sql片段
使用sql标签来定义一个sql片段:
<!-- 定义sql片段 -->
<!--
[sql标签]:定义一个sql片段
[id]:sql片段的唯一标识
建议:
1、sql片段中的内容最好是以单表来定义
2、如果是查询字段,则不要写上select
3、如果是条件语句,则不要写上where
-->
<sql id="select_user_where">
<if test="userext != null">
<if test="userext.sex != null and userext.sex != ''">
and sex = #{userext.sex}
</if>
<if test="userext.username != null and userext.username != ''">
and username like '%${userext.username}%'
</if>
</if>
</sql>
2.2引用sql片段
使用<includerefid='' /> 来引用sql片段:
<!-- 根据用户id来查询用户信息(使用sql片段) -->
<!--
[include标签]:引用已经定义好的sql片段
[refid]:引用的sql片段id
-->
<select id="finduserlist" parametertype="userqueryvo" resulttype="userext">
select * from user
<where>
<include refid="select_user_where"/>
</where>
</select>
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
<select id="finduserscount" parametertype="queryuservo"
resulttype="int">
select count(1) from user
<where>
<include refid="select_user_where"/>
</where>
</select>
3、foreach
向sql传递数组或list时,mybatis使用foreach解析数组里的参数并拼接到sql中。
(1)传递pojo对象中的list集合
1.1需求
在用户查询列表和查询总数的statement中增加多个id输入查询。
1.2sql
select * from user where id in (1,10,16)
1.3定义pojo中的list属性
package com.itheima.mybatis.po;
import java.util.list;
/**
* <p>title: userqueryvo</p>
* <p>description: todo(这里用一句话描述这个类的作用) <p>
*/
public class userqueryvo {
//用户信息
private userext userext;
//商品id集合
private list<integer> idlist;
//商品信息
public list<integer> getidlist() {
return idlist;
}
public void setidlist(list<integer> idlist) {
this.idlist = idlist;
}
public userext getuserext() {
return userext;
}
public void setuserext(userext userext) {
this.userext = userext;
}
//订单信息
}
1.4映射文件
<!-- [foreach标签]:表示一个foreach循环 -->
<!-- [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 -->
<!-- [item]:每次遍历出来的对象 -->
<!-- [open]:开始遍历时拼接的串 -->
<!-- [close]:结束遍历时拼接的串 -->
<!-- [separator]:遍历出的每个对象之间需要拼接的字符 -->
<if test="idlist != null and idlist.size > 0">
<foreach collection="idlist" item="id" open="and id in (" close=")" separator=",">
#{id}
</foreach>
</if>
1.5mapper接口
//根据用户id的集合查询用户列表(学习foreach标签之通过pojo对象传id集合)
public list<userext> finduserlist(userqueryvo vo);
1.6测试代码
@test
public void testfinduserlist() {
// 创建sqlsession
sqlsession sqlsession = sqlsessionfactory.opensession();
// 通过sqlsession,获取mapper接口的动态代理对象
usermapper mapper = sqlsession.getmapper(usermapper.class);
// 构造queryuservo对象
queryuservo vo = new queryuservo();
// userext ext = new userext();
// ext.setusername("小明");
// ext.setsex("1");
// vo.setuserext(ext);
// 创建用户id集合,然后设置到queryuservo对象中
list<integer> idlist = new arraylist<integer>();
idlist.add(1);
idlist.add(10);
idlist.add(16);
vo.setidlist(idlist);
// 调用mapper代理对象的方法
list<userext> list = mapper.finduserlist(vo);
system.out.println(list);
// 关闭sqlsession
sqlsession.close();
}
(2)直接传递list集合
2.1需求
根据用户id的集合查询用户列表
2.2sql
select * from user where id in (1,10,16)
2.3映射文件
<!-- 根据用户id的集合查询用户列表(学习foreach标签之直接传id集合) -->
<!--
[foreach标签]:表示一个foreach循环
[collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。
[item]:定义遍历集合之后的参数名称
[open]:开始遍历之前需要拼接的sql串
[close]:结束遍历之后需要拼接的sql串
[separator]:遍历出的每个对象之间需要拼接的字符
-->
<select id="findusersbyidlist" parametertype="java.util.list" resulttype="user">
select * from user
<where>
<if test="list != null and list.size > 0">
<foreach collection="list" item="id" open="and id in (" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
2.4mapper接口
//根据用户id的集合查询用户列表(学习foreach标签之直接传id集合)
public list<user> findusersbyidlist (list<integer> idlist);
2.5测试代码
@test
public void findusersbyidlisttest() {
// 创建sqlsession
sqlsession sqlsession = sqlsessionfactory.opensession();
// 通过sqlsession,获取mapper接口的动态代理对象
usermapper usermapper = sqlsession.getmapper(usermapper.class);
// 构造list<integer>集合
list<integer> idlist = new arraylist<integer>();
idlist.add(1);
idlist.add(10);
idlist.add(16);
// 调用mapper对象的方法
list<user> list = usermapper.findusersbyidlist (idlist);
system.out.println(list);
// 关闭sqlsession
sqlsession.close();
}
以上就是mybatis映射文件的实例代码详解的详细内容。