封装输出结果:MyBatis执行sql语句,得到ResultSet,转为java对象
这里我们两个,分别为resultType和resultMap
文章目录
- 1.resultType
- 1.1 java类型的全限定名称
- 1.2 自定义别名
- 1.2.1 typeAlias自定义别名
- 1.2.2 package自定义别名
- 1.3 resultType表示简单类型
- 1.4 resultType
- 2.resultMap
- 3.列名和Java对象属性名称不一致解决方式
- 3.1 使用resultMap:自定义列名和属性名称对应关系
- 3.2 使用resultType
1.resultType
resultType属性:在执行select时使用,作为标签的属性出现的。
resultType:执行sql得到ResultSet转换的类型,使用类型的完全限定名或别名。注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。
它的值有两种:
- java类型的全限定名称
- 使用别名
1.1 java类型的全限定名称
dao接口中定义方法
Student selectStudentById(Integer id);
mapper文件中
<select id="selectStudentById" parameterType="int" resultType="com.lu.entity.Student">
select id, name, email, age from student where id = #{studentId}
</select>
resultType:现在使用的是java类型的全限定名称。表示的意思是mybatis执行sql,把ResultSet中的数据转为Student类型的对象。
mybatis会做一下操作:
1.调用com.lu.entity.Student的无参构造方法, 创建对象。
Student student = new Student(); //使用反射创建对象
2.同名的列赋值给同名的属性
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
3.得到java对象,如果dao接口返回值是List集合,mybatis把student对象放入到List集合
所以执行 Student mystudent = dao.selectById(1001);
得到数据库中 id = 1001这行数据,这行数据的列值,赋值给了mystudent对象的属性。你能得到mystudent对象,就相当于是id = 1001这行数据。
1.2 自定义别名
mybatis提供的对java类型定义简短,好记的名称。
自定义别名有两种方式:分别为typeAlias和package
1.2.1 typeAlias自定义别名
使用typeAlias自定义别名的步骤:
1.在mybatis主配置文件,使用typeAliases标签声明别名
<typeAliases>
<!--第一种语法格式
type:java类型的全限定名称(自定义类型)
alias:自定义别名
-->
<typeAlias type="com.lu.entity.Student" alias="stu"></typeAlias>
</typeAliases>
注意:标签必须写在标签后面
2.在mapper文件中,resultType = “别名”
<select id="selectStudentById" parameterType="int" resultType="stu">
select id, name, email, age from student where id = #{studentId}
</select>
3.测试类中测试
@Test
public void testselectStudentById() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectStudentById(1002);
System.out.println(student);
session.close();
}
控制台输出:
使用typeAlias有优点也有缺点
优点:别名可以自定义
缺点:每个类型必须单独定义
1.2.2 package自定义别名
主配置文件中:
<!--第二种方式
name:包名,mybatis会把这个包中所有类名作为别名
-->
<package name="com.lu.entity"/>
mapper文件中:
<select id="selectStudentById" parameterType="int" resultType="student">
select id, name, email, age from student where id = #{studentId}
</select>
这一种方式resultType中不区分大小写,所以全用小写同样也可以
测试类中测试:
同样测试成功
优点:使用方便,一次给多个类定义别名。
缺点:别名不能随便定义,必须是类名。
这两种自定义别名都有优点和缺点,所以建议是不适用别名,就使用全限定名称,这样清晰明了。
1.3 resultType表示简单类型
我们首先在dao接口中定义一个方法
long countStudent();
在mapper文件中编写sql语句
<!--执行sql语句,得到的是一个值(一行一列)-->
<select id="countStudent" resultType="java.lang.Long">
select count(*) from student
</select>
在测试类中测试
@Test
public void testCountStudent() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
long nums = dao.countStudent();
System.out.println("nums = " + nums);
session.close();
}
控制台输出:
1.4 resultType
dao接口中定义方法:
Map<Object, Object> selectMap(Integer id);
mapper文件中写sql语句:
<!--
执行sql得到一个Map结构数据,mybatis执行sql,把ResultSet转为map
-->
<select id="selectMap" resultType="java.util.HashMap">
select id, name from student where id = #{studentid}
</select>
测试类中进行测试:
@Test
public void testSelectMap() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Map<Object, Object> map = dao.selectMap(1001);
System.out.println("map = " + map);
System.out.println("name = " + map.get("name"));
System.out.println("id = " + map.get("id"));
session.close();
}
控制台输出:
我们可以看到执行结果,列名作为map的key,列值作为value
dao接口返回一个map,sql语句最多能获取一行记录,多于一行是错误
2.resultMap
resultMap:结果映射。自定义列名和Java对象属性的对应关系。常用在列名和属性名不同的情况。
用法:
1.先定义resultMap标签,指定列名和属性名称对应关系
2.在select标签使用resultMap属性,指定上面定义的resultMap的id值
我们来举一个例子
首先定义一个CustomObject类
package com.lu.entity;
public class CustomObject {
private Integer cid;
private String cname;
private String email;
private Integer age;
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "CustomObject{" +
"cid=" + cid +
", cname='" + cname + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
我们发现这里cid和cname和数据库里面的列名不一致
我们再在dao接口中定义一个方法
CustomObject selectById2(Integer id);
如果我们要将从数据库取出来的内容赋值给CustomObject对象,那么如果我们继续用resultType的话,从数据库中取出来的数据只能赋值给email和age,无法给cid和cname进行赋值,这个时候我们就需要用到resultMap
我们在mapper文件中这样来写:
<!--
使用resultMap定义列和属性的关系
定义resultMap
id:给resultMap的映射关系起个名称,唯一值
type:Java类型的全限定名称
-->
<resultMap id="customMap" type="com.lu.entity.CustomObject">
<!--定义列名和属性名的对应-->
<!--主键类型使用id标签-->
<id column="id" property="cid"></id>
<!--非主键类型使用result标签-->
<result column="name" property="cname"></result>
<!--列名和属性名相同,不用定义-->
</resultMap>
<!--使用resultMap属性,指定映射关系的id-->
<select id="selectById2" resultMap="customMap">
select id, name, email, age from student where id = #{studentid}
</select>
这样我们就可以使用resultMap来定义数据库列和属性的关系
我们在测试类中进行测试:
@Test
public void testSelectById2() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
CustomObject co = dao.selectById2(1001);
System.out.println(co);
session.close();
}
控制台输出:
这样resultMap就成功解决了列名和属性名不一致的情况。
注意:resultType和resultMap不能同时使用。
3.列名和Java对象属性名称不一致解决方式
3.1 使用resultMap:自定义列名和属性名称对应关系
这个方法在上面讲解resultMap的时候就讲解了,可以直接看上面
3.2 使用resultType
使用列别名,让别名和Java对象属性名称一样
我们在dao接口中定义一个方法:
CustomObject selectById3(Integer id);
我们在mapper文件中写:
<!--使用列别名,解决列名和属性名不同的问题-->
<select id="selectById3" resultType="com.lu.entity.CustomObject">
select id AS cid, name AS cname, email, age where id = #{studentid}
</select>
我们在测试类中进行测试
@Test
public void testSelectById3() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
CustomObject co = dao.selectById2(1003);
System.out.println(co);
session.close();
}
控制台输出: