【Mybatis】Mybatis参数深入
1.Mybatis参数深入
1.1输入参数——parameterType
parameterType标签是用来设定sql语句中参数的数据类型。它可以设定的数据类型可以是基本数据类型,引用数据类型(如String类型),自定义数据类型。
但是要注意的是,基本数据类型和String可以直接写类型名称,也可以使用包名。
下面以一个sql的模糊查询为例:
<!--模糊查询1-->
<select id="findUserByName" parameterType="string"
resultType="com.xq.pojo.User">
select * from user where username like #{username}
</select>
这是直接写类型名称
<!--模糊查询1-->
<select id="findUserByName" parameterType="java.lang.String"
resultType="com.xq.pojo.User">
select * from user where username like #{username}
</select>
这是写包的名称的方式
至于为什么既能用包名用能用类型名称,可以看一下源码
它这里给我们常见的数据类型起了别名,所以这也是为什么基本数据类型和String可以用两种方式,而自定义数据类型不可以,因为他也不知道你写的什么,不可能提前帮你写好别名,所以只能用包名。
1.2传递pojo对象
编写接口
public List<User> findUserById(QueryVo queryvo);
编写实体类
public class Query{
//保存id的集合
List<Integer> ids;
public List<Integer>getIds(){
return ids;
}
public void setIds(List<Integer> ids){
this.ids=ids;
}
}
编写映射文件
<!--
根据用户id的集合进行查询
foreach 遍历集合的标签
collection:list集合的名称
item:遍历的集合元素的别名
separator:select * from user where id in(1,2,3); in后面括号里面参
数用逗号分隔开来。
open:括号的开始部分 (
close:括号的结束部分 )-->
<select id="findUserByIds" parameterType="com.xq.pojo.QueryVo"
resultType="com.xq.pojo.User">
select * from user where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
测试
@Test
public void testFindUserByIds(){
QueryVo queryVo = new QueryVo();
List<Integer> list = new ArrayList<Integer>();
list.add(41);
list.add(42);
list.add(43);
queryVo.setIds(list);
List<User> userList = userDao.findUserByIds(queryVo);
for(User user : userList){
System.out.println(user);
}
}
补充一下:这里的findUserByIds的对应的SqlMapConfig.xml中对应的sql语句为
select * from user where id=#{id}
1.3输出参数——resultType和resultMap
ResultType属性可以指定结果集的数据类型,它支持基本数据类型,引用数据类型和自定义数据类型。
它和parameterType一样,如果注册过类型别名,那么可以直接使用别名当然也可以使用包名,但是引用数据类型就只能使全限定类名。
下面来演示两种特殊情况
这是我们要进行操作的表
构建实体类
public class User {
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(Date userBirthday) {
this.userBirthday = userBirthday;
}
public String getUserSex() {
return userSex;
}
public void setUserSex(String userSex) {
this.userSex = userSex;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userBirthday=" + userBirthday +
", userSex='" + userSex + '\'' +
", userAddress='" + userAddress + '\'' +
'}';
}
}
构建接口
//查询所有User信息
public List<User> findAll();
接口映射文件
<select id="findAll" resultType="com.xq.pojo.User">
select * from user
</select>
测试
@Test
public void testFindAll() throws Exception{
List<User> userList = userDao.findAll();
for(User user : userList){
System.out.println(user);
}
}
观察测试结果
这里只有username有值,其他的都没有被查询到。
为什么只有username有值,而其他的没有被查询到呢?
因为在windows和MYSQL中,忽略了大小写,只要实体类字段和数据表字段一致就行了。实体类的userName和数据表中的username除了大小写其他都一样,而其他的字段都不一样,自然查询不到。
那么怎么解决呢,有两种方式
第一种就是给字段名取别名,使它们能够相互映射。
修改映射配置‘
<select id="findAll" resultType="com.xq.pojo.User">
select id as userId,username as userName,birthday as
userBirthday,sex as userSex,address as userAddress from user
</select>
但是你有没有想过,给每一个字段都起一个别名,是不是太麻烦了,所以一般不推崇。
那么还有另外一种方法,就是使用resultMap进行手动映射。
<!--使用ResultMap标签手动映射,解决实体字段和数据表字段不一致的问题-->
<resultMap id="userMap" type="com.xq.pojo.User">
<id property="userId" column="id"></id>
<result property="userName" column="username"></result>
<result property="userBirthday" column="birthday"></result>
<result property="userSex" column="sex"></result>
<result property="userAddress" column="address"></result>
</resultMap>
<select id="findAll" resultMap="userMap">
select * from user
</select>
resultMap标签
id的只是任意的,是select查询标签的放回值引用属性,也就是resultMap标签中的id要和select标签中的resultMap值一样就行了。
type就是映射实体的全限定名,如果你配置别名也可以使用别名。
id标签:
描述主键字段的映射关系
property:实体类的属性
column:数据表的字段名称
result标签
描述非主键字段的映射关系
select标签
resultMap:描述查询结果的返回值类型,但是这里不能再使用resultType类型了,而是需要引用resultMap标签中的id值
讲了这么多,下面来对比一下resultMap和resultType
功能特性
resultType
:它是一种简单直接的结果映射方式,要求查询结果的列名和实体类的属性名精确匹配,MyBatis 会自动将查询结果映射到指定类型的对象中。它主要适用于列名和属性名一致的简单映射场景。
resultMap
:这是一种更灵活、强大的结果映射方式,允许你自定义查询结果列和实体类属性之间的映射关系,即使列名和属性名不一致,也能通过resultMap
进行准确映射。此外,它还支持处理复杂的映射关系,如嵌套查询、嵌套结果等。
使用场景
resultType
:当查询结果的列名和实体类的属性名完全一致,或者只需要进行简单的类型映射(如返回基本数据类型、Map
、List
等)时,使用resultType
会更加简洁方便
resultMap
:在以下几种情况下,建议使用resultMap
:
查询结果的列名和实体类的属性名不一致。
需要处理复杂的映射关系,如关联查询、嵌套查询等。
需要对查询结果进行特殊处理,如类型转换、自定义映射逻辑等。