1. 程式人生 > >mybatis3.2.7學習筆記2_一對一、一對多、多對多、延時載入、快取

mybatis3.2.7學習筆記2_一對一、一對多、多對多、延時載入、快取

參考源:

  我對比了一下mybatis和hibernate的一對一 一對多 多對多的概念

  mybatis的要比hibernate簡單的多  更加突出了mybatis注重sql的概念

* resuType--將sql的列名和pojo的屬性進行一一的對映
 *  resultMap--可以避免使用resultType方式的重複記錄
 * association--將sql列對映到pojo物件中 collection--將關聯資訊對映到list列表中
 * association、collection都具備延時載入功能 mybatis具有二級快取
 * SqlSession--一級快取,當SqlSession未關閉時,使用key-value的形式儲存物件,當進行增加、刪除、修改時,都會清空一級快取中的資料
 * Mapper名稱空間--二級快取,二級快取的介面為Cache
 * ,mybatis提供的二級快取預設實現為PerpetualCache,以Mapper的名稱空間為單位進行快取
 * ,可跨多個SqlSession,當SqlSession關閉時
 * ,將一級快取的物件寫入到二級快取,要進行二級快取的物件必須序列化,因為二級快取不一定在記憶體中,可能在硬碟
 *  當進行增加、刪除、修改時,都會清空二級快取中的資料
*  useCache="true"  
 *  flushCache="true"


Mapper的配置檔案

<?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的值與mapper的介面包 -->
<mapper namespace="com.undergrowth.mybatis.mapper.OrderUserMapper">
	<!-- 使用resultType進行一對一的對映 -->
	<select id="findOrdersUserByResultType" resultType="com.undergrowth.mybatis.po.OrdersUser">
		select
		orders.*,user.username,user.birthday from orders,user where
		orders.user_id=user.id
	</select>
	<!-- 使用resultMap進行一對一的對映 -->
	<resultMap type="com.undergrowth.mybatis.po.OrdersUserPojo"
		id="findOrdersUserByResultMapId">
		<result column="id" property="id" />
		<result column="user_id" property="user_id" />
		<result column="number" property="number" />
		<result column="createtime" property="createtime" />
		<result column="note" property="note" />

		<association property="user" javaType="com.undergrowth.mybatis.po.User">
			<result column="username" property="username" />
			<result column="birthday" property="birthday" />
		</association>
	</resultMap>

	<!-- 使用resultMap進行一對一的對映 -->
	<select id="findOrdersUserByResultMap" resultMap="findOrdersUserByResultMapId">
		select
		orders.*,user.username,user.birthday from orders,user where
		orders.user_id=user.id
	</select>

	<!-- 使用collection進行集合元素的對映 對映成一對多 避免記錄的重複 -->
	<!-- 使用extends使orders與user不用進行對映 -->
	<resultMap type="com.undergrowth.mybatis.po.OrdersUserDetailPojo"
		id="findOrderUserDetailResultMapId" extends="findOrdersUserByResultMapId">
		<collection property="orderDetails"
			ofType="com.undergrowth.mybatis.po.OrderDetail">
			<result column="orders_id" property="orders_id" />
			<result column="items_id" property="items_id" />
			<result column="items_num" property="items_num" />
		</collection>
	</resultMap>

	<select id="findOrderUserDetailResultMap" resultMap="findOrderUserDetailResultMapId">
		SELECT
		orders.*,
		user.username,
		user.birthday,
		orderdetail.orders_id,
		orderdetail.items_id,
		orderdetail.items_num
		FROM
		orders,
		user,
		orderdetail
		WHERE
		orders.user_id = user.id
		AND orders.id = orderdetail.orders_id
	</select>

	<resultMap type="com.undergrowth.mybatis.po.UserToOrdersVo"
		id="findUserAndItemsResultMapId">
		<result column="user_id" property="id" />
		<result column="username" property="username" />
		<result column="birthday" property="birthday" />
		<result column="sex" property="sex" />
		<result column="user_address" property="address" />

		<!-- 關聯訂單列表 -->
		<collection property="orderList"
			ofType="com.undergrowth.mybatis.po.OrdersToOrderDetailVo">
			<result column="id" property="id" />
			<result column="user_id" property="user_id" />
			<result column="number" property="number" />
			<result column="createtime" property="createtime" />
			<result column="note" property="note" />
			<!-- 訂單關聯明細 -->
			<collection property="orderDetailList"
				ofType="com.undergrowth.mybatis.po.OrderDetailToItems">
				<result column="orders_id" property="orders_id" />
				<result column="items_id" property="items_id" />
				<result column="items_num" property="items_num" />
				<!-- 關聯商品 -->
				<association property="items" javaType="com.undergrowth.mybatis.po.Items">
					<result column="name" property="name" />
					<result column="price" property="price" />
					<result column="detail" property="detail" />
				</association>
			</collection>
		</collection>
	</resultMap>

	<!-- 使用 collection和association進行使用者和商品明細的多對多的對映 -->
	<select id="findUserAndItemsResultMap" resultMap="findUserAndItemsResultMapId">

		SELECT
		orders.*,
		user.username,
		user.birthday,
		user.sex,
		user.address
		user_address,
		orderdetail.orders_id,
		orderdetail.items_id,
		orderdetail.items_num,
		items.name,
		items.price,
		items.detail
		FROM
		orders,
		user,
		orderdetail,
		items
		WHERE
		orders.user_id =
		user.id
		AND orders.id =
		orderdetail.orders_id
		AND orderdetail.items_id =
		items.id
	</select>

	<select id="findUserById" resultType="com.undergrowth.mybatis.po.User">
		select * from user where id=#{value}
	</select>

	<!-- 延時載入 association -->
	<resultMap type="com.undergrowth.mybatis.po.OrdersUserPojo"
		id="findOrderUserLazyLoadingId">
		<result column="id" property="id" />
		<result column="user_id" property="user_id" />
		<result column="number" property="number" />
		<result column="createtime" property="createtime" />
		<result column="note" property="note" />
		<association property="user" javaType="com.undergrowth.mybatis.po.User"
			select="findUserById" column="user_id"></association>
	</resultMap>
	<select id="findOrderUserLazyLoading" resultMap="findOrderUserLazyLoadingId">
		select * from
		orders
	</select>
   <!-- 開啟Mapper的二級快取 預設實現為PerpetualCache -->
   <cache></cache>
</mapper>

介面檔案

package com.undergrowth.mybatis.mapper;

import java.util.List;

import com.undergrowth.mybatis.po.OrdersUser;
import com.undergrowth.mybatis.po.OrdersUserDetailPojo;
import com.undergrowth.mybatis.po.OrdersUserPojo;
import com.undergrowth.mybatis.po.UserToOrdersVo;

/**
 * 通過
 * @author u1
 *
 */
public interface OrderUserMapper {

	public List<OrdersUser> findOrdersUserByResultType();
	public List<OrdersUserPojo> findOrdersUserByResultMap();
	public List<OrdersUserDetailPojo> findOrderUserDetailResultMap();
	public List<UserToOrdersVo> findUserAndItemsResultMap();
	public List<OrdersUserPojo> findOrderUserLazyLoading();
}

測試程式碼

package com.undergrowth.mybatis.dao;

import java.io.IOException;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;

import com.undergrowth.mybatis.mapper.OrderUserMapper;
import com.undergrowth.mybatis.po.OrdersUser;
import com.undergrowth.mybatis.po.OrdersUserDetailPojo;
import com.undergrowth.mybatis.po.OrdersUserPojo;
import com.undergrowth.mybatis.po.UserToOrdersVo;
import com.undergrowth.mybatis.util.SqlSessionUtil;

/**
 * 測試程式碼 
 * resuType--將sql的列名和pojo的屬性進行一一的對映 
 * resultMap--可以避免使用resultType方式的重複記錄
 * association--將sql列對映到pojo物件中 collection--將關聯資訊對映到list列表中
 * association、collection都具備延時載入功能
 *  mybatis具有二級快取
 * SqlSession--一級快取,當SqlSession未關閉時,使用key-value的形式儲存物件
 * Mapper名稱空間--二級快取,二級快取的介面為Cache
 * ,mybatis提供的二級快取預設實現為PerpetualCache,以Mapper的名稱空間為單位進行快取,可跨多個SqlSession
 * 要進行二級快取的物件必須序列化
 * @author u1
 * 
 */
public class OrderUserMapperDao {

	SqlSessionFactory sqlSessionFactory = null;

	@Before
	public void before() throws IOException {
		sqlSessionFactory = SqlSessionUtil
				.getSqlSessionFactory("mybatis-conf.xml");
	}

	/**
	 * 使用resultType進行一對一的對映
	 */
	@Test
	public void testOneToOne() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			OrderUserMapper orderUserMapper = sqlSession
					.getMapper(OrderUserMapper.class);
			List<OrdersUser> ordersUsers = orderUserMapper
					.findOrdersUserByResultType();
			for (OrdersUser ordersUser : ordersUsers) {
				System.out.println(ordersUser);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}

	/**
	 * 使用resultMap進行一對一的對映
	 */
	@Test
	public void testOneToOneResultMap() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			OrderUserMapper orderUserMapper = sqlSession
					.getMapper(OrderUserMapper.class);
			List<OrdersUserPojo> ordersUsers = orderUserMapper
					.findOrdersUserByResultMap();
			for (OrdersUserPojo ordersUser : ordersUsers) {
				System.out.println(ordersUser);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}

