MyBatis 03 -MyBatis映射
MyBatis映射
-
- 1 ORM映射
-
- 1.1 MyBatis自动ORM失效
- 1.2 方案一:列的别名
- 1.3 方案二:直接使用Map集合映射结果
- 1.4 方案三:自定义结果映射(ResultMap)
- 2 MyBatis高级映射
-
- 2.1 数据库中表的关系
- 2.2 OneToOne
-
- 2.2.1 方案一:返回Map
- 2.2.2 方案二:实体类关联
- 2.2.3 方案三:分步查询
- 2.3 OneToMany
-
- 2.3.1 方案一:返回Map
- 2.3.2 方案二:实体类关联
- 2.3.3 方案三:分步查询
- 2.4 ManyToMany
-
- 2.4.1 方案一:实体类关联
- 8.4.2 方案二:分步查询
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标签一般表示普通字段 (不是必须的) --><!-- 属性:dcolumn 表示数据库中的字段名 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语句的时候要取别名