1. 程式人生 > >MyBatis 學習(五) 一對一對映 一對多對映

MyBatis 學習(五) 一對一對映 一對多對映

案例使用兩張表

一張user使用者表
這裡寫圖片描述
這裡寫圖片描述

對映關係分析
首先,站在訂單的角度考慮:
一張訂單對應一個使用者,這是一對一
然後,站在使用者的角度考慮:
一個使用者可以有多個訂單,這是一對多

那麼SQL語句該如何寫?
還記得外聯接嗎,left/right join
以某張表為主,取出裡面所有記錄,然後每條記錄與另外一張表進行連線
不管能不能匹配上條件,最終都會保留;能匹配,正確保留,不匹配,其他表的欄位都置空
也就是說,以哪張表為主,哪張表的記錄保留的最完整,另外一張是殘缺的,因為有些欄位沒能和主表匹配上

一對一

以訂單為主所以sql語句如下

       select o.* ,
         u.username
         from orders as o left join user as u
         on o.user_id = u.id

下面放案例原始碼:

寫兩個bean
user 、orders
在一對一中,為表示兩者關係,在orders中存一個user變數 表示一對一
user

public class User {

    private int id ;
    private String username ;
    private Date birthday ;
    private
String sex ; private String address ; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public
Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", birthday=" + birthday + ", sex=" + sex + ", address=" + address + "]"; } }

orders

public class Orders {

    private int id ;
    private int user_id ;
    private Integer number ;
    private Date createtime ;
    private String note ;
    private User user ;


    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getUser_id() {
        return user_id;
    }
    public void setUser_id(int user_id) {
        this.user_id = user_id;
    }
    public Integer getNumber() {
        return number;
    }
    public void setNumber(Integer number) {
        this.number = number;
    }
    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;
    }
    @Override
    public String toString() {
        return "Orders [id=" + id + ", user_id=" + user_id + ", number=" + number + ", createtime=" + createtime
                + ", note=" + note + "]";
    }
}

MyBatis總配置檔案
SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

   <!-- 別名 -->
   <typeAliases>
         <package name="cn.itcast.bean"/>
   </typeAliases>

   <!-- 環境配置 -->
   <environments default="development">
      <environment id="development">
         <!-- 使用jdbc事務管理 -->
         <transactionManager type="JDBC" />
         <!-- 資料庫連線池 -->
         <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver" />
            <property name="url"
               value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
            <property name="username" value="root" />
            <property name="password" value="root" />
         </dataSource>
      </environment>
   </environments>

   <!-- 對映 -->
   <mappers>
      <package name="cn/itcast/dao"/>
   </mappers>

</configuration>

由於我們以訂單表為主,所以為訂單生產代理介面
放回List 訂單不止一個所以用list

public interface OrdersDao {

//    一對一   一份訂單對應一個使用者
    List <Orders> findOrders () ;

}

Mapper.xml
使用resultMap完成對映關係

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.dao.OrdersDao">

   <resultMap type="orders" id="o">
      <!-- 在一對一或一對多查詢中,resultMap的自動設值容易失效,所以最好手動設值 -->
      <id column="id" property="id"/>
      <result column="user_id" property="user_id"/>
      <result column="number" property="number"/>
      <result column="createtime" property="createtime"/>

      <!-- 一對一   javaType表示儲存型別  一定要寫否則報錯-->
      <association property="user" javaType="user">
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
      </association>
   </resultMap>

   <select id="findOrders"  resultMap="o">
         select o.* ,
         u.username
         from orders as o left join user as u
         on o.user_id = u.id
   </select>
</mapper>

test

/**
 *
 */
package cn.itcast.bean;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import cn.itcast.dao.OrdersDao;

/**
 * @author Administrator
 *
 */
public class Demo {

    @Test
    public void one2one () throws IOException
    {
      String resource = "SqlMapConfig.xml" ;
      InputStream in = Resources.getResourceAsStream(resource) ;

      SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in) ;

      SqlSession ss =  ssf.openSession() ;

