MyBatis 學習(五) 一對一對映 一對多對映
阿新 • • 發佈:2019-02-11
案例使用兩張表
一張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]