本文主要講了使用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>
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>
<?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>
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("小王");
}
}

結果顯示,查詢正確。
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>
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。