MyBatis3系列__05查询补充&resultMap与resultType区别
1.查询补充
当你查询一条记录并且是简单查询时,情况相对简单,可以参考以下的例子:public employee getempbyid(integer id);
对应的xml文件中:
<select id="getempbyid" resulttype="com.mybatis.learn.bean.employee"> select id, last_name lastname, gender, email from tbl_employee where id = #{id} </select>
当查询多条记录时,可以参考以下方式:、
public list<employee> getlistbygender(string gender); public map<string, object> getmapbyid(integer id); //该注解时指定封存记录的map的key @mapkey("lastname") public map<string, employee> getmap(string gender);
xml中:
<!-- 查询多条记录时,若是用list封装结果,resulttype填写list中的每条记录的泛型的全类名 --> <select id="getlistbygender" resulttype="com.mybatis.learn.bean.employee"> select * from tbl_employee where gender=#{gender} </select> <!-- map存储查询结果时,单条记录可以直接在resulttype中写map --> <select id="getmapbyid" resulttype="map"> select * from tbl_employee where id=#{id} </select> <!-- map存错多条查询结果时,reuslttype指定的也是里面每条记录的泛型的全类名 --> <select id="getmap" resulttype="com.mybatis.learn.bean.employee"> select * from tbl_employee where gender=#{gender} </select>
2.resulttype&resultmap
如果是简单查询,推荐使用resulttype(resultmap也能使用,但是比较麻烦),使用方式在前面演示过了。 resultmap除了可以使用在简单查询情况下,也能使用在resulttype不能胜任的地方,如:联合查询,关联查询等,举个例子: 查询员工信息时包含部门信息: 新建javabean:
package com.mybatis.learn.bean; import lombok.*; @getter @setter @noargsconstructor @allargsconstructor @tostring public class department { private integer deptid; private string deptname; }
在原来的employee类添加新的属性department以及getter setter
private department deparment;
建表sql:
create table `tbl_dept` ( `dept_id` int(11) unsigned not null, `dept_name` varchar(255) default null, primary key (`dept_id`) ) engine=innodb default charset=utf8;
修改表tbl_employee ,新增字段dept_id;
此时,由于全部字段存在于两个表中,需要关联查询,已经创建的javabean没有一个能满足要
求,这时可以结合resultmap创建一个:
还是在employeemapper.xml文件中:
<!-- 场景一: 查询employee的同时查询员工对应的部门 employee===department 一个员工有与之对应的部门信息; id last_name gender dept_id dept_name (private department dept;) --> <!-- 联合查询:级联属性封装结果集 resultmap: id标签:指定主键; result标签:指定普通列 column:指定数据库中的列名 property:指定对应的javabean中的属性名 其实,指定id后再指定和数据库不一样的字段即可,不过推荐全部指定 --> <!-- 方式一:关联查询--> <resultmap id="myemp" type="com.mybatis.learn.bean.employee"> <id column="id" property="id"/> <result column="last_name" property="lastname"/> <result column="gender" property="gender"/> <result column="email" property="email"/> <result column="dept_id" property="dept.deptid"/> <result column="dept_name" property="dept.deptname"/> </resultmap> <!-- 方式二:使用association定义关联的单个对象的封装规则;--> <resultmap id="myemp2" type="com.mybatis.learn.bean.employee"> <id column="id" property="id"/> <result column="last_name" property="lastname"/> <result column="gender" property="gender"/> <result column="email" property="email"/> <!-- association可以指定联合的javabean对象 property="dept":指定哪个属性是联合的对象 javatype:指定这个属性对象的类型[不能省略] --> <association property="dept" javatype="com.mybatis.learn.bean.department"> <id column="dept_id" property="deptid"/> <result column="dept_name" property="deptname"/> </association> </resultmap> <select id="getfullempbyid" resultmap="myemp"> select e.id, e.last_name, e.gender, e.email, d.dept_id, d.dept_name from tbl_employee e left join tbl_dept d on e.dept_id = d.dept_id where id = #{id} </select> <select id="getfullemp2byid" resultmap="myemp2"> select e.id, e.last_name, e.gender, e.email, d.dept_id, d.dept_name from tbl_employee e left join tbl_dept d on e.dept_id = d.dept_id where id = #{id} </select>
更改查询mapper:
public employee getfullemp2byid(integer id); public employee getfullempbyid(integer id);
这时可以分别测试一下了。 当然,resultmap的意义还不止于此,比如你想分布查询时: 首先开启延迟加载:更改mybatis-config.xml文件:
<!-- 设置延迟加载 显示的指定每个我们需要更改的配置的值,即使他是默认的。 防止版本更新带来的问题 --> <setting name="lazyloadingenabled" value="true"/> <setting name="aggressivelazyloading" value="false"/>
原理就是在一个查询中嵌套一个查询,并且在需要关联的字段时才去执行嵌套的查询:
//employeemapper中新增的方法 public employee getempbystep(integer id); //employeemapper.xml中新增的内容: <resultmap id="myempbystep" type="com.mybatis.learn.bean.employee"> <id column="id" property="id"/> <result column="last_name" property="lastname"/> <result column="gender" property="gender"/> <result column="email" property="email"/> <association column="dept_id" property="dept" select="com.mybatis.learn.dao.departmentmapper.getdeptbyid"/> </resultmap> <select id="getempbystep" resultmap="myempbystep"> select * from tbl_employee where id=#{id} </select> //你也发现了问题对不对,没有对应的嵌套的sql,ok,现在补齐: //新增departmentmapper: import com.mybatis.learn.bean.department; public interface departmentmapper { public department getdeptbyid(integer deptid); } //以及对应的xml: <select id="getdeptbyid" resulttype="com.mybatis.learn.bean.department"> select * from tbl_dept where dept_id=#{deptid} </select>
ok,如何证明分布查询呢:
下面的例子将会证明:
@test public void testgetempbystep() { string resources = "mybatis-config.xml"; inputstream inputstream = null; try { inputstream = resources.getresourceasstream(resources); } catch (ioexception e) { e.printstacktrace(); } sqlsessionfactory sessionfactory = new sqlsessionfactorybuilder().build(inputstream); sqlsession session = sessionfactory.opensession(true); employeemapper mapper = session.getmapper(employeemapper.class); employee emp = mapper.getempbystep(1); system.out.println(emp.getemail()); system.out.println(emp.getdept()); }
执行结果如下:
第一次查询,不需要查询dept
debug 03-23 15:51:26,066 ==> preparing: select * from tbl_employee where id=? (basejdbclogger.java:159)
debug 03-23 15:51:26,134 ==> parameters: 1(integer) (basejdbclogger.java:159)
debug 03-23 15:51:26,231 <== total: 1 (basejdbclogger.java:159)
第一次的查询结果,打印了email
eeee
需要dept时,执行对应的sql
debug 03-23 15:51:26,232 ==> preparing: select * from tbl_dept where dept_id=? (basejdbclogger.java:159)
debug 03-23 15:51:26,233 ==> parameters: 1(long) (basejdbclogger.java:159)
debug 03-23 15:51:26,236 <== total: 1 (basejdbclogger.java:159)
department(deptid=1, deptname=组织部)