程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> Mybatis關聯查詢一對一和一對多的實現

Mybatis關聯查詢一對一和一對多的實現

編輯:DB2教程

Mybatis關聯查詢一對一和一對多的實現


本文主要講了使用Mybatis實現關聯查詢,分為一對一和一對多兩種情況,最後並對ResultMap進行一個簡要說明。

一、創建表、分析

下面是兩表,一個是顧客表,一個是車票表。一個顧客可以對應多張車票,但是一張車票只能對應一個顧客

t_customer:顧客表,一個顧客可以對應多張車票

t_ticket:車票表,一張車票只能對應一個顧客

1、創建數據表及插入初始數據

創建數據表

 

use test;
DROP TABLE IF EXISTS t_customer;
CREATE TABLE t_customer(
customerId INT PRIMARY KEY AUTO_INCREMENT,
customerName VARCHAR(20) NOT NULL,
customerTel INT NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS t_ticket;
CREATE TABLE t_ticket(
ticketId INT PRIMARY KEY  AUTO_INCREMENT,
ticketAddress VARCHAR(50) NOT NULL,
ticketPrice INT NOT NULL,
ticketCId INT NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入數據:

 

 

use test;

insert into t_customer values(1,'小王',1888327654);
insert into t_customer values(2,'天天',3456546354);
insert into t_customer values(3,'阿大',123345566);

insert into  t_ticket values(1,'武漢到重慶',100,1);
insert into  t_ticket values(2,'北京到上海',200,1);
insert into  t_ticket values(3,'深圳到廣州',50,1);

傳統的聯合查詢的方法

 

 

select c.*,t.* from t_customer c  JOIN t_ticket t ON (c.customerId=t.ticketCId) where c.customerName ='小王';

 

結果如下:

\

二、工程創建

1、新建java工程,導入需要的包,最後整個工程目錄 如下:

\

2、創建表對應的類:

Customer.java:

 

package com.mucfc.model;
import java.util.List;
/**
 *顧客信息類
 *@author linbingwen
 *@2015年5月13日8:30:12
 */
public class Customer {
	private Integer customerId;
	private String customerName;
	private Integer customerTel;
	private List tickets;//使用一個List來表示車票

	public List getTickets() {
		return tickets;
	}

	public void setTickets(List tickets) {
		this.tickets = tickets;
	}

	public Integer getCustomerId() {
		return customerId;
	}

	public void setCustomerId(Integer customerId) {
		this.customerId = customerId;
	}

	public String getCustomerName() {
		return customerName;
	}

	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}

	public Integer getCustomerTel() {
		return customerTel;
	}

	public void setCustomerTel(Integer customerTel) {
		this.customerTel = customerTel;
	}

	@Override
	public String toString() {
		return "Customer [customerId=" + customerId + ", customerName="
				+ customerName + ", customerTel=" + customerTel+"]";
	}



}

 

Ticket.java:

 

package com.mucfc.model;
/**
 *車票信息類
 *@author linbingwen
 *@2015年5月13日8:30:12
 */
public class Ticket {
	private Integer ticketId;
	private String ticketAddress;
	private Integer ticketPrice;
	private Integer ticketCId;
	private Customer customer;//使用一個customer來表示顧客

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public Integer getTicketId() {
		return ticketId;
	}

	public void setTicketId(Integer ticketId) {
		this.ticketId = ticketId;
	}

	public String getTicketAddress() {
		return ticketAddress;
	}

	public void setTicketAddress(String ticketAddress) {
		this.ticketAddress = ticketAddress;
	}

	public Integer getTicketPrice() {
		return ticketPrice;
	}

	public void setTicketPrice(Integer ticketPrice) {
		this.ticketPrice = ticketPrice;
	}

	public Integer getTicketCId() {
		return ticketCId;
	}

	public void setTicketCId(Integer ticketCId) {
		this.ticketCId = ticketCId;
	}

	@Override
	public String toString() {
		return "Ticket [ticketId=" + ticketId + ", ticketAddress="
				+ ticketAddress + ", ticketPrice=" + ticketPrice
				+ ", ticketCId=" + ticketCId + "]";
	}


}
注意Customer.java:中有個list,list來存放車票,Ticket.java中有一個 customer。

 

3、定義sql映射文件

(1)首先是一對多關聯:

MyBatis中使用collection標簽來解決一對一的關聯查詢,collection標簽可用的屬性如下:property:指的是集合屬性的值ofType:指的是集合中元素的類型column:所對應的外鍵字段名稱select:使用另一個查詢封裝的結果

<?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="com.mucfc.model.CustomerMapper">  
 <!-- 定義數據庫字段與實體對象的映射關系 -->  
    <resultMap type="Customer" id="customerBean">  
        <id column="customerId" property="customerId"/>  
        <result column="customerName" property="customerName"/>  
        <result column="customerTel" property="customerTel"/>       
        <!-- 一對多的關系 -->  
        <!-- property: 指的是集合屬性的值, ofType:指的是集合中元素的類型 -->  
        <collection property="tickets" ofType="Ticket">  
            <id column="ticketId" property="ticketId"/>  
            <result column="ticketAddress" property="ticketAddress"/>  
            <result column="ticketPrice" property="ticketPrice"/>  
            <result column="ticketCId" property="ticketCId"/>  
        </collection>  
    </resultMap>    
      
    <!-- 根據id查詢Person, 關聯將Orders查詢出來 -->  
    <select id="selectCustomerByName" parameterType="string" resultMap="customerBean">  
        select c.*,t.* from t_customer c,t_ticket t  where  c.customerId=t.ticketCId and c.customerName =#{customerName};  
    </select>  
      
 </mapper>  


(2)接著是一對一關聯:

 

MyBatis中使用association標簽來解決一對一的關聯查詢,association標簽可用的屬性如下:property:對象屬性的名稱javaType:對象屬性的類型column:所對應的外鍵字段名稱select:使用另一個查詢封裝的結果

<?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="com.mucfc.model.TicketMapper">  
    <!-- 定義數據庫字段與實體對象的映射關系  -->  
    <resultMap type="Ticket" id="ticketBean">  
        <id column="ticketId" property="ticketId" />  
        <result column="ticketAddress" property="ticketAddress" />  
        <result column="ticketPrice" property="ticketPrice" />  
        <result column="ticketCId" property="ticketCId" />  
        <!-- 一對一的關系 -->  
        <!-- property: 指的是屬性的值, javaType:指的是元素的類型 -->  
        <association property="customer" javaType="Customer">  
            <id column="customerId" property="customerId" />  
            <result column="customerName" property="customerName" />  
            <result column="customerTel" property="customerTel" />  
        </association>  
    </resultMap>  
    <!-- 根據id查詢ticket, 關聯將Customer查詢出來 -->  
    <select id="selectTicketById" parameterType="int" resultMap="ticketBean">  
        select c.*,t.* from t_customer c,t_ticket t where  
        c.customerId=t.ticketCId and t.ticketId =#{ticketId}  
    </select>  
</mapper>  

4、總配置文件

 

<?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>  
        <typeAlias alias="Customer" type="com.mucfc.model.Customer"/>  
        <typeAlias alias="Ticket" type="com.mucfc.model.Ticket" />  
    </typeAliases>  
      
    <!-- 配置數據源相關的信息  -->  
    <environments default="development">  
        <environment id="development">  
            <transactionManager type="JDBC" />  
            <dataSource type="POOLED">  
            <property name="driver" value="com.mysql.jdbc.Driver"/>  
             <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/>   
            <property name="username" value="root"/>   
            <property name="password" value="christmas258@"/>    
            </dataSource>  
        </environment>  
    </environments>  
      
    <!-- 列出映射文件 -->  
    <mappers>  
        <mapper resource="com/mucfc/model/CustomerMapper.xml" />  
        <mapper resource="com/mucfc/model/TicketMapper.xml" />   
    </mappers>  
</configuration>  

5、測試

 

 

package com.mucfc.test;

import java.io.Reader;
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 com.mucfc.model.Customer;
import com.mucfc.model.Ticket;

public class Test {
	private static SqlSessionFactory sqlSessionFactory;
	private static Reader reader;
	static {
		try {
			reader = Resources.getResourceAsReader("mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/*
	 * 一對一關聯查詢
	 */
	public static void selectTicketById(int id) {
		SqlSession session = null;
		try {
			session = sqlSessionFactory.openSession();
			Ticket ticket = (Ticket) session.selectOne(
					"com.mucfc.model.TicketMapper.selectTicketById", id);
			if (ticket == null)
				System.out.println("null");
			else {
				System.out.println(ticket);
				System.out.println(ticket.getCustomer());
			}
		} finally {
			session.close();
		}
	}

	/*
	 * 一對多關聯查詢
	 */
	public static void selectCustomerByName(String string) {
		SqlSession session = null;
		try {
			session = sqlSessionFactory.openSession();
			Customer customer = (Customer) session
					.selectOne(
							"com.mucfc.model.CustomerMapper.selectCustomerByName",
							string);
			if (customer == null)
				System.out.println("null");
			else {
				System.out.println(customer);
				List tickets = customer.getTickets();
				for (Ticket ticket : tickets) {
					System.out.println(ticket);
				}
			}
		} finally {
			session.close();
		}
	}

	public static void main(String[] args) {
		System.out.println("==============一對一查詢,根據車票來查顧客===============");
		selectTicketById(1);
		System.out.println("==============多對一查詢,根據顧客來查車票===============");
		selectCustomerByName("小王");

	}

}

結果:

 

\

結果顯示,查詢正確。

三、ResultMap標簽                        

 

 

MyBatis中在查詢進行select映射的時候,返回類型可以用resultType,也可以用resultMap,resultType是直接表示返回類型的,而resultMap則是對外部ResultMap的引用,但是resultType跟resultMap不能同時存在。在MyBatis進行查詢映射的時候,其實查詢出來的每一個屬性都是放在一個對應的Map裡面的,其中鍵是屬性名,值則是其對應的值。當提供的返回類型屬性是resultType的時候,MyBatis會將Map裡面的鍵值對取出賦給resultType所指定的對象對應的屬性。所以其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當我們提供的返回類型屬性是resultType的時候,MyBatis對自動的給我們把對應的值賦給resultType所指定對象的屬性,而當我們提供的返回類型是resultMap的時候,因為Map不能很好表示領域模型,我們就需要自己再進一步的把它轉化為對應的對象,這常常在復雜查詢中很有作用。

當Java接口與XML文件在一個相對路徑下時,可以不在myBatis配置文件的mappers中聲明:

<!-- 列出映射文件 -->  
<mappers>  
    <mapper resource="com/mucfc/model/CustomerMapper.xml" />  
    <mapper resource="com/mucfc/model/TicketMapper.xml" />   
</mappers>  

SQL 映射XML 文件一些初級的元素:

1. cache – 配置給定模式的緩存
2. cache-ref – 從別的模式中引用一個緩存
3. resultMap – 這是最復雜而卻強大的一個元素了,它描述如何從結果集中加載對象
4. sql – 一個可以被其他語句復用的SQL 塊
5. insert – 映射INSERT 語句
6. update – 映射UPDATE 語句
7. delete – 映射DELEETE 語句
8. select - 映射SELECT語句

 


resultMap 是MyBatis 中最重要最強大的元素了。你可以讓你比使用JDBC 調用結果集省掉90%的代碼,也可以讓你做許多JDBC 不支持的事。現實上,要寫一個等同類似於交互的映射這樣的復雜語句,可能要上千行的代碼。ResultMaps 的目的,就是這樣簡單的語句而不需要多余的結果映射,更多復雜的語句,除了只要一些絕對必須的語句描述關系以外,再也不需要其它的。
resultMap屬性:type為java實體類;id為此resultMap的標識。
resultMap可以設置的映射:

1. constructor – 用來將結果反射給一個實例化好的類的構造器
a) idArg – ID 參數;將結果集標記為ID,以方便全局調用
b) arg –反射到構造器的通常結果
2. id – ID 結果,將結果集標記為ID,以方便全局調用
3. result – 反射到JavaBean 屬性的普通結果
4. association – 復雜類型的結合;多個結果合成的類型
a) nested result mappings – 幾resultMap 自身嵌套關聯,也可以引用到一個其它上
5. collection –復雜類型集合a collection of complex types
6. nested result mappings – resultMap 的集合,也可以引用到一個其它上
7. discriminator – 使用一個結果值以決定使用哪個resultMap
a) case – 基本一些值的結果映射的case 情形
i. nested result mappings –一個case 情形本身就是一個結果映射,因此也可以包括一些相同的元素,也可以引用一個外部resultMap。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved