mybatis 关联表心得

Posted 吖水的程序路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis 关联表心得相关的知识,希望对你有一定的参考价值。

  1,例如订单表与用户表的关联,一个订单对应一个用户,这是一对一关联;

用代码实现是这样:

A(用resultType去实现的话,如下)

1,使用到继承,

OrderUser extend Order{

 private String username;
    private String address;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}

  这个类只需要写出相关确定需要的信息即可。

2,编写mapper.xml 

OrderUser类继承Orders类后,OrderUser类包括了Orders类的所有字段,只需要定义用户的信息字段即可。 
接着按照需求编写sql语句,在OrderMapper.xml映射文件中添加如下select元素:

<select id="getOrderUserList" resultType="orderuser">
    SELECT
        o.id,
        o.user_id userId,
        o.number,
        o.createtime,
        o.note,
        u.username,
        u.address
    FROM
        orders o
    LEFT JOIN `user` u ON o.user_id = u.id
</select>

3,最后在dao层编写接口
List<OrderUser> getOrderUserList();

最后在OrderMapperTest单元测试类中编写如下测试方法:

@Test
public void testGetOrderUserList() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    List<OrderUser> orderList = orderMapper.getOrderUserList();
    for (OrderUser orderUser : orderList) {
        System.out.println(orderUser);
    }
    sqlSession.close();
}

方法二:
使用resultmap 实现:
定义专门的resultMap用于映射一对一查询结果。首先在Orders类中加入user属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,
所以这里使用单个User对象存储关联查询的用户信息。这样Orders类的代码为:

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

}
重点的区别是,这里增加了一个User的对象属性,下面的mapper 就可以使用属性来进行关联了。
先在OrderMapper.xml映射文件中添加如下select元素:
<select id="getOrderUserResultMap" resultMap="order_user_resultmap">
    SELECT
        o.id,
        o.user_id,
        o.number,
        o.createtime,
        o.note,
        u.username,
        u.address
    FROM
        orders o
    LEFT JOIN `user` u ON o.user_id = u.id
</select>

 

上面id为order_user_resultmap的resultMap也须定义,如下:

<resultMap type="orders" id="order_user_resultmap">
    <id property="id" column="id"/>
    <result property="userId" column="user_id" />
    <result property="number" column="number" />
    <result property="createtime" column="createtime" />
    <result property="note" column="note" />
    <!-- 配置一对一关联映射 -->
    <association property="user" javaType="cn.itheima.mybatis.po.User"> //这个就是关联的属性(通过一对一进行关联)
        <id property="id" column="user_id"/>
        <result property="username" column="username"/>
        <result property="address" column="address"/>
    </association>
</resultMap>

  3,附上resultType 与 resultMap最直观的区别:、

<select id="selectUsers" parameterType="int" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select>
 
使用resultMap
 
<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="username"/>
  <result property="password" column="password"/>
</resultMap>
 
<select id="selectUsers" parameterType="int" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>
 
 
看出来了吧,resultType和resultMap都映射到了User对象中
 
说说不同点吧,resultType 和restltMap
restulyType:
1.对应的是java对象中的属性,大小写不敏感,
2.如果放的是java.lang.Map,key是查询语句的列名,value是查询的值,大小写敏感
3.resultMap:指的是定义好了的id的,是定义好的resyltType的引用
注意:用resultType的时候,要保证结果集的列名与java对象的属性相同,而resultMap则不用,而且resultMap可以用typeHander转换
4.type:java 对象对应的类,id:在本文件要唯一column :数据库的列名或别名,property:对应java对象的属性,jdbcType:java.sql.Types
查询语句中,resultMap属性指向上面那个属性的标签的id
parameterType:参数类型,只能传一个参数,如果有多个参数要封装,如封装成一个类,要写包名加类名,基本数据类型则可以省略
5.一对1、一对多时,若有表的字段相同必须写别名,不然查询结果无法正常映射,出现某属性为空或者返回的结果与想象中的不同,而这往往是没有报错的。
6.若有意外中的错误,反复检查以上几点,和认真核查自己的sql语句,mapper.xml文件是否配置正确。
 
 
另外还有resultMap 元素,它是 MyBatis 中最重要最强大的元素,它能提供级联查询,缓存等功能
 












以上是关于mybatis 关联表心得的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis关联查询,表字段相同,resultMap映射问题的解决办法

mybatis专题-----代码生成器关联查询缓存

mybatis学习笔记三(关联关系)

SpringBoot与Mybatis整合(包含generate自动生成代码工具,数据库表一对一,一对多,关联关系中间表的查询)

MyBatis学习——分步查询与延迟加载

Mybatis-Plus和Mybatis的区别