Mybatis入门笔记(4)——输入映射和输出映射
输入映射papameterType
传递简单类型
基本类型和String我们可以直接写类型名称,也可以使用包名.类名的方式。例如:java.lang.String
传递pojo对象
Mybatis使用ognl表达式解析对象字段的值、#{}或${}括号中的值为pojo属性名称。
OGNL表达式:Object Graphic Navigation Language。对象 图 导航 语言
它是通过对象的取值方法来获取数据,比如user.username。在写法上把get给省略了。
比如:我们获取用户的名称
类中的写法:user.getUsername();
OGNL表达式写法:user.username;
mybatis中为什么能直接写username,而不用user呢。因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名。
传递pojo包装对象
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。Pojo 类中包含 pojo。
需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。
在com.ben.domain里编写QueryVo类
/**
* @ClassName: QueryVo
* @author: benjamin
* @version: 1.0
* @description: 查询条件对象
* @createTime: 2019/07/15/17:35
*/
public class QueryVo implements Serializable {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
编写持久层接口
public interface IUserDao {
// 根据 QueryVo 中的条件查询用户
List<User> findByVo(QueryVo vo);
}
配置映射文件
<!-- 根据用户名称模糊查询,参数变成一个 QueryVo 对象了 -->
<select id="findByVo" resultType="com.ben.domain.User"
parameterType="com.ben.domain.QueryVo">
select * from user where username like #{user.username};
</select>
测试包装类作为参数
@Test
public void testQueryVo(){
QueryVo vo = new QueryVo();
User user = new User();
user.setUsername("%五%");
vo.setUser(user);
List<User> users = userdao.findByVo(vo);
for(User u : users) {
System.out.println(u);
}
}
输出映射resultType
输出简单类型
映射配置文件
<!-- 查询总记录条数 -->
<select id="findTotal" resultType="int">
select count(*) from user;
</select>
接口实现类
// 查询总记录数
int queryUserCount();
测试方法
//查询用户总数
@Test
public void testQueryUserCount(){
int count = userdao.queryUserCount();
System.out.println(count);
}
输出pojo类型
resultType输出可以是一个对象。
输出pojo列表
resultType输出也可以是一个列表。
使用resultMap
背景:resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
问题:如果pojo的属性名和SQL中的列名不一致怎么办?
解决方法:如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,
resultMap实质上还需要将查询结果映射到pojo对象中。
我们以添加用户为例,
配置好映射配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ben.dao.IUserDao">
<select id="findAll" resultType="com.ben.domain.User">
select username,birthday,address,sex from user
</select>
</mapper>
编写持久层接口
public interface IUserDao {
// 查询所有用户
List<User> findAll();
}
编写测试文件
//添加用户
@Test
public void testFindAll() throws IOException {
List<User> list = userdao.findAll();
for (User user : list) {
System.out.println(user);
}
}
结果:
因为除了userName属性,其他所有属性都没对应上数据库的列名。mysql数据库在为windows下不区别大小写,因此userName是能对应到数据库中username列。在linux下严格区分大小写。
解决方法1:
编写sql语句,效率高;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ben.dao.IUserDao">
<select id="findAll" resultType="com.ben.domain.User">
select id as userId,username as userName,birthday as userBirthday,address as userAddress,sex as userSex from user
</select>
</mapper>
完美:
使用resultMap,配置查询结果的列名和实体类的属性名的对应关系。修改xml配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ben.dao.IUserDao">
<!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
<resultMap id="userMap" type="com.ben.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>
<!-- 查询所有 -->
<select id="findAll" resultMap="userMap">
select * from user;
</select>
</mapper>