mybatis的结果集映射

结果集的映射:
            1.自动映射-根据字段名和属性名

            2.如果字段取了别名,会根据别名自动映射属性名

            3.在setting中通过设置使用驼峰命名映射,前提是在配置文件中配有<setting name="mapUnderscoreToCamelCase" value="true"/>。具体可以上网搜

            4.通过配置resultMap的形式进行映射


情况一(映射结果封装到Map中):

接口:

public interface EmpMapper {
	//将映射结果封装到Map中,只能是HashMap。key通过@MapKey来指定,比如
        //将Emp对象中的empno属性的值作为key。这样就可以通过key来找到对应的value
       @MapKey("empno")
	public Map<Integer,Emp> findEmpsByReturnMap(String lastName);
}

对应的mapper文件:

这里的resultType是emp,一般是完全限定名,由于做了别名的设置,可以直接写成emp

<mapper namespace="com.anseon.mapper.EmpMapper">
        <select id="findEmpsByReturnMap" resultType="emp" >
		select * from emp  where last_name like #{lastName}
	</select>
</mapper>

test:

	public void test1(){
		EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
		Map<String, Object> map = mapper.findEmpByReturnMap(7369);
		System.out.println(map);
	}


情况二(关联映射):

这里的关联映射是1对1或者多对1的情况,以pojo为标准:

pojo:

public class Emp {
	private Integer empno;
	private String lastName;
	private String job;
	private double salary;
	private Dept dept;


public class Dept {
    private Integer deptno;
    private String name;
    private String loc;

当然一定要有set get 以及构造函数,这里省略了。


对应的mapper文件:

	  <resultMap type="emp" id="empMap">
	  		<id column="empno" property="empno"/>
	  		<result column="ename" property="lastName"/>
	  		<result column="job" property="job"/>
	  		<result column="salary" property="salary"/>
	  </resultMap>

       <resultMap type="emp" id="empRelationMap" extends="empMap">
               <association property="dept" javaType="com.anseon.pojo.Dept">
               <!--column:Dept表中的字段名或者别名
                   property:javaType类中的属性名  -->
                          <!--注意这里的dno是别名,对应的是sql语句中起的别名  -->
                   <id column="dno" property="deptno"/>
                   <result column="dname" property="name"/>
                   <result column="loc" property="loc"/>
               </association>
       </resultMap>

      <select id="findEmpAndDeptByNo" resultMap="empRelationMap">
          select e.*,d.DEPTNO dno,dname,loc
          from emp e ,dept d
          where e.deptno = d.deptno and e.empno = #{empno}
      </select>
 
 
这里看清楚了吗?有两个resultMap,一个select,具体关系如下:

id=empMap的resultMap:

type本来是完全限定名,由于取了别名,可以直接写emp,所以以下的所有property的值都是emp对象的属性

<id>:这个标签是用来标明表中的主键字段。column必须是sql语句中查询的字段,如果没有取别名,就与表中的字段名一致。property对应类的属性名

<result>:这个标签用来标明表中的非主键字段。column和property跟id标签的意思一样

id=empRelationMap的resultMap:

extends:说明继承哪个resultMap,这样一来就不需要重复写<id>和<result>了

<association>:对应pojo中,Emp类有个Dept类属性,而这个标签就是用来说明找Emp表的时候怎样映射Dept表中的字段到dept属性中。

<association property & javaType>:property对应的是type 为 emp 中的dept属性,javaType对应的是该属性映射为Dept类。因此以下的column都是Dept表中的字段或者别名,property都是Dept类的属性名

这里应该看到,只通过一句sql语句就能将两张表中的数据找到,并映射封装到两个对象中


对应的接口:

public Emp findEmpAndDeptByNo(Integer empno);

test:

	@Test
	public void testResultMap2(){
		EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
		Emp emp = mapper.findEmpAndDeptByNo(7369);
		System.out.println(emp);
		System.out.println(emp.getDept());
	}

情况三:

分步查询

其实跟上面的关联查询一样,结果都是将数据封装到两个对象中,不过分步查询是将一条sql语句拆开成单独的几条。关键是要看明白怎么拆成几条sql语句

pojo是一样的,就不写了


mapper文件:

emp的mapper文件:

	  <!--分步查询
	   		  select 引用的查询语句(命名空间+语句的id)
	   		  column sql查询语句中的字段,查出来的值会当做参数传入另一条sql语句中(虽然是参数,也要跟属性名一致)
	   		  -->
	   <resultMap type="emp" id="empStepMap" extends="empMap">
	   		<association property="dept" select="com.anseon.mapper.DeptMapper.findDeptByNo"
	   		 column="deptno"/>
	   </resultMap>
	  <select id="findEmpAndDeptByStep" resultMap="empStepMap">
	  	select * from emp where empno = #{empno}
	  </select>

dept的mapper文件:

<mapper namespace="com.anseon.mapper.DeptMapper">
	<resultMap type="dept" id="deptMap">
		<id column="deptno" property="deptno"/>
		<result column="dname" property="name"/>
		<result column="loc" property="loc"/>
	</resultMap>
	<select id="findDeptByNo" resultMap="deptMap">
		select * from dept where deptno= #{deptno}
	</select>
</mapper>

这可以做对应:namaspace.id = com.anseon.mapper.DeptMapper.findDeptByNo,这跟emp的mapper 中的select对应

sql语句中的#{deptno}跟emp的mapper文件中的column值对应。


对应的接口:

public Dept findDeptByNo(Integer deptno);

public Emp findEmpAndDeptByStep(Integer empno);

test:

省略。。。


以上就是分步查询,将一条sql语句拆分成相应的几条sql语句


情况4:

一对多,主要是pojo中有个list集合,当中的元素是自定义类。

pojo

public class Dept {
	private Integer deptno;
	private String name;
	private String loc;
	private List<Emp> emps;

mapper文件

dept的mapper文件,这里采用分步查询,分步查询的其中一个优点是:可以实现懒加载

	<!--分步查询  支持懒加载-->
	<resultMap type="dept" id="deptMapStep" extends="deptMap">
		<collection property="emps"
		column="deptno" select="com.anseon.mapper.EmpMapper.findEmpsByDeptno"/>
	</resultMap>
	
	
	<select id="findDeptByStep" resultMap="deptMapStep">
		select * from dept where deptno = #{deptno}
	</select>

对应的emp的mapper文件

	  <select id="findEmpsByDeptno" resultMap="empMap">
	  	select * from emp where deptno = #{deptno}
	  </select>

这样就是一对多的设置了。主要就是association 换成  collection


关于懒加载:

需要在mybatis的配置文件中设置:

		<!--开启懒加载  -->
		<setting name="lazyLoadingEnabled" value="true"/>
		<!-- 每个属性按需加载  -->
		<setting name="aggressiveLazyLoading" value="false"/>

但是这个aggressiveLazyLoading有版本问题,需要依照版本来区分默认值

猜你喜欢

转载自blog.csdn.net/Luke_R/article/details/78506488