MyBatis(四)Mybatis的参数
目录
- Mybatis的参数
- 一、parameterType配置参数
- 1. 引入
- 2. 注意事项
- 3. 传递poji包装对象
- ①编写QueryVo
- ②编写持久层接口
- ③持久层接口的映射文件
- ④测试包装类作为参数
- ⑤运行结果
- 二、Mybatis的输出结果封装
- 1. 基本类型示例
- ① Dao接口
- ② 映射配置
- 2. 实体类类型示例
- ① Dao接口
- ② 映射配置
- 3. 特殊情况示例
- ① 修改实体类
- ② Dao接口
- ③ 映射配置
- ④ 测试查询结果
- ⑤ 修改映射配置
- 4. resultMap结果类型
- ① 定义resultMap
- ②查询操作的配置
- ③测试查询
Mybatis的参数
一、parameterType配置参数
1. 引入
我们在对SQL语句传递参数的时候,使用标签的parameterType属性
来设定。该属性的取值可以是基本类型,引用类型(例如String类型),还可以是实体类类型(POJO类型),同时也可以使用实体类的包装类,我们将着重介绍如何使用实体类的包装类作为参数传递。
2. 注意事项
- 基本类型和String类型我们可以直接写类型名称,也可以使用包名.类名的方式,例如:
java.lang.String
。 - 而实体类类型,我们只能写全限定类名。
其中的原因呢,就是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名, 而我们的是实体类并没有注册别名,所以必须写全限定类名。而如何注册实体类的别名我们后面再讲。
在mybatis的官方文档说明中:
这些都是支持的默认别名。
如果我们打开源码 TypeAliasRegistery.class
,我们可以清楚地看出它们分别是怎么定义出来的:
3. 传递poji包装对象
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
我们举一个例子:
需求: 根据用户查询用户信息,查询条件放到QueryVo的user属性中。
①编写QueryVo
package com.veeja.domain;/*** 查询条件对象。*/
public class QueryVo {private User user;public User getUser() {return user;}public void setUser(User user) {this.user = user;}
}
②编写持久层接口
/*** @author veeja* <p>* 用户的持久层接口*/
public interface IUserDao {/*** 根据QueryVo中的条件查询用户** @param vo* @return*/List<User> findUserByVo(QueryVo vo);
}
③持久层接口的映射文件
<!--根据queryVo的条件查询用户-->
<select id="findUserByVo" parameterType="com.veeja.domain.QueryVo"resultType="com.veeja.domain.User">select * from user where username like #{user.username}
</select>
④测试包装类作为参数
/*** 测试使用QueryVo作为查询条件*/
@Test
public void testFindByVo() throws IOException {QueryVo vo = new QueryVo();User user = new User();user.setUsername("%李%");vo.setUser(user);// 执行删除方法List<User> users = userDao.findUserByVo(vo);for (User u : users) {System.out.println(u);}
}
⑤运行结果
也完全符合我们的预期。
二、Mybatis的输出结果封装
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。
我们在前面的 CRUD 案例中已经对此属性进行过应用了。
需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须 使用全限定类名。例如:我们的实体类此时必须是全限定类名(今天最后一个章节会讲解如何配置实体类的别名)
同时,当是实体类名称是,还有一个要求,实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装。
1. 基本类型示例
这一种我们在CRUD操作中已经使用过了。就不再赘述,只是把例子放在下面:
① Dao接口
/*** 查询用户的总记录数** @return*/
int findTotal();
② 映射配置
<!--查询用户的总记录数-->
<select id="findTotal" resultType="int">select count(id) from user
</select>
2. 实体类类型示例
这一种我们在CRUD操作中已经使用过了。就不再赘述,只是把例子放在下面:
① Dao接口
/*** 查询所有的用户** @return*/
List<User> findAll();
② 映射配置
<!-- 查询所有的操作 -->
<select id="findAll" resultType="com.veeja.domain.User">select * from user
</select>
3. 特殊情况示例
① 修改实体类
如果我们修改实体类中的属性名称,让实体类中的属性和数据库中的列名不一致,例如修改User类:
public class User implements Serializable {private Integer userId;private String userName;private String userAddress;private String userSex;private Date userBirthday;@Overridepublic String toString() {return "User{" +"userId=" + userId +", userName='" + userName + '\'' +", userAddress='" + userAddress + '\'' +", userSex='" + userSex + '\'' +", userBirthday=" + userBirthday +'}';}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getUserName() {return userName;}........................}
其实就是简单的修改实体类中属性名称,并且重新生成get/set方法和toString方法。
② Dao接口
/*** 查询所有的用户** @return*/
List<User> findAll();
③ 映射配置
<!-- 查询所有的操作 -->
<select id="findAll" resultType="com.veeja.domain.User">select * from user
</select>
④ 测试查询结果
/*** 测试查询所有*/
@Test
public void testFindAll() {// 5. 执行查询所有方法List<User> users = userDao.findAll();for (User user : users) {System.out.println(user);}
}
我们运行一下,发现出现问题了:
我们发现,大部分都是null,而只有username显示了属性。
null的原因是我们修改了实体类的属性名,就没法映射过来了。而username有值的原因是我们是把username修改为了userName,而MySQL在windows系统中是不区分大小写的。所以才会有这种现象。
⑤ 修改映射配置
针对上面的问题我们应该怎么解决呢?
其中一个方案是我们可以使用别名进行查询,例如把映射配置文件修改为:
<!-- 查询所有的操作 -->
<select id="findAll" resultType="com.veeja.domain.User">select id as userId,username as userName,birthday as userBirthday,sex as userSex, address as userAddress from user
</select>
查询结果:
如果我们查询的表中列很多,都使用别名的话岂不是很麻烦,有没有别的解决办法呢?
请往下看。
4. resultMap结果类型
resultMap标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系,从而实现封装。
在select标签中使用resultMap属性指定引用即可。同时resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
那么我们怎么样解决上面遗留的问题呢?
① 定义resultMap
我们要在resultMap中建立User实体类和数据库表的对应关系。
使用type属性来指定实体类的全限定类名。
id属性是给定的一个唯一标识,是给查询select标签引用使用的。
在IUserDao.xml中添加:
<!--配置 查询结果的列名和实体类的属性名的对应关系 -->
<resultMap id="userMap" type="com.veeja.domain.User"><!--主键字段的对应--><id property="userId" column="id"></id><!--非主键字段的对应--><result property="userName" column="username"></result><result property="userAddress" column="address"></result><result property="userSex" column="sex"></result><result property="userBirthday" column="birthday"></result>
</resultMap>
②查询操作的配置
而我们的查询配置,指定的resultType属性要更换成resultMap属性,换成我们上面声明的id即可,也就是:
<!-- 查询所有的操作 -->
<select id="findAll" resultMap="userMap"><!--select id as userId,username as userName,birthday as userBirthday, sex as userSex, address as userAddress from user-->select * from user
</select>
③测试查询
我们再次执行查询的方法,发现是没有问题的:
end.
MyBatis(四)Mybatis的参数相关推荐
- MyBatis(四)MyBatis插件原理
MyBatis插件原理 MyBatis对开发者非常友好,它通过提供插件机制,让我们可以根据自己的需要去增强MyBatis的功能.其底层是使用了代理模式+责任链模式 MyBatis官方https://m ...
- mybatis parametertype 多个参数
mybatis parametertype 多个参数 一.单个参数: public List<XXBean> getXXBeanList(@param("id")Str ...
- MyBatis注解模式取参数方法
2019独角兽企业重金招聘Python工程师标准>>> @Select("select count(*) from (select id from patrol_host ...
- mybatis传递多个参数_深入浅出MyBatis:MyBatis解析和运行原理
原文:https://juejin.im/post/5abcbd946fb9a028d1412efc 本篇文章是「深入浅出MyBatis:技术原理与实践」书籍的总结笔记. 上一篇介绍了反射和动态代理基 ...
- Mybatis四种分页方式
1.数组分页 查询出全部数据,然后再list中截取需要的部分. mybatis接口 List<Student> queryStudentsByArray(); xml配置文件 <se ...
- MyBatis多个接口参数报错:Available parameters are [0, 1, param1, param2], 及解决方法
MyBatis多个接口参数报错:Available parameters are [0, 1, param1, param2], 及解决方法 参考文章: (1)MyBatis多个接口参数报错:Avai ...
- MyBatis(一)MyBatis介绍和配置详解
在Java程序里面去操作数据库,最原始的办法是使用JDBC的API.需要分为六步: 注册驱动 通过DriverManager获取一个Connection 通过Connection创建一个Stateme ...
- MyBatis二 MyBatis常见面试题
一 MyBatis是什么? MyBatis是一款优秀的持久层框架,一个半ORM (对象关系映射)框架,它支持定制化SQL.存储过程以及高级映射.MyBatis避免了几乎所有的JDBC代码和手动设置参数 ...
- (Mybatis)Mybatis简介和初步使用
1. Mybatis简介 1.1什么是Mybatis MyBatis 是一款优秀的持久层框架 它支持定制化 SQL.存储过程以及高级映射. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参 ...
- MyBatis(三)MyBatis缓存和工作原理
MyBatis缓存 MyBatis提供了一级缓存和二级缓存,并且预留了集成第三方缓存的接口. 从上面MyBatis的包结构可以很容易看出跟缓存相关的类都在cache的package里,其底层是一个Ca ...
最新文章
- alsa 测试 linux_python语音智能对话聊天机器人--linuxamp;amp;树莓派双平台兼容
- 生物计算:SIR模型笔记
- word2vec原理之CBOW与Skip-Gram模型基础
- 【收藏】docker安装redis
- T-SQL with as 关键字
- jQuery框架学习第四天:使用jQuery操作元素的属性与样式
- java apktoo_apktool.jar最新版下载|apktool_2.0.3.jar 官方版_最火软件站
- .NET跨平台之旅:基于.NET Core改写EnyimMemcached,实现Linux上访问memcached缓存
- vue把数据导出为Excel表格的方法
- 音乐播放小窗口html,jQuery+html5迷你网页音乐播放器代码
- 【软件测试】使用C++ Test进行动态测试
- postgresql unsupported frontend protocol 1234.5680问题
- 计算机网络 --- 计算机和因特网2
- Spark中distinct、reduceByKey和groupByKey的区别与取舍
- Java面试题——基础篇一
- DC-DC变换器(DCDC Converter / Switched-mode Power Supply)简介
- 又发福利!日历小程序源码
- 为什么用Yarn来做Docker容器调度引擎
- Docker-windows使用教程
- Java到底是什么?学习java可以做什么呢?