1. 程式人生 > >mybatis學習筆記(二) 多pojo,複雜對映

mybatis學習筆記(二) 多pojo,複雜對映

現在在資料庫增加兩張表blog與comment ,即部落格與評論表。

CREATE TABLE `blog` (
  `id` int(11) NOT NULL default '0',
  `title` varchar(255) default NULL,
  `content` text,
  `pub_time` datetime default NULL,
  `user_id` int(11) default NULL,
  PRIMARY KEY  (`id`),
  KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `comment` (
  `id` int(11) NOT NULL default '0',
  `content` text,
  `pub_time` datetime default NULL,
  `blog_id` int(11) default NULL,
  `user_id` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

增加pojo物件

package com.zf.mybatis.pojo;

import java.util.Date;
import java.util.List;

public class Blog {

	private int id ;
	private String title ;
	private String content ;
	private Date pubTime ;
	private User author ;
	private List<Comment> comments ;

	public int getId() {
		return id;
	}

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

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getPubTime() {
		return pubTime;
	}

	public void setPubTime(Date pubTime) {
		this.pubTime = pubTime;
	}

	public User getAuthor() {
		return author;
	}

	public void setAuthor(User author) {
		this.author = author;
	}

	public List<Comment> getComments() {
		return comments;
	}

	public void setComments(List<Comment> comments) {
		this.comments = comments;
	}
	
}


package com.zf.mybatis.pojo;

import java.util.Date;

public class Comment {
	
	private int id ;
	private String content ;
	private Date pubTime;
	private Blog blog ;
	private User author ;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public Date getPubTime() {
		return pubTime;
	}
	public void setPubTime(Date pubTime) {
		this.pubTime = pubTime;
	}
	public Blog getBlog() {
		return blog;
	}
	public void setBlog(Blog blog) {
		this.blog = blog;
	}
	public User getAuthor() {
		return author;
	}
	public void setAuthor(User author) {
		this.author = author;
	}
}


編寫對映檔案

Blog.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.zf.mybatis.pojo.BlogMapper">

	<sql id="queryFields">
	  id , title , content , pub_time as pubTime , user_id as User
	</sql>
	
	<resultMap type="Blog" id="detailBlogResultMap">
		<id property="id" column="blog_id" />
		<result property="title" column="blog_title" />
		<result property="content" column="blog_content" />
		<result property="pubTime" column="blog_pub_time" />
		<association property="author" column="blog_user_id" javaType="User" >
			<id property="id" column="user_id" />
			<result property="title" column="title" />
			<result property="password" column="user_password" />
			<result property="userName" column="user_user_name" />
			<result property="userAge" column="user_user_age" />
			<result property="userAddress" column="user_user_address" />
		</association>
		<collection property="comments" column="comment_blog_id" ofType="Comment"  >
			<id property="id" column="comment_id" />
			<result property="content" column="comment_content" />
		</collection>
	</resultMap>
	
    <select id="selectByID" parameterType="int" resultMap="detailBlogResultMap">
        select
        B.id as blog_id ,
        B.title as blog_title ,
        B.content as blog_content ,
        B.pub_time as blog_pub_time ,
        B.user_id as blog_user_id ,
        U.id as user_id,
        U.password as user_password,
        U.user_name as user_user_name ,
        U.user_age as user_user_age ,
        U.user_address as user_user_address ,
        C.id as comment_id ,
        C.blog_id as comment_blog_id ,
        C.content as comment_content
        from `blog` B 
        left outer join `user` U on B.user_id = U.id
        left outer join `comment` C on B.id = C.blog_id
        
        where B.id = #{id}
    </select>
    
</mapper>
按照上面的配置,會將blog的所有欄位全部查詢出來 ,author的所有欄位查詢出來,comment的id與content欄位查詢出來。  如果要查詢出其他的欄位,可以在resutMap中進行配置,並在sql中加入要查詢的欄位。

然後在mybatis-config.xml檔案中加入pojo的別名,並將Blog.xml對映檔案註冊到mybatis-config.xml檔案中。

之後就可以進行測試了。 看能否查詢出想要的資料。 

注意:可以通過配置log4j來列印sql的輸出。 首先在pom.xml中加入log4j的依賴,然後加入log4j的配置檔案,如下:

log4j.rootCategory=DEBUG, stdout 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG 


現在編寫測試類來測試:

package com.zf.mybatis;

import java.io.IOException;
import java.io.Reader;

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

import com.zf.mybatis.pojo.Blog;

public class TestMyBatis02 {
	
	private  SqlSessionFactory sqlSessionFactory;
	private  Reader reader; 

	@Before
	public void init(){
		try {
			reader  = Resources.getResourceAsReader("mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testQueryBlog(){
		SqlSession session = sqlSessionFactory.openSession();
		try {
			Blog blog = (Blog) session.selectOne("com.zf.mybatis.pojo.BlogMapper.selectByID" ,1);
			if(blog != null)
			System.out.printf(
					"title:%s , content:%s , pubTime:%tT , authorName:%s ,authorAge:%d , authorPass:%s , authorAddress:%s" ,
					blog.getTitle(), 
					blog.getContent() ,
					blog.getPubTime() ,
					blog.getAuthor().getUserName(),
					blog.getAuthor().getUserAge() ,
					blog.getAuthor().getPassword() ,
					blog.getAuthor().getUserAddress() 
					);
			else
				System.out.println("沒有查詢到資料");
		} finally {
			session.close();
		}
	}
	
	
	

}

執行testQueryBlog方法列印結果如下:
ooo Using Connection [[email protected]]
==>  Preparing: select B.id as blog_id , B.title as blog_title , B.content as blog_content , B.pub_time as blog_pub_time , B.user_id as blog_user_id , U.id as user_id, U.password as user_password, U.user_name as user_user_name , U.user_age as user_user_age , U.user_address as user_user_address from `blog` B left outer join `user` U on B.user_id = U.id where B.id = ? 
==> Parameters: 1(Integer)
<==      Total: 1
title:testtitle , content:test content , pubTime:23:14:31 , authorName:summer ,authorAge:100 , authorPass:123131 , authorAddress:shanghai,pudong
可以看到 , 正確的查詢除了資料。 (在執行方法之前首先在資料庫blog表中插入一條測試資料),上面的方法同時會將該blog的所有comment也查詢出來,但是要實現在comment表中插入一些測試資料。

上面的resultMap寫起來相當的龐大,且不利於複用。 所以還有另外一種方式來配置resultMap ,如下:

 
    <resultMap type="Blog" id="detailBlogResultMap02">
		<id property="id" column="blog_id" />
		<result property="title" column="blog_title" />
		<result property="content" column="blog_content" />
		<result property="pubTime" column="blog_pub_time" />
		<association property="author" column="blog_user_id" javaType="User" select="com.zf.mybatis.pojo.UserMapper.selectByID" />
		<collection property="comments" column="blog_id"  javaType="ArrayList" ofType="Comment" select="com.zf.mybatis.pojo.CommentMapper.selectByBlogID" />
	</resultMap>
	
    <select id="selectByID02" parameterType="int" resultMap="detailBlogResultMap02">
        select
        B.id as blog_id ,
        B.title as blog_title ,
        B.content as blog_content ,
        B.pub_time as blog_pub_time ,
        B.user_id as blog_user_id
        from `blog` B
        where B.id = #{id}
    </select>


注意 association節點中的select屬性,他的值指向了User.xml中的selectByID方法,所以他會使用該方法進行查詢, 這樣做的好處是提高了程式碼的複用率 ,也減小了resultMap的複雜性。 但是這樣會存在一個N+1的問題。

注意collection中的select指向的是Comment.xml中的selectByBlogID方法,它會將sql中查詢出來列名為blog_id的值傳遞給該方法作為引數。

Comment.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.zf.mybatis.pojo.CommentMapper">
	
	<sql id="queryFields">
	  id , content , pub_time , blog_id , user_id
	</sql>
	
    <select id="selectByID" parameterType="int" resultType="Comment">
        select 
        <include refid="queryFields"/> 
        from `comment` where id = #{id}
    </select>
    
    <select id="selectByBlogID" parameterType="int" resultType="Comment">
    select
    <include refid="queryFields"/>
    from `comment` where blog_id = #{id}
    </select>
    
    
</mapper>


另外一種提高程式碼複用率的方法是將resultMap提取出來, 同時也減小了resultMap的複雜度。 程式碼如下:

<resultMap type="Blog" id="detailBlogResultMap03">
		<id property="id" column="blog_id" />
		<result property="title" column="blog_title" />
		<result property="content" column="blog_content" />
		<result property="pubTime" column="blog_pub_time" />
		<association property="author" column="blog_user_id" javaType="User" resultMap="authorResultMap03" />
		<collection property="comments" column="comment_blog_id" ofType="Comment"  resultMap="commentResultMap03" />
	</resultMap>
	
	<resultMap type="User" id="authorResultMap03">
			<id property="id" column="user_id" />
			<result property="title" column="title" />
			<result property="password" column="user_password" />
			<result property="userName" column="user_user_name" />
			<result property="userAge" column="user_user_age" />
			<result property="userAddress" column="user_user_address" />
	</resultMap>
	
	<resultMap type="Comment" id="commentResultMap03">
			<id property="id" column="comment_id" />
			<result property="content" column="comment_content" />
	</resultMap>
	
	
    <select id="selectByID03" parameterType="int" resultMap="detailBlogResultMap">
        select
        B.id as blog_id ,
        B.title as blog_title ,
        B.content as blog_content ,
        B.pub_time as blog_pub_time ,
        B.user_id as blog_user_id ,
        U.id as user_id,
        U.password as user_password,
        U.user_name as user_user_name ,
        U.user_age as user_user_age ,
        U.user_address as user_user_address ,
        C.id as comment_id ,
        C.blog_id as comment_blog_id ,
        C.content as comment_content
        from `blog` B 
        left outer join `user` U on B.user_id = U.id
        left outer join `comment` C on B.id = C.blog_id
        where B.id = #{id}
    </select>
    
    

相關推薦

mybatis學習筆記 pojo複雜對映

現在在資料庫增加兩張表blog與comment ,即部落格與評論表。 CREATE TABLE `blog` ( `id` int(11) NOT NULL default '0', `title` varchar(255) default NULL, `co

MySQL高效程式設計學習筆記--個表的連線

關係型資料庫為了減少資料佔用有限的儲存空間,都會進行資料分割到幾個表的規範化處理,將這幾個分割管理的資料重新結合到一起就是表連線處理。 1.內連線 內連線就是表間的主鍵和外來鍵相連,只取得鍵值一致的資料的連線方式。具體語法: Select 列

mybatis學習筆記之XML方式的基本用法

在前一篇筆記中,我們建立了配置 mybatis-config.xml 檔案,原來 mappers標籤下的內容為: <mappers> <mapper resource="tk/mybatis/simple/mapper/CountryMa

MyBatis學習筆記- 介面式程式設計

MyBatis 的 HelloWorld 的進階 注意:本次操作是在上一個筆記的基礎之上 工程目錄如下: 1. 建立一個 EmployeeMapper 的介面 public interface EmployeeMapper { public Employee ge

Mybatis學習筆記--關聯查詢一對一一對

關聯查詢 改造User實體類 public class User implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private S

Mybatis學習筆記-Mybatis配置檔案與對映檔案詳解

一、Mybatis配置檔案詳解 以下是mybatis.xml檔案,提倡放在src目錄下,檔名任意 <?xml version="1.0" encoding="UTF-8"?> <

mybatis框架總體說明---Mybatis學習筆記

mybatis是什麼? mybatis可以讓程式設計師的主要精力放在sql上,通過mybatis提供的對映方式,自由靈活生成(半自動化,大部分需要程式設計師編寫sql)滿足需要的sql語句。 my

Mybatis學習筆記--入門程式

1.下載Mybatis包 mybaits的程式碼由github.com管理 下載地址:https://github.com/mybatis/mybatis-3/releases 選擇對應的版本下載 下載後解壓mybatis後 2.環境搭建 2.1 建立工程

MyBatis學習筆記優化MyBatis配置解耦合提高複用性

我們接著上篇的環境,優化MyBatis配置 1.連線資料庫的配置放在properties檔案中 在src下建立db.properties檔案,寫連線資料庫需要使用到的資料庫驅動,連線URL地址,使用者名稱,密碼;內容如下 driver=com.mysq

機器學習筆記——變數最小乘法

在上一節中,我們介紹了最簡單的學習演算法——最小二乘法去預測奧運會男子100米時間。但是可以發現,它的自變數只有一個:年份。通常,我們所面對的資料集往往不是單個特徵,而是有成千上萬個特徵組成。那麼我們就引入特徵的向量來表示,這裡涉及到矩陣的乘法,向量,矩陣求導等

MyBatis學習筆記——標籤使用

resultMap手動對映 當資料庫表中的欄位名稱與pojo的實體類的名稱不同的時候,使用resultMap: 示例程式碼: <mapper namespace="com.zrxjuly.mybatis.mapper.OrderMapper"&g

MyBatis學習筆記——優化MyBatis配置檔案

在使用MyBatis的時候,MyBatis的配置檔案可以說是相當重要的了。那麼,我們先來看看MyBatis配置檔案中的內容和順序: <properties>(屬性) <setting>(全域性配置引數) <typeAliases>(類

java學習筆記執行緒

1、執行緒的生命週期:新建(New)、就緒(Runnable)、執行(Running)、阻塞(Blocked)、死亡(Dead)。 2、啟動執行緒呼叫的是start()方法而不是run()方法。如果直接呼叫run()方法,則run()方法會立即執行,而且在run()方法返回之前其他執行緒無法併發執行,也就是說

機器學習筆記矩估計極大似然估計

1.引數估計:矩估計 樣本統計量 設X1,X2…Xn…為一組樣本,則 - 樣本均值 : X¯¯¯=1n∑i=1nXi - 樣本方差:S2=1n−1∑i=1n(Xi−X¯¯¯

Mybatis 學習筆記——關聯對映關係一對一一對

一、背景知識    在介紹對映關係之前需要我們對 resultMap 要足夠了解。在 resultMap 中有如下節點可配置: id :唯一標識列,column 為資料庫ID列,property為 POJO 的id屬性,注意在查詢出的結果集中每一列都必須不一樣

Java 執行緒 學習筆記停止執行緒的幾種方法

1.異常法: package test; import exthread.MyThread; import exthread.MyThread; public class Run { pu

MyBatis學習筆記一對的關聯查詢和傳遞個引數

首發於我的部落格 和尚的部落格 本文講解一對多的關聯查詢,傳遞多個引數。 1.傳遞多個引數 當你的形參傳遞>1個的時候,parameterType不寫,讓其自動處理 #{值},預設為arg0,arg1…..或param1,param2,,,

Mybatis 學習筆記——關聯對映關係

三、多對多對映關係 1. 需求:查詢使用者及商品資訊 2. POJO類 /mybatis01/src/com/po/User.java package com.po; import java.util.Date; import java.util.List;

執行緒學習筆記之執行緒安全問題

執行緒安全問題的現象 首先讓我們考慮一個問題: class Demo implements Runnable{ private int num = 100; //實現Runnable介面,覆蓋run方法 public void r

myBatis學習筆記5——一對關聯表查詢

需求 上一篇筆記是一對一,一個學生對應一個老師,本次我們修改一下需求,一個老師有多個學生 參考:myBatis學習筆記(4)——一對一關聯表查詢 老師類: package com.bank.en