首页 > 开发 > Java > 正文

Mybatis映射文件实例详解

2024-07-13 10:03:48
字体:
来源:转载
供稿:网友

 一、输入映射

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映射文件实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对VeVb武林网网站的支持!


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表