在讲之前,先把javaBean列出来. 因为下面一直在用:
public class Employee { private Integer id; private String lastName; private String email; private String gender; public Employee() { super(); } public Employee(Integer id, String lastName, String email, String gender) { super(); this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]"; }
1.resultType
从这条语句中返回的期望类型的类的完全限定名或别名,如果是集合,应该是集合可以包含的类型.而不是集合本身,此属性和resultMap,不能同时使用
使用1: 返回值是list类型
<!-- public List<Employee> getEmpsByLastNameLike(String lastName); --> <!--resultType:如果返回的是一个集合,要写集合中元素的类型 --> <select id="getEmpsByLastNameLike" resultType="com.kwy.mybatis.bean.Employee"> select * from tbl_employee where last_name like #{lastName} </select>
使用2: 单条记录封装一个map
//返回一条记录的map;key就是列名,值就是对应的值 <!--public Map<String, Object> getEmpByIdReturnMap(Integer id); --> <select id="getEmpByIdReturnMap" resultType="map"> select * from tbl_employee where id=#{id} </select>mybatis已经为常用的类起了别名,map就是其中一个
使用3:多条记录封装一个map
//多条记录封装一个map:Map<Integer,Employee>:键是这条记录的主键,值是记录封装后的javaBean //@MapKey:告诉mybatis封装这个map的时候使用哪个属性作为map的key @MapKey("lastName") public Map<String, Employee> getEmpByLastNameLikeReturnMap(String lastName);
<!--public Map<Integer, Employee> getEmpByLastNameLikeReturnMap(String lastName); --> <select id="getEmpByLastNameLikeReturnMap" resultType="com.kwy.mybatis.bean.Employee"> select * from tbl_employee where last_name like #{lastName} </select>resultType是和自动封装有关, 指定封装什么类型, 数据就封装成什么类型.如果查出来的列名,和javaBean属性名不一样,那么一开始就封装不成功的. 解决办法是,1.写了别名; 2.如果列名和javaBean属性名符合驼峰命名,我们就开启驼峰命名就好了.3.自定义结果集resultMap
2.resultMap
外部resultMap的命名引用,和resultType不能同时使用简单使用
<!-- public Employee getEmpByIdStep(Integer id);--> <select id="getEmpByIdStep" resultMap="MyEmpByStep"> select * from tbl_employee where id=#{id} <if test="_parameter!=null"> and 1=1 </if> </select>更强大的走起:
如果我们的javaBean------Employee中添加了一个部门的属性
public class Employee { private Integer id; private String lastName; private String email; private String gender; //部门属性 private Department dept; public Employee() { super(); } public Employee(Integer id, String lastName, String email, String gender) { super(); this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; } public Department getDept() { return dept; } public void setDept(Department dept) { this.dept = dept; } ......
javaBean-------Department
public class Department { private Integer id; private String departmentName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } @Override public String toString() { return "Department [id=" + id + ", departmentName=" + departmentName + "]"; }场景一
查询Employee的同时查询员工对应的部门
一个员工有与之对应的部门信息;
id last_name gender d_id did dept_name (private Department dept;)
1.联合查询: 采用级联属性封装结果集
<select id="getEmpAndDept" resultMap="MyDifEmp"> SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id, d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d WHERE e.d_id=d.id AND e.id=#{id} </select>
<resultMap type="com.kwy.mybatis.bean.Employee" id="MyDifEmp"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="gender" property="gender"/> <result column="did" property="dept.id"/> <result column="dept_name" property="dept.departmentName"/> </resultMap>
2.使用association定义关联的单个对象的封装规则;
<resultMap type="com.kwy.mybatis.bean.Employee" id="MyDifEmp2"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="gender" property="gender"/> <!-- association可以指定联合的javaBean对象,一个复杂的类型关联;许多结果将包成这种类型 ----嵌入结果映射-结果映射自身的关联; property="dept":指定哪个属性是联合的对象 javaType:指定这个属性对象的类型[不能省略] --> <association property="dept" javaType="com.kwy.mybatis.bean.Department"> <id column="did" property="id"/> <result column="dept_name" property="departmentName"/> </association> </resultMap>上面这种是使用的association的嵌套结果集,还可以使用它的分步查询
我们在现实的开发中,有department表,就会有department的mapper. 也会有根据id来查询部门.
1: 按照员工id查询员工信息
2.根据查询员工信息中的d_id值去部门表查出部门信息
3.部门设置到员工中
<!-- id last_name email gender d_id --> <resultMap type="com.kwy.mybatis.bean.Employee" id="MyEmpByStep"> <id column="id" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <!-- association定义关联对象的封装规则 select:表明当前属性是调用select指定的方法查出的结果 column:指定将哪一列的值传给这个方法 流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性 --> <association property="dept" select="com.kwy.mybatis.dao.DepartmentMapper.getDeptById" column="d_id"> </association> </resultMap> <!-- public Employee getEmpByIdStep(Integer id);--> <select id="getEmpByIdStep" resultMap="MyEmpByStep"> select * from tbl_employee where id=#{id} <if test="_parameter!=null"> and 1=1 </if> </select>
分步查询好处:
1.组合已有的方法
2.可以使用延迟加载
什么叫延迟加载: Employee==>Dept; Employee包含dept属性,我们每次查询Employee对象的时候,都将一起查询出来挺浪费资源的,所以可以改成部门信息在我们使用的时候再去查询
分段查询的基础上加上两个配置就可以实现延迟加载了
配置1.开启懒加载lazyLoadingEnabled, lazy loading开关,默认为true
配置2.aggressiveLazyLoading: 侵略性 lazy loading 开关, 默认为true, 这个属性,如果为true则当你访问任何一个属性都会加载所有的其他lazy load属性,即使你根本没有调用哪个lazy load属性,说白了就是aggressiveLazyLoading=true,则lazy load等于没用,所以要使用lazy load还是将其设为false
在mybatis-config.xml配置文件配置:
<settings> <!--显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题 --> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>场景二
查询部门的时候将部门对应的所有员工信息也查询出来
public class Department { private Integer id; private String departmentName; private List<Employee> emps; public List<Employee> getEmps() { return emps; } public void setEmps(List<Employee> emps) { this.emps = emps; } ...... }
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 --> <resultMap type="com.kwy.mybatis.bean.Department" id="MyDept"> <id column="did" property="id"/> <result column="dept_name" property="departmentName"/> <!-- collection定义关联集合类型的属性的封装规则 ofType:指定集合里面元素的类型 --> <collection property="emps" ofType="com.kwy.mybatis.bean.Employee"> <!-- 定义这个集合中元素的封装规则 --> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> </collection> </resultMap> <!-- public Department getDeptByIdPlus(Integer id); --> <select id="getDeptByIdPlus" resultMap="MyDept"> SELECT d.id did,d.dept_name dept_name, e.id eid,e.last_name last_name,e.email email,e.gender gender FROM tbl_dept d LEFT JOIN tbl_employee e ON d.id=e.d_id WHERE d.id=#{id} </select>
这个查询可不可以做成分布的
<!-- collection:分段查询 --> <resultMap type="com.kwy.mybatis.bean.Department" id="MyDeptStep"> <id column="id" property="id"/> <id column="dept_name" property="departmentName"/> <collection property="emps" select="com.kwy.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId" column="{deptId=id}" fetchType="lazy"></collection> </resultMap> <!-- public Department getDeptByIdStep(Integer id); --> <select id="getDeptByIdStep" resultMap="MyDeptStep"> select id,dept_name from tbl_dept where id=#{id} </select> <!-- 扩展:多列的值传递过去: 将多列的值封装map传递; column="{key1=column1,key2=column2}" fetchType="lazy":表示使用延迟加载; - lazy:延迟 - eager:立即 -->再来说resultMap 另外一个属性: discriminator mybatis可以根据鉴别器判断某列的值,然后根据某列的值来改变封装行为
这里就不举例说明了
下面来说一下mybatis注解
@Select("select * from tb1_employee where id=#{id}") Employee selectByEmpId(String id);这个就是最简单的使用方式了.我是感觉简单的使用注解还行,如果是复杂的,就不太好了. 而且这样总有一种java代码和sql又混在一起的感觉.