      OrdersDao od = ss.getMapper(OrdersDao.class) ;

       List <Orders> o = od.findOrders() ;

      for ( Orders or : o ){
          System.out.println(or);
          if (or.getUser()!=null)
          {
              System.out.println("    " + or.getUser());
          }
          System.out.println();
      }

    }
}


結果
Orders [id=3, user_id=1, number=1000010, createtime=Wed Feb 04 13:22:35 CST 2015, note=null]
   User [id=1, username=王五, birthday=null, sex=null, address=null]

Orders [id=4, user_id=1, number=1000011, createtime=Tue Feb 03 13:22:41 CST 2015, note=null]
   User [id=1, username=王五, birthday=null, sex=null, address=null]

Orders [id=5, user_id=10, number=1000012, createtime=Thu Feb 12 16:13:23 CST 2015, note=null]
   User [id=10, username=張三, birthday=null, sex=null, address=null]

Orders [id=6, user_id=30, number=44444, createtime=Fri Jan 26 18:07:52 CST 2018, note=null]
   User [id=30, username=哈哈, birthday=null, sex=null, address=null]

一對多

   select
      o.id ,
      o.user_id ,
      o.number ,
      o.createtime,
      u.username
         from  user as u  inner join  orders as o
         on o.user_id = u.id

一個使用者可以有多個訂單
在userbean中加上一個list集合存放orders,生成getset方法

   private List<Orders> list ;


   public List<Orders> getList() {
      return list;
   }
   public void setList(List<Orders> list) {
      this.list = list;
   }

這次是以user表為主,我們為user表生成代理介面
返回list 一個user代表一個使用者一個使用者裡面包含多個訂單 ,使用者不止一個,所以用list

/**
 *
 */
package cn.itcast.dao;

import java.util.List;

import cn.itcast.bean.User;

/**
 * @author Administrator
 *
 */
public interface UserDao {

    List <User> findUser() ;
}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.dao.UserDao">

   <resultMap type="user" id="u">
      <!-- 在一對一或一對多查詢中,resultMap的自動設值容易失效,所以最好手動設值 -->
      <id column="user_id" property="id"/>
      <result column="username" property="username"/>

      <!-- 一對多   javaType表示儲存型別  一定要寫否則報錯 ofType 裡面存放集合的泛型型別-->
      <collection property="list" javaType="List" ofType="orders">
         <id column="id" property="id"/>
         <result column="user_id" property="user_id"/>
         <result column="number" property="number"/>
         <result column="createtime" property="createtime"/>
      </collection>
   </resultMap>

   <select id="findUser"  resultMap="u">
         select
      o.id ,
      o.user_id ,
      o.number ,
      o.createtime,
      u.username
         from  user as u  inner join  orders as o
         on o.user_id = u.id
   </select>
</mapper>

test

@Test
   public void one2many () throws IOException
   {
     String resource = "SqlMapConfig.xml" ;
      InputStream in = Resources.getResourceAsStream(resource) ;

      SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in) ;

      SqlSession ss =  ssf.openSession() ;

      UserDao ud = ss.getMapper(UserDao.class) ;

      List <User> list = ud.findUser() ;

      for ( User u : list )
      {
        System.out.println(u);
        List<Orders> or = u.getList() ;
        for ( Orders o : or )
        {
           System.out.println(" " +o);
        }
      }
   }

結果
User [id=1, username=王五, birthday=null, sex=null, address=null]
 Orders [id=3, user_id=1, number=1000010, createtime=Wed Feb 04 13:22:35 CST 2015, note=null]
 Orders [id=4, user_id=1, number=1000011, createtime=Tue Feb 03 13:22:41 CST 2015, note=null]
User [id=10, username=張三, birthday=null, sex=null, address=null]
 Orders [id=5, user_id=10, number=1000012, createtime=Thu Feb 12 16:13:23 CST 2015, note=null]
User [id=30, username=哈哈, birthday=null, sex=null, address=null]
 Orders [id=6, user_id=30, number=44444, createtime=Fri Jan 26 18:07:52 CST 2018, note=null]