> 文章列表 > MyBatis 03 -MyBatis映射

MyBatis 03 -MyBatis映射

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语句的时候要取别名

学习计划指导