Mybatis的参数深入

Mybatis的参数深入

  • Mybatis的映射文件其实就是与DAO相对应,因为DAO中的方法有输入参数及返回结果,那么在Mybatis的映射文件中自然也就有与之对应的参数和返回结果。
  • 在Mybatis的映射文件中参数用parameterType来代表,它的值可以是基本类型,也可以是包装的对象,在Mybatis的映射文件中返回结果用resultType或resultMap来代表。

2.1 Mybatis的参数

2.1.1 parameterType(输入类型)

2.1.2 传递简单类型

2.1.3 传递pojo对象

Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

2.1.4 传递pojo包装对象

开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

Pojo类中包含pojo。
需求:根据用户名查询用户信息,查询条件放到QueryVo的user属性中。

2.1.4.1 QueryVo封装

public class QueryVo { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }

2.1.4.2 UserMapper接口

在UserMapper接口中加入如下方法:


/***
 * 根据用户名查询用户
 * @param vo
 * @return
 */
User findByVo(QueryVo vo);

2.1.4.3 UserMapper.xml

修改UserMapper.xml文件


<select id="findByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
    SELECT * FROM  user WHERE username = #{user.username}
</select>

如果我们使用的是包装类作为参数,比如这个示例的QueryVo类作为findByVo()方法的参数,那么在使用时,因为QueryVo类中有一个User类的user对象,而这个user对象中才能找到username属性,所以我们在访问属性时,就使用OGNL表达式才访问对象的属性。

2.1.4.4 测试包装类作为参数

添加测试方法,如下:


/***
 * 测试QueryVo
 */
@Test
public void testQueryVo(){
    QueryVo vo = new QueryVo();
    User user = new User();
    user.setUsername("张三");
    vo.setUser(user);
    User userInfo = userMapper.findByVo(vo);
    System.out.println(userInfo);
}

2.1 Mybatis的输出结果封装

2.1.1 resultType(输出类型)

2.1.1.1 输出简单类型

修改UserMapper接口,增加如下方法


/***
 * 查询总数
 * @return
 */
int findUserCount();

修改UserMapper.xml,增加如下方法:


<!--简单类型-->
<select id="findUserCount" resultType="java.lang.Integer">
    SELECT COUNT(*) FROM  user
</select>

测试代码


/***
 * 返回简单数据类型
 */
@Test
public void testFindUserCount(){
    int count = userMapper.findUserCount();
}

输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。

2.1.1.2 输出Pojo对象

2.1.1.3 输出Pojo列表

2.2 resultMap结果类型

  • resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
  • 如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
  • resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

2.2.1 UserMapper.xml定义

需求:如果返回的列名与实体类的属性不一致时,我们就不能封装结果集到指定的实体对象。

SQL:select id id_,username username_ ,birthday birthday_ ,sex sex_ ,address address_ from user where username='传智播客'

通过改别名的方式,现在返回结果集的列名已经与User类的属性名不相同了。


<!--findByVo-->
<select id="findByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
    SELECT id id_,username username_ ,birthday birthday_ ,sex sex_ ,address address_  FROM  user WHERE username = #{user.username}
</select>

我们再次运行程序,发现出错如下:


org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 1 ms ago.
### The error may exist in com/itheima/mapper/UserMapper.xml
### The error may involve com.itheima.mapper.UserMapper.findByVo
### The error occurred while executing a query
### Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

这个错误就是我们返回结果集的列名与对应User的属性名不对应造成的,使用resultMap可以将建立起结果集的列与实体类的属性名之间的映射,这样就可以解决列名与属性名不相同的问题。

2.2.2 定义resultMap

由于上边的mapper.xml中sql查询列和Users.java类属性不一致,需要定义resultMap:userListResultMap将sql查询列和Users.java类属性对应起来


<!--UserResultMap-->
<resultMap id="UserResultMap" type="com.itheima.domain.User">
    <id column="id_" property="id" />
    <result column="username_" property="username" />
    <result column="birthday_" property="birthday" />
    <result column="sex_" property="sex" />
    <result column="address_" property="address" />
</resultMap>

<!--findByVo-->
<select id="findByVo" parameterType="com.itheima.domain.QueryVo" resultMap="UserResultMap">
    SELECT id id_,username username_ ,birthday birthday_ ,sex sex_ ,address address_  FROM  user WHERE username = #{user.username}
</select>
  • < id />此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个 。
  • property:表示User类的属性。
  • column:表示sql查询出来的字段名。
  • column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
  • < result />普通结果,即pojo的属性。

2.2.3 测试效果


==>  Preparing: SELECT id id_,username username_ ,birthday birthday_ ,sex sex_ ,address address_ FROM user WHERE username = ? 
==> Parameters: 张三(String)
<==      Total: 1User{id=42, username='张三', birthday=Fri Mar 02 15:09:37 CST 2018, sex='女', address='北京金燕龙'}
上一篇:AD学习10(2021.11.10)


下一篇:AD学习4(2021.11.2)