Java基礎-SSM之mybatis一對多和多對一關系映射
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.准備測試環境(創建數據庫表)
1>.創建customers表;
use yinzhengjie; create table if not exists customers(id int primary key auto_increment,name varchar(20) , age int) ;
2>.創建orders表
use yinzhengjie; create table orders(id int primary key auto_increment , orderno varchar(20) , price float , cid int) ;
3>.創建指定的包名和文件,具體結構如下:
4>.添加Maven依賴
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 <groupId>cn.org.yinzhengjie</groupId> 7 <artifactId>Mybatis</artifactId> 8 <version>1.0-SNAPSHOT</version> 9 <dependencies> 10 <dependency> 11 <groupId>junit</groupId> 12 <artifactId>junit</artifactId> 13 <version>4.11</version> 14 </dependency> 15 <dependency> 16 <groupId>mysql</groupId> 17 <artifactId>mysql-connector-java</artifactId> 18 <version>5.1.17</version> 19 </dependency> 20 <dependency> 21 <groupId>org.mybatis</groupId> 22 <artifactId>mybatis</artifactId> 23 <version>3.2.1</version> 24 </dependency> 25 </dependencies> 26 </project>
二.編寫自定義類
1>.編寫Customer類
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.mybatis.domain.one2many; 7 8 import java.util.ArrayList; 9 import java.util.List; 10 11 /** 12 * 客戶 13 */ 14 public class Customer { 15 private Integer id ; 16 private String name ; 17 private int age ; 18 19 //建立從Customer到Order之間一對多關系,因為一個客戶可能會有多個訂單。我們將多個訂單放在一個list中。 20 private List<Order> orders = new ArrayList<Order>() ; 21 22 public List<Order> getOrders() { 23 return orders; 24 } 25 26 public void setOrders(List<Order> orders) { 27 this.orders = orders; 28 } 29 30 public Integer getId() { 31 return id; 32 } 33 34 public void setId(Integer id) { 35 this.id = id; 36 } 37 38 public String getName() { 39 return name; 40 } 41 42 public void setName(String name) { 43 this.name = name; 44 } 45 46 public int getAge() { 47 return age; 48 } 49 50 public void setAge(int age) { 51 this.age = age; 52 } 53 }
2>.編寫Order類
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.mybatis.domain.one2many; 7 8 /** 9 * 訂單 10 */ 11 public class Order { 12 private Integer id ; 13 private String orderno ; 14 private float price ; 15 //建立從Order到Customer之間多對一關聯關系 16 private Customer customer ; 17 18 public Integer getId() { 19 return id; 20 } 21 22 public void setId(Integer id) { 23 this.id = id; 24 } 25 26 public String getOrderno() { 27 return orderno; 28 } 29 30 public void setOrderno(String orderno) { 31 this.orderno = orderno; 32 } 33 34 public float getPrice() { 35 return price; 36 } 37 38 public void setPrice(float price) { 39 this.price = price; 40 } 41 42 public Customer getCustomer() { 43 return customer; 44 } 45 46 public void setCustomer(Customer customer) { 47 this.customer = customer; 48 } 49 }
三.編寫配置文件
1>.mybatis-config.xml 文件內容
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <properties> 7 <property name="driver" value="com.mysql.jdbc.Driver"/> 8 <property name="url" value="jdbc:mysql://localhost:5200/yinzhengjie"/> 9 <property name="username" value="root"/> 10 <property name="password" value="yinzhengjie"/> 11 </properties> 12 13 <!-- 我們使用typeAliases標簽給我們自定義類起個別名。--> 14 <typeAliases> 15 <typeAlias type="cn.org.yinzhengjie.mybatis.domain.one2many.Customer" alias="_Customer" /> 16 <typeAlias type="cn.org.yinzhengjie.mybatis.domain.one2many.Order" alias="_Order" /> 17 </typeAliases> 18 19 <environments default="development"> 20 <environment id="development"> 21 <transactionManager type="JDBC"/> 22 <dataSource type="POOLED"> 23 <property name="driver" value="${driver}"/> 24 <property name="url" value="${url}"/> 25 <property name="username" value="${username}"/> 26 <property name="password" value="${password}"/> 27 </dataSource> 28 </environment> 29 </environments> 30 <mappers> 31 <!-- 我們使用mapper標簽指定映射文件,使用resource指定具體的路徑,如果沒有寫絕對路徑,默認的根路徑就在resources目錄中--> 32 <mapper resource="CustomerMapper.xml"/> 33 <mapper resource="OrderMapper.xml"/> 34 </mappers> 35 </configuration>
2>.OrderMapper.xml 文件內容
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 <!-- 定義名字空間 --> 5 <mapper namespace="orders"> 6 <insert id="insert"> 7 <!-- 注意,我們傳遞的參數 #{customer.id}是對象的屬性,因此,這里千萬別寫cid,盡管我們在創建數據庫中定義的有這個字段,但是我們在定義類的時候是把它定義為對象的一個屬性! --> 8 insert into orders(orderno, price , cid) values(#{orderno}, #{price} , #{customer.id}) ; 9 </insert> 10 11 <!--用resultMap標簽定義數據庫的查詢結果映射,這個結果不能直接和我們自定義的類進行交互,需要通過resultMap標簽定義結果映射才能使用我們自定義的類接收數據。--> 12 <select id="selectOne" resultMap="rm_Order"> 13 SELECT 14 <!-- 定義需要查詢的別名 --> 15 o.id oid , 16 o.orderno oorderno , 17 o.price oprice , 18 o.cid ocid , 19 c.id cid , 20 c.name cname , 21 c.age cage 22 FROM 23 <!-- 定義需要查詢的字段 --> 24 orders o 25 <!-- 使用左外連接查詢 --> 26 LEFT OUTER JOIN customers c on o.cid = c.id 27 where 28 o.id = #{id} 29 </select> 30 <select id="selectAll" resultMap="rm_Order"> 31 SELECT 32 o.id oid , 33 o.orderno oorderno , 34 o.price oprice , 35 o.cid ocid , 36 c.id cid , 37 c.name cname , 38 c.age cage 39 FROM 40 orders o 41 LEFT OUTER JOIN customers c on o.cid = c.id 42 </select> 43 44 <!-- 使用resultMap標簽定義結果映射,即將id為"rm_Order"的查詢結果和我們自定義的類做一個關聯關系,否則直接拿查詢出來的結果字段和我們自定義的字段是對應不上的!--> 45 <resultMap id="rm_Order" type="_Order"> 46 <!--將查詢結果“oid”字段對應為我們自定義別名類“_Order”的“id"字段--> 47 <id column="oid" property="id" /> 48 <result column="oorderno" property="orderno"/> 49 <result column="oprice" property="price"/> 50 51 52 <!-- 多對一關聯關系 --> 53 <!-- 使用association這個標簽可以建立關聯屬性, property表示"_Order"的屬性,column是通過上面定義的"ocid"別名來查詢的,而javaType表示指定"customer"歲對應的屬性為"_Customer" --> 54 <association property="customer" column="ocid" javaType="_Customer"> 55 <!--下面就是具體的對應關系。--> 56 <id column="cid" property="id" /> 57 <result column="cname" property="name" /> 58 <result column="cage" property="age" /> 59 </association> 60 </resultMap> 61 </mapper>
3>.CustomerMapper.xml 文件內容
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 <!-- 定義名字空間 --> 5 <mapper namespace="customers"> 6 <!-- useGeneratedKeys的值為true時,表示需要使用數據庫深層的keys,同時我們需要指定使用哪個深層的key。而指定具體使用哪個key我們使用keyProperty來定義! --> 7 <insert id="insert" useGeneratedKeys="true" keyProperty="id"> 8 <!-- 注意,#{name}, #{age}中的name和age字樣必須和我們自定義類要一致喲! --> 9 insert into customers(name, age) values(#{name}, #{age}) ; 10 </insert> 11 12 <!--用resultMap標簽定義數據庫的查詢結果映射,這個結果不能直接和我們自定義的類進行交互,需要通過resultMap標簽定義結果映射才能使用我們自定義的類接收數據。--> 13 <select id="selectOne" resultMap="rm_Customer"> 14 select 15 c.id cid , 16 c.name cname , 17 c.age cage , 18 o.id oid , 19 o.orderno oorderno , 20 o.price oprice , 21 o.cid ocid 22 from 23 customers c left outer join orders o on o.cid = c.id 24 where 25 c.id = #{id} ; 26 </select> 27 28 <resultMap id="rm_Customer" type="_Customer"> 29 <id column="cid" property="id"/> 30 <result column="cname" property="name"/> 31 <result column="cage" property="age"/> 32 <!--使用collection這個標簽可以建立關聯屬性。多對一關系映射--> 33 <collection property="orders" ofType="_Order" column="ocid"> 34 <id column="oid" property="id"/> 35 <result column="oorderno" property="orderno" /> 36 <result column="oprice" property="price"/> 37 </collection> 38 </resultMap> 39 40 </mapper>
四.編寫測試代碼
1>.編寫測試代碼如下:
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.mybatis.test; 7 8 import cn.org.yinzhengjie.mybatis.domain.one2many.Customer; 9 import cn.org.yinzhengjie.mybatis.domain.one2many.Order; 10 import org.apache.ibatis.io.Resources; 11 import org.apache.ibatis.session.SqlSession; 12 import org.apache.ibatis.session.SqlSessionFactory; 13 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 14 import org.junit.Test; 15 16 import java.io.InputStream; 17 import java.util.List; 18 19 20 public class TestOne2Many { 21 /** 22 * 測試往Customer插入指定的數據 23 */ 24 @Test 25 public void testInsertCustomer() throws Exception { 26 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); 27 SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in); 28 SqlSession sess = sf.openSession(); 29 Customer c = new Customer(); 30 c.setName("yinzhengjie"); 31 c.setAge(18); 32 sess.insert("customers.insert", c); 33 34 Order o = new Order(); 35 o.setOrderno("no001"); 36 o.setPrice(100); 37 //設置關聯關系 38 o.setCustomer(c); 39 40 sess.insert("orders.insert" , o) ; 41 sess.commit(); 42 sess.close(); 43 } 44 45 /** 46 * 測試查詢指定的order 47 */ 48 @Test 49 public void testSelectOneOrder() throws Exception { 50 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); 51 SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in); 52 SqlSession sess = sf.openSession(); 53 Order o = sess.selectOne("orders.selectOne" , 1); 54 System.out.println(o.getOrderno()); 55 List<Order> orders = sess.selectList("orders.selectAll"); 56 for(Order obj : orders){ 57 System.out.print(obj.getOrderno()); 58 Customer c = obj.getCustomer() ; 59 if(c != null){ 60 System.out.println(c.getName()); 61 } 62 else{ 63 System.out.println(); 64 } 65 } 66 sess.commit(); 67 sess.close(); 68 } 69 70 71 /** 72 * 測試查詢指定的Customer 73 */ 74 @Test 75 public void testSelectCustomer() throws Exception { 76 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); 77 SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in); 78 SqlSession sess = sf.openSession(); 79 Customer c = sess.selectOne("customers.selectOne" , 1); 80 for(Order o : c.getOrders()){ 81 System.out.println(o.getId() + " " + o.getOrderno()); 82 } 83 sess.commit(); 84 sess.close(); 85 } 86 }
2>.查詢數據庫執行結果如下: