MyBatis之resultMap的作用和xml配置折腾

简单的搭建。

MyBatis实战——前身iBatis、基础环境搭建和如何"钓鱼" 这篇写了基础的环境搭建和代码操作。

我这里是使用了xml加interface结合的方法进行操作。现有Employee类。如果是简单的select,可以看看下面简单的例子。

Employee.java

 

public class Employee {//省略get set 方法
	private int id;
	private String first_name;
	private String last_name;
	private int salary;
}

 

 

 

EmployeeMapper.java

 

package com.mybatis3.mappers;

import model.Employee;

public interface EmployeeMapper
{
	Employee findEmployeeById(Integer a);
}


EmployeeMapper.xml(和EmployeeMapper.java位于同个package中

 

 

 

 

<?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.mybatis3.mappers.EmployeeMapper">  
  <select id="findEmployeeById" resultType="model.Employee">  
    select * from Employee where id = #{abc} <!-- 后面发现这个参数名这里填什么都无所谓,能映射到 -->
  </select>  
</mapper>  


mybatis-config.xml的mappers映射改成:

 

 

 

 

<mapper class="com.mybatis3.mappers.EmployeeMapper" />


进行查询操作。

 

 

public class Factory {  
    public static void main(String[] args) {  
        String configxml = "mybatis-config.xml";  
        InputStream is = null;  
        try {  
            is = Resources.getResourceAsStream(configxml);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);  
        SqlSession s = sf.openSession();  
        EmployeeMapper employeeMapper =  s.getMapper(EmployeeMapper.class);
        Employee e =  employeeMapper.findEmployeeById(47);
        System.out.println(e.getFirst_name());  
        System.out.println(e.getLast_name());  
        System.out.println(e.getSalary()); 
        s.close();  
    }  
}  


这是单表查询的时候,那么问题就来了。如果是多表复杂的查询。现在有了一张新表Employer,假如你是框架的设计者,会让Employee的字段全部丢到Employer中吗,显然不合适。

 

 

这是MyBatis提供了resultmap的方法。先看看单独一个类也可以使用resultmap进行映射。

Employer类

 

public class Employer {
	private int id;//省略set get 方法
	private int employee_id;
	private String name;
	private Employee em;
}

 

 

EmployerMapper.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.mybatis3.mappers.EmployerMapper">
	<resultMap id="Employer" type="model.Employer">
		<id property="id" column="id" />	<!-- id相当于resultmap的引用的唯一标识-->
		<result property="name" column="name" />  <!-- property对应javabean的属性名,column对应数据库字段名 -->
		<result property="employee_id" column="employee_id" />
	</resultMap>

	<select id="findEmployeeById" resultMap="Employer">
		select * from Employer where id = #{abc}
	</select>
</mapper>

 


测试:

 

public class Factory {  
    public static void main(String[] args) {  
        String configxml = "mybatis-config.xml";  
        InputStream is = null;  
        try {  
            is = Resources.getResourceAsStream(configxml);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);  
        SqlSession s = sf.openSession();  
        EmployerMapper employerMapper =  s.getMapper(EmployerMapper.class);
        Employer e2 =  employerMapper.findEmployeeById(1);
        System.out.println(e2.getEmployee_id());
        System.out.println(e2.getName());
        s.close();  
    }  
}  

 

 

 

 

 

折腾resultMap的id,result属性:

接下来开始折腾了。将EmployerMapper.xml里面改成只剩:

 

	<resultMap id="Employer" type="model.Employer">
	</resultMap>

	<select id="findEmployeeById" resultMap="Employer">
		select * from Employer where id = #{abc}
	</select>


发现还是能正常映射。但是如果改javabean的一个属性:

 

 

	private int employeeid;
	public int getEmployeeid() {
		return employeeid;
	}
	public void setEmployeeid(int employee_id) {
		this.employeeid = employee_id;
	}


这样最后取值是取不到的,因为映射不到。那究竟是属性名还是通过getset方法的名字映射呢。再折腾:

 

 

	private int employeeid;
	public int getEmployee_id() {
		return employeeid;
	}
	public void setEmployee_id(int employee_id) {
		this.employeeid = employee_id;
	}


employeeid属性名与数据库字段名不对应,但是get,set的方法名是和数据库字段名对应的。运行正常。

 

如果不想在配置这里瞎折腾,JavaBean字段名保持和数据库字段名是最好的选择。

 

折腾resultMap extends属性,表关联查询。

Employer.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.mybatis3.mappers.EmployerMapper">
	<resultMap id="Employer" type="model.Employer">
	</resultMap>
	<resultMap type="model.Employer" id="EmployerWithEmployee"
		extends="Employer">
		<result property="em.id" column="id" />
		<result property="em.first_name" column="first_name" />
		<result property="em.last_name" column="last_name" />
		<result property="em.salary" column="salary" />
	</resultMap>
	<select id="findEmployeeById2" resultMap="EmployerWithEmployee">
		select employee_id,name,b.first_name,b.salary,b.last_name from Employer a
		left join Employee b on a.employee_id=b.id where a.id = #{abc}
	</select>
</mapper>


测试:

 

 

        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);  
        SqlSession s = sf.openSession();  
        EmployerMapper employerMapper =  s.getMapper(EmployerMapper.class);
        Employer e2 =  employerMapper.findEmployeeById2(1);
        System.out.println(e2.getEmployee_id());
        System.out.println(e2.getName());
        System.out.println(e2.getEm().getFirst_name());
        System.out.println(e2.getEm().getLast_name());

 

 

 

 

 

注意这次的em不再是和上面第一个折腾的一样,是和方法名一致的。这次是和属性名一致。不然会报错。

而且MyBatis的关联查询就这么简单,还是一样的关联语句,只不过加了一些映射配置。

 

折腾association

extends拓展看起来挺好,但是讲到解耦的话,你extends出来是个不伦不类的东西。本身我就有Employee的存在。

所以,这时association出现了。

 

<mapper namespace="com.mybatis3.mappers.EmployerMapper">
	<resultMap id="Employee" type="model.Employee">
		<id property="id" column="id" />
		<result property="first_name" column="first_name" />
		<result property="last_name" column="last_name" />
		<result property="salary" column="salary" />
	</resultMap>

	<resultMap id="Employer" type="model.Employer">
		<id property="id" column="id" />	<!-- id相当于resultmap的引用的唯一标识-->
		<result property="name" column="name" />  <!-- property对应javabean的属性名,column对应数据库字段名 -->
		<result property="employee_id" column="employee_id" />
		<association property="em" resultMap="Employee" />
	</resultMap>
	<select id="findEmployeeById2" resultMap="Employer">
		select employee_id,name,b.first_name,b.salary,b.last_name from Employer a
		left join Employee b on a.employee_id=b.id where a.id = #{abc}
	</select>
</mapper>


测试代码不变:

 

 

SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);  
SqlSession s = sf.openSession();  
EmployerMapper employerMapper =  s.getMapper(EmployerMapper.class);
Employer e2 =  employerMapper.findEmployeeById2(1);
System.out.println(e2.getEmployee_id());
System.out.println(e2.getName());
System.out.println(e2.getEme().getFirst_name());
System.out.println(e2.getEme().getLast_name());
s.close();  


但是不同于resultmap使用extends,result标签是不可少的,一旦少了,将获取不到其属性值。

 

 

经过上面种种折腾之后终于知道作者讲的作用是什么:最后就明白了书上所讲的ResultMap的作用,映射SQL选择声明的结果到JavaBean属性中。通过一对一和一对多associations可以将简单选择声明映射复杂的声明。

MyBatis是一款优秀的基于Java的持久层框架,它的数据访问层采用了ORM(Object Relational Mapping)的思想,使得我们可以通过XML配置或者注解的方式将Java对象映射到数据库中的表。 在MyBatis中,我们可以通过使用XML的方式配置结果集的映射规则,这个过程就是使用resultMap来完成的。resultMapMyBatis中用来描述如何将数据库结果集映射到Java对象的规则集,其中包括了属性名、Java类型、JDBC类型、以及类型转换器等。 在MyBatisMapper XML文件中,我们可以使用resultMap元素来定义一个结果集映射规则,该元素可以包含多个子元素,如id、result、association、collection等。其中,id元素用于指定结果集映射规则的唯一标识,result元素用于指定单个属性的映射规则,association元素用于指定关联对象的映射规则,collection元素用于指定集合属性的映射规则等。 一个简单的resultMap示例代码如下: ``` <resultMap id="userResultMap" type="User"> <id column="id" property="id" /> <result column="username" property="username" /> <result column="password" property="password" /> <result column="email" property="email" /> </resultMap> ``` 在上述代码中,我们定义了一个名为userResultMapresultMap,它的Java类型为User。该resultMap包含了四个result元素,分别用于指定id、username、password、email这四个属性的映射规则。其中,column属性指定了数据库表中对应的列名,property属性指定了Java对象中对应的属性名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iaiti

赏顿早餐钱~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值