欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis映射文件实例详解

程序员文章站 2024-03-08 00:02:15
 一、输入映射 parametertype 指定输入参数的java类型,可以使用别名或者类的全限定名。它可以接收简单类型、pojo、hashmap。 1、传...

 一、输入映射

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映射文件实例详解,希望对大家有所帮助