	/**
	 * 使用resultMap和collection進行一對多的對映
	 */
	@Test
	public void findOrderUserDetailResultMap() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			OrderUserMapper orderUserMapper = sqlSession
					.getMapper(OrderUserMapper.class);
			List<OrdersUserDetailPojo> ordersUsers = orderUserMapper
					.findOrderUserDetailResultMap();
			for (OrdersUserDetailPojo ordersUser : ordersUsers) {
				System.out.println(ordersUser);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}

	/**
	 * 使用resultMap和collection association進行多對多的對映
	 */
	@Test
	public void findUserAndItemsResultMap() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			OrderUserMapper orderUserMapper = sqlSession
					.getMapper(OrderUserMapper.class);
			List<UserToOrdersVo> ordersUsers = orderUserMapper
					.findUserAndItemsResultMap();
			for (UserToOrdersVo ordersUser : ordersUsers) {
				System.out.println(ordersUser);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}

	/**
	 * 延時載入
	 */
	@Test
	public void findOrderUserLazyLoading() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			OrderUserMapper orderUserMapper = sqlSession
					.getMapper(OrderUserMapper.class);
			List<OrdersUserPojo> ordersUsers = orderUserMapper
					.findOrderUserLazyLoading();
			for (OrdersUserPojo ordersUser : ordersUsers) {
				System.out.println(ordersUser);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}
	
	/**
	 * 測試二級快取
	 * @throws IOException 
	 */
	@Test
	public void testCache() throws IOException{
		SqlSession sqlSession=SqlSessionUtil.getSqlSessionFactory("mybatis-conf.xml").openSession();
		OrderUserMapper mapper=sqlSession.getMapper(OrderUserMapper.class);
		System.out.println("第一次查詢訂單使用者");
		List<OrdersUser> ordersUsers=mapper.findOrdersUserByResultType();
		for (OrdersUser ordersUser : ordersUsers) {
			System.out.println(ordersUser);
		}
		//關閉一級快取
		sqlSession.close();
		//如果未使用二級快取 此時再次查詢 會輸出查詢語句
		sqlSession=SqlSessionUtil.getSqlSessionFactory("mybatis-conf.xml").openSession();
		mapper=sqlSession.getMapper(OrderUserMapper.class);
		System.out.println("第二次查詢");
		ordersUsers=mapper.findOrdersUserByResultType();
		for (OrdersUser ordersUser : ordersUsers) {
			System.out.println(ordersUser);
		}
		sqlSession.close();
	}
}

開快取和延時載入配置

<!-- mybatis執行時全域性引數配置 -->
	<settings>
		<setting name="cacheEnabled" value="true"></setting>
		<setting name="lazyLoadingEnabled" value="true" />
		<!-- 按需載入每個懶載入屬性 -->
		<setting name="aggressiveLazyLoading" value="false" />
	</settings>

剩下的除了和前一篇部落格一樣外  還有一些POJO

package com.undergrowth.mybatis.po;

import java.io.Serializable;
import java.util.Date;

public class OrdersUser extends Orders implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String username;
	private Date birthday;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	public String toString() {
		return super.toString() + "[username=" + username + ", birthday="
				+ birthday + "]";
	}
}

package com.undergrowth.mybatis.po;

public class OrdersUserPojo extends Orders {
	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	@Override
	public String toString() {
		return super.toString() + "OrdersUserPojo [user=" + user + "]";
	}

}

package com.undergrowth.mybatis.po;

import java.util.List;

public class UserToOrdersVo extends User {
	private List<OrdersToOrderDetailVo> orderList;

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

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

	@Override
	public String toString() {
		return super.toString()+"UserToOrdersVo [orderList=" + orderList + "]";
	}
	
}

package com.undergrowth.mybatis.po;

import java.util.List;

public class OrdersToOrderDetailVo extends Orders {
	private List<OrderDetailToItems> orderDetailList;

	public List<OrderDetailToItems> getOrderDetailList() {
		return orderDetailList;
	}

	public void setOrderDetailList(List<OrderDetailToItems> orderDetailList) {
		this.orderDetailList = orderDetailList;
	}

	@Override
	public String toString() {
		return super.toString() + "OrdersToOrderDetailVo [orderDetailList="
				+ orderDetailList + "]";
	}

}


package com.undergrowth.mybatis.po;

public class OrderDetailToItems extends OrderDetail {
	private Items items;

	public Items getItems() {
		return items;
	}

	public void setItems(Items items) {
		this.items = items;
	}

	@Override
	public String toString() {
		return super.toString() + "OrderDetailToItems [items=" + items + "]";
	}

}