【Mybatis】Mybatis關聯查詢一對一和一對多的實現,mybatis一對一

來源:互聯網
上載者:User

【Mybatis】Mybatis關聯查詢一對一和一對多的實現,mybatis一對一

   林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

  本文主要講了使用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<Ticket> tickets;//使用一個List來表示車票public List<Ticket> getTickets() {return tickets;}public void setTickets(List<Ticket> 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;}@Overridepublic 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;}@Overridepublic 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 wherec.customerId=t.ticketCId and t.ticketId =#{ticketId}</select></mapper>

4、總設定檔

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//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<Ticket> 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 types6. nested result mappings – resultMap 的集合,也可以引用到一個其它上7. discriminator – 使用一個結果值以決定使用哪個resultMapa) case – 基本一些值的結果映射的case 情形i. nested result mappings –一個case 情形本身就是一個結果映射,因此也可以包括一些相同的元素,也可以引用一個外部resultMap。

   林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka


相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.