有了前面幾章的基礎,對一些簡單的應用是可以處理的,但在實際項目中,經常是關聯表的查詢,比如最常見到的多對一,一對多等。這些查詢是如何處理的呢,這一講就講這個問題。我們首先創建一個Article 這個表,并初始化數據.
Drop TABLE IF EXISTS `article`; Create TABLE `article` ( `id` int(11) NOT NULL auto_increment, `userid` int(11) NOT NULL, `title` varchar(100) NOT NULL, `content` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- 添加幾條測試數據 -- ---------------------------- Insert INTO `article` VALUES ('1', '1', 'test_title', 'test_content'); Insert INTO `article` VALUES ('2', '1', 'test_title_2', 'test_content_2'); Insert INTO `article` VALUES ('3', '1', 'test_title_3', 'test_content_3'); Insert INTO `article` VALUES ('4', '1', 'test_title_4', 'test_content_4');
你應該發現了,這幾個文章對應的userid都是1,所以需要用戶表user里面有id=1的數據。可以修改成滿足自己條件的數據.按照orm的規則,表已經創建了,那么肯定需要一個對象與之對應,所以我們增加一個 Article 的class
package com.yihaomen.mybatis.model; public class Article { private int id; private User user; private String title; private String content; public int getId() { return id; } public void setId(int id) { this.id = id; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } 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; } }
注意一下,文章的用戶是怎么定義的,是直接定義的一個User對象。而不是int類型。
多對一的實現
場景:在讀取某個用戶發表的所有文章。當然還是需要在User.xml 里面配置 select 語句, 但重點是這個 select 的resultMap 對應什么樣的數據呢。這是重點,這里要引入 association 看定義如下:
<!-- User 聯合文章進行查詢 方法之一的配置 (多對一的方式) --> <resultMap id="resultUserArticleList" type="Article"> <id property="id" column="aid" /> <result property="title" column="title" /> <result property="content" column="content" /> <association property="user" javaType="User"> <id property="id" column="id" /> <result property="userName" column="userName" /> <result property="userAddress" column="userAddress" /> </association> </resultMap> <select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList"> select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article where user.id=article.userid and user.id=#{id} </select>
這樣配置之后,就可以了,將select 語句與resultMap 對應的映射結合起來看,就明白了。用association 來得到關聯的用戶,這是多對一的情況,因為所有的文章都是同一個用戶的。
還有另外一種處理方式,可以復用我們前面已經定義好的 resultMap ,前面我們定義過一個 resultListUser ,看這第二種方法如何實現:
<resultMap type="User" id="resultListUser"> <id column="id" property="id" /> <result column="userName" property="userName" /> <result column="userAge" property="userAge" /> <result column="userAddress" property="userAddress" /> </resultMap> <!-- User 聯合文章進行查詢 方法之二的配置 (多對一的方式) --> <resultMap id="resultUserArticleList-2" type="Article"> <id property="id" column="aid" /> <result property="title" column="title" /> <result property="content" column="content" /> <association property="user" javaType="User" resultMap="resultListUser" /> </resultMap> <select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList"> select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article where user.id=article.userid and user.id=#{id} </select>
將 association 中對應的映射獨立抽取出來,可以達到復用的目的。
好了,現在在Test 類中寫測試代碼:
public void getUserArticles(int userid){ SqlSession session = sqlSessionFactory.openSession(); try { IUserOperation userOperation=session.getMapper(IUserOperation.class); List<Article> articles = userOperation.getUserArticles(userid); for(Article article:articles){ System.out.println(article.getTitle()+":"+article.getContent()+ ":作者是:"+article.getUser().getUserName()+":地址:"+ article.getUser().getUserAddress()); } } finally { session.close(); } }
漏掉了一點,我們一定要在 IUserOperation 接口中,加入 select 對應的id 名稱相同的方法:
public List<Article> getUserArticles(int id);
另外需要 Configuration.xml中加入
<typeAliases>
<typeAlias alias="User" type="com.shanheyongmu.mybatis.model.User"/>
<typeAlias alias="Article" type="com.shanheyongmu.mybatis.model.Article"/>
</typeAliases>
然后運行就可以測試。
關聯查詢(多表查詢)的時候。。設置的aid是作用嗎?
如果你不設置那個別名,那么結果集中將會有兩個id列。會造成映射混亂吧。我做這個例子的時候沒有設置別名,結果明明是4條記錄,查詢出來就只有1條了。
由于原文轉載還是存在錯誤。特此粘貼 run as main 通過的代碼
user.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.shanheyongmu.mybatis.models.UserMapper"> --> <mapper namespace="com.shanheyongmu.mybatis.inter.IUserOperation"> <select id="selectUserByID" parameterType="int" resultType="User"> select * from user where id=#{id} </select> <!-- 多對一 方二 start--><!-- 為了返回list 類型而定義的returnMap --> <resultMap type="User" id="resultListUser"> <id column="id" property="id"/> <result column="userName" property="userName"/> <result column="userAge" property="userAge"/> <result column="userAddress" property="userAddress"/> </resultMap> <!-- 返回list的select語句,注意resultMap的值是指向 前面定義好的--> <select id="selectUsers" parameterType="string" resultMap="resultListUser"> select * from user where username like #{username} </select> <!-- User聯合文章進行查詢 方法二的配置 多對一 --> <resultMap type="Article" id="resultUserArticleList2"> <id property="id" column="aid"/> <result property="title" column="title"/> <result property="content" column="content"/> <association property="user" javaType="User" resultMap="resultListUser"/> </resultMap> <!-- 多對一 方二 end--> <!-- User 聯合文章進行查詢 方法之一的配置 (多對一的方式) start --> <resultMap type="Article" id="resultUserArticleList"> <id column="aid" property="id"/> <result column="title" property="title"/> <result column="content" property="content"/> <association property="user" javaType="User"> <id column="id" property="id"/> <result column="userName" property="userName"/> <result column="userAddress" property="userAddress"/> </association> </resultMap> <!-- 方法一 end --> <!-- 查詢語句 方法一 二公用 --> <select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList"> select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article where user.id=article.userid and user.id=#{id} </select> <!-- 執行增加操作的SQL語句。id和parameterType 分別與IUserOperation接口中的addUser方法的名字和 參數類型一致。以#{name}的形式引用Student參數 的name屬性,MyBatis將使用反射讀取Student參數 的此屬性。#{name}中name大小寫敏感。引用其他 的gender等屬性與此一致。seGeneratedKeys設置 為"true"表明要MyBatis獲取由數據庫自動生成的主 鍵;keyProperty="id"指定把獲取到的主鍵值注入 到Student的id屬性 --> <insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> insert into user(userName,userAge,userAddress) values(#{username},#{userAge},#{userAddress}) </insert> <update id="updateUser" parameterType="User"> update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id} </update> <delete id="deleteUser" parameterType="int"> delete from user where id=#{id} </delete> </mapper>
Test.java
package com.yihaomen.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.yihaomen.mybatis.inter.IUserOperation; import com.yihaomen.mybatis.model.Article; import com.yihaomen.mybatis.model.User; public class Test { private static SqlSessionFactory sqlSessionFactory; private static Reader reader; static{ try{ reader = Resources.getResourceAsReader("Configuration.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); }catch(Exception e){ e.printStackTrace(); } } public static SqlSessionFactory getSession(){ return sqlSessionFactory; } public void getUserArticles(int userid){ SqlSession session = sqlSessionFactory.openSession(); try { IUserOperation userOperation=session.getMapper(IUserOperation.class); List<Article> articles = userOperation.getUserArticles(userid); for(Article article:articles){ System.out.println(article.getTitle()+":"+article.getContent()+ ":作者是:"+article.getUser().getUserName()+":地址:"+ article.getUser().getUserAddress()); } } finally { session.close(); } } public static void main(String[] args) { Test testUser=new Test(); testUser.getUserArticles(1); } }
config.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 alias="User" type="com.shanheyongmu.mybatis.model.User"/> <typeAlias alias="Article" type="com.shanheyongmu.mybatis.model.Article"/> </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/shanheyongmu/mybatis/model/User.xml"/> </mappers> </configuration>
文章列表