MyBatis 03 -MyBatis映射

文章详细介绍了MyBatis在ORM映射上的常见问题及解决方案,包括列别名、Map集合映射和自定义ResultMap。同时,深入探讨了MyBatis的高级映射特性,如一对一(OneToOne)、一对多(OneToMany)和多对多(ManyToMany)关系的映射方法,包括直接返回Map、实体类关联和分步查询等不同方案。
摘要由CSDN通过智能技术生成

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yinying293

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值