1. 程式人生 > >MyBatis一對多和多對一

MyBatis一對多和多對一

     在學習MyBatis3的過程中,文件上面一直在強調一個id的東西!在做這個實驗的時候,也因為沒有理解清楚id含義而導致一對多的“多”中也只有一條資料。id和result的唯一不同是id表示的結果將是當比較物件例項時用到的標識屬性。這幫助來改進整體表現,特別是快取和嵌入結果對映。所以不同資料的id應該唯一區別,不然導致資料結果集只有一條資料。

一、表

二、實體

1.person

package com.kerwin.mybatis.pojo;

import java.util.List;

public class Person {

	private int id;
	private String name;
	private List<Orders> orderList;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Orders> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<Orders> orderList) {
		this.orderList = orderList;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + "]";
	}

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(int id, String name, List<Orders> orderList) {
		super();
		this.id = id;
		this.name = name;
		this.orderList = orderList;
	}

}

2.order
package com.kerwin.mybatis.pojo;

public class Orders {
	private int id;
	private double price;
	private Person person;
	
	
	
	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}



	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}


	

	@Override
	public String toString() {
		return "Orders [id=" + id + ", price=" + price + "]";
	}

	public Orders() {
		super();
		// TODO Auto-generated constructor stub
	}

}

三、對映mapper檔案

1. PersonMapper.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="com.kerwin.mybatis.pojo.Person">
	<resultMap type="com.kerwin.mybatis.pojo.Person" id="personreSultMap">
		<id column="p_id" property="id"/>
		<result column="name" property="name"/>
		<collection property="orderList" ofType="com.kerwin.mybatis.pojo.Orders" column="pid">
			<id column="o_id" property="id"/>
			<result column="price" property="price"/>
		</collection>
		
	</resultMap>
	
	<select id="selectPersonFetchOrder" parameterType="int" resultMap="personreSultMap" >
		select p.*,o.* from person p,orders o where o.pid=p.p_id and p.p_id=#{id}
	</select>
	
	
</mapper>

2.     OrdersMapper.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="com.kerwin.mybatis.pojo.Orders">
	<resultMap type="com.kerwin.mybatis.pojo.Orders" id="OrdersResultMap">
		<id column="o_id" property="id"/>
		<result column="price" property="price"/>
		<association property="person" javaType="com.kerwin.mybatis.pojo.Person">
			<id column="p_id" property="id"/>
			<result column="name" property="name"/>
		</association>
	</resultMap>
	
	<select id="selectOrdersFetchPerson" resultMap="OrdersResultMap">
		select p.*,o.* from person p,orders o where o.pid=p.p_id and o.o_id=#{id} 
	</select>

</mapper>

3.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>
	<typeAlias type="com.kerwin.mybatis.pojo.Author" alias="Author"/>
</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/mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
	<mapper resource="com/kerwin/mybatis/pojo/AuthorMapper.xml"/>
	<mapper resource="com/kerwin/mybatis/pojo/PostMapper.xml"/>
	<mapper resource="com/kerwin/mybatis/pojo/PersonMapper.xml"/>
	<mapper resource="com/kerwin/mybatis/pojo/OrdersMapper.xml"/>
  </mappers>
</configuration>

四。測試類
/**
 * 
 */
package com.kerwin.mybatis.test;

import java.io.InputStream;

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.BeforeClass;
import org.junit.Test;

import com.kerwin.mybatis.pojo.Orders;
import com.kerwin.mybatis.pojo.Person;

/**
 * @author Administrator
 * 
 */
public class PersonAndOrderTest {

	private static SqlSessionFactory sessionFactory;
	
	/**
	 * @throws java.lang.Exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
		InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
		sessionFactory = factoryBuilder.build(inputStream);

	}
	
	//一對多,查詢person(一)級聯查詢訂單order(多)
	@Test
	public void testSelectPersonFetchOrder() throws Exception {
		SqlSession session = sessionFactory.openSession();
		Person person = session.selectOne("com.kerwin.mybatis.pojo.Person.selectPersonFetchOrder", 1);
		System.out.println(person);
		System.out.println(person.getOrderList().size());
		for(Orders orders : person.getOrderList()){
			System.out.println(orders);
		}
		session.close();
	}
	
	//多對一,查詢訂單order(多)級聯查詢person(一)
	@Test
	public void testSelectOrdersFetchPerson() throws Exception{
		SqlSession session = sessionFactory.openSession();
		Orders orders = session.selectOne("com.kerwin.mybatis.pojo.Orders.selectOrdersFetchPerson", 1);
		System.out.println(orders);
		System.out.println(orders.getPerson());
		session.close();
	}
	
}

五、測試結果

1.一對多,查詢person(一)級聯查詢訂單order(多)

2.多對一,查詢訂單order(多)級聯查詢person(一)

注意:兩張表中的主鍵id欄位名要唯一,例如不能都寫id,不然的話,在一對多查詢的時候就會出現:級聯出來的訂單項只有一條記錄。我之前就是將兩張表的主鍵id欄位名都寫為id,導致測試結果級聯出來的多一直只有一條資料,具體如下: