MyBatis映射
1 ORM映射
1.1 MyBatis自动ORM失效
MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。
1.2 方案一:列的别名
在SQL中使用 as 为查询字段添加列别名,以匹配属性名
<select id="getAll1" resultType="product">
select p_id pid,t_id tid,p_name name,p_time time,p_price price ,
p_state state ,p_image image, p_info info,isdel del from product;
</select>
1.3 方案二:直接使用Map集合映射结果
常用的java类,mybatis已经取了类型别名了
不用写成
<select id="selectAll2" resultType="java.util.map">
<select id="getAll2" resultType="map">
select * from product;
</select>
//解决方法2:直接返回一个Map集合
List<Map<String,Object>> getAll2();
1.4 方案三:自定义结果映射(ResultMap)
<!-- resultMap属性 表示自定义映射的id -->
<select id="getAll3" resultMap="productMap" >
select * from product;
</select>
<!-- resultMap标签 表示自定义映射 id:唯一标识 type:映射类型 -->
<resultMap id="productMap" type="product">
<!-- id标签一般表示主键 result标签一般表示普通字段 (不是必须的) -->
<!-- 属性:d
column 表示数据库中的字段名 property表示实体类中的属性名
djavaType 表示java中的类型 jdbcType表示数据类型中数据类型(mybatis可以自动识别) -->
<id column="p_id" property="pid"/>
<result column="t_id" property="tid"/>
<result column="p_name" property="name"/>
<result column="p_time" property="time"/>
<result column="p_price" property="price"/>
<result column="p_info" property="info"/>
<result column="p_state" property="state"/>
<result column="p_image" property="image"/>
<result column="isdel" property="del"/>
</resultMap>
2 MyBatis高级映射
全局懒加载
association 一对一的关联映射
property:实体类中属性名称(在Person类中定义的Passport属性的名称)
javaType:映射对应java类型collection:一对多的关联映射
property:关联的实体类中的集合的属性名
ofType: 集合泛型的类型
2.1 数据库中表的关系
实体间的关系:关联关系
OneToOne:一对一关系(person— passport)
OneToMany:一对多关系(dept— emp)
多对一(多个一对一)
ManyToMany:多对多关系(student— teacher)
多个一对多
2.2 OneToOne
SQL参考person表和passport表
三种实现方案
- 直接返回一个Map集合
- 实体类中进行关联,mapper中做映射
- 分步查询,实现懒加载(了解)
2.2.1 方案一:返回Map
映射代码
//1、直接将连表查询的结果映射到Map中(写一个公共类(将两个表的写到一个新的类中)) (一般不推荐这样操作)
List<Map<String,Object>> getAll1();
<select id="getAll1" resultType="map">
select * from person p INNER JOIN passport pp on p.pid = pp.id;
</select>
2.2.2 方案二:实体类关联
实体类关联
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private Integer id;
private String name;
private Integer age;
private String phone;
private String pid;
private Passport passport;
}
映射代码
<select id="getAll2" resultMap="personMap">
select p.*,pp.id p_id,pp.info,pp.fromAdd ,pp.toAdd , pp.uid from person p INNER JOIN passport pp on p.pid = pp.id;
</select>
<resultMap id="personMap" type="person">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="phone" property="phone"/>
<result column="pid" property="pid"/>
<!--
association 一对一的关联映射
property:实体类中属性名称(在Person类中定义的Passport属性的名称)
javaType:映射对应java类型
-->
<association property="passport" javaType="priv.yinying.pojo.Passport">
<id column="p_id" property="id"/>
<result column="info" property="info"/>
<result column="fromAdd" property="fromAdd"/>
<result column="toAdd" property="toAdd"/>
<result column="uid" property="uid"/>
</association>
</resultMap>
- 注意:指定“一方”关系时(对象),使用< association property=“” javaType=“” >
2.2.3 方案三:分步查询
实体类关联
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private Integer id;
private String name;
private Integer age;
private String phone;
private String pid;
private Passport passport;
}
映射代码
<select id="getAll3" resultMap="personMap1">
select * from person
</select>
<resultMap id="personMap1" type="person">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="phone" property="phone"/>
<result column="pid" property="pid"/>
<!--
association 一对一的关联映射
property:实体类中属性名称(在Person类中定义的Passport属性的名称)
javaType:映射对应java类型
select:分步查询的方法
column:根据指定外键做查询
fetchType:设置懒加载 eager:积极加载(无论是否使都会查询) lazy:懒加载(什么时候使用什么时候查询)
-->
<association property="passport"
javaType="priv.yinying.pojo.Passport"
select="selectPassport"
column="pid"
fetchType="lazy">
</association>
</resultMap>
<select id="selectPassport" resultType="passport" >
select * from passport where id = #{pid}
</select>
2.3 OneToMany
SQL参考emp表和dept表
2.3.1 方案一:返回Map
//此方式不适合一对多的查询情况
2.3.2 方案二:实体类关联
实体类关联
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private Integer deptno;
private String dname;
private String location;
//一对多
private List<Emp> empList;
}
映射代码
<select id="getAll2" resultMap="deptMap">
select * from dept d INNER JOIN emp e on d.deptno = e.deptno;
</select>
<resultMap id="deptMap" type="dept">
<id column="deptno" property="deptno"/>
<result column="dname" property="dname"/>
<result column="location" property="location"/>
<!--
collection:一对多的关联映射
property:关联的实体类中的集合的属性名
ofType: 集合泛型的类型
-->
<collection property="empList" ofType="emp">
<id column="empno" property="empno"/>
<result column="ename" property="ename"/>
<result column="job" property="job"/>
<result column="mgr" property="mgr"/>
<result column="hiredate" property="hiredate"/>
<result column="sal" property="sal"/>
<result column="comm" property="comm"/>
<result column="deptno" property="deptno"/>
<result column="image" property="image"/>
</collection>
</resultMap>
2.3.3 方案三:分步查询
实体类关联
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private Integer deptno;
private String dname;
private String location;
//一对多
private List<Emp> empList;
}
映射代码
<select id="getAll3" resultMap="deptMap1">
select * from dept;
</select>
<resultMap id="deptMap1" type="dept">
<id column="deptno" property="deptno"/>
<result column="dname" property="dname"/>
<result column="location" property="location"/>
<collection property="empList"
ofType="emp"
select="selectEmp"
column="deptno"
fetchType="lazy"/>
</resultMap>
<select id="selectEmp" resultType="emp">
select * from emp where deptno = #{deptno}
</select>
- 注意:指定“多方”关系时(集合),使用< collection ofType=“” property=“” >
2.4 ManyToMany
SQL参考student表和teacher表
2.4.1 方案一:实体类关联
实体类关联
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Double score;
private List<Teacher> teacherList;
}
映射代码
<select id="getAll1" resultMap="studentMap">
select s.id sid,s.name sname , s.score score , t.*
from student s INNER JOIN t_s ts on s.id = ts.sid INNER JOIN teacher t on t.id = ts.tid
</select>
<resultMap id="studentMap" type="student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="score" property="score"/>
<!-- 一对多的关联映射 -->
<collection property="teacherList" ofType="teacher">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="job" property="job"/>
</collection>
</resultMap>
8.4.2 方案二:分步查询
与上面一对多的分步查询一致
注意:连表查询的时候,如果两张表有同名字段,在写sql语句的时候要取别名