MyBatis教程– CRUD操作和映射關系–第2部分

為了說明這一點,我們正在考慮以下示例域模型:

會有用戶,每個用戶可能都有一個博客,每個博客可以包含零個或多個帖子。

這三個表的數據庫結構如下:

CREATE TABLE user (user_id int(10) unsigned NOT NULL auto_increment,email_id varchar(45) NOT NULL,password varchar(45) NOT NULL,first_name varchar(45) NOT NULL,last_name varchar(45) default NULL,blog_id int(10) unsigned default NULL,PRIMARY KEY  (user_id),UNIQUE KEY Index_2_email_uniq (email_id),KEY FK_user_blog (blog_id),CONSTRAINT FK_user_blog FOREIGN KEY (blog_id) REFERENCES blog (blog_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE blog (blog_id int(10) unsigned NOT NULL auto_increment,blog_name varchar(45) NOT NULL,created_on datetime NOT NULL,PRIMARY KEY  (blog_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE post (post_id int(10) unsigned NOT NULL auto_increment,title varchar(45) NOT NULL,content varchar(1024) NOT NULL,created_on varchar(45) NOT NULL,blog_id int(10) unsigned NOT NULL,PRIMARY KEY  (post_id),KEY FK_post_blog (blog_id),CONSTRAINT FK_post_blog FOREIGN KEY (blog_id) REFERENCES blog (blog_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

在這里,我將解釋如何獲取和映射*-一對一和一對多結果映射。

package com.sivalabs.mybatisdemo.domain;public class User 
{private Integer userId;private String emailId;private String password;private String firstName;private String lastName;private Blog blog;//setters and getters
}

package com.sivalabs.mybatisdemo.domain;import java.util.ArrayList;
import java.util.Date;
import java.util.List;public class Blog {private Integer blogId;private String blogName;private Date createdOn;private List<Post> posts = new ArrayList<Post>();//setters and getters
}

package com.sivalabs.mybatisdemo.domain;import java.util.Date;public class Post 
{private Integer postId;private String title;private String content;private Date createdOn;//setters and getters
}

在mybatis-config.xml中,為bean配置類型別名。

<typeAliases><typeAlias type='com.sivalabs.mybatisdemo.domain.User' alias='User'/><typeAlias type='com.sivalabs.mybatisdemo.domain.Blog' alias='Blog'/><typeAlias type='com.sivalabs.mybatisdemo.domain.Post' alias='Post'/>  
</typeAliases>


*-具有一個結果映射:

在UserMapper.xml中,如下配置sql查詢和結果映射:

<mapper namespace='com.sivalabs.mybatisdemo.mappers.UserMapper'><resultMap type='User' id='UserResult'><id property='userId' column='user_id'/><result property='emailId' column='email_id'/><result property='password' column='password'/><result property='firstName' column='first_name'/><result property='lastName' column='last_name'/><association property='blog' resultMap='BlogResult'/></resultMap><resultMap type='Blog' id='BlogResult'><id property='blogId' column='blog_id'/><result property='blogName' column='BLOG_NAME'/><result property='createdOn' column='CREATED_ON'/>    </resultMap><select id='getUserById' parameterType='int' resultMap='UserResult'>SELECT U.USER_ID, U.EMAIL_ID, U.PASSWORD, U.FIRST_NAME, U.LAST_NAME, B.BLOG_ID, B.BLOG_NAME, B.CREATED_ONFROM USER U LEFT OUTER JOIN BLOG B ON U.BLOG_ID=B.BLOG_IDWHERE U.USER_ID = #{userId}</select><select id='getAllUsers' resultMap='UserResult'>SELECT U.USER_ID, U.EMAIL_ID, U.PASSWORD, U.FIRST_NAME, U.LAST_NAME, B.BLOG_ID, B.BLOG_NAME, B.CREATED_ONFROM USER U LEFT OUTER JOIN BLOG B ON U.BLOG_ID=B.BLOG_ID</select></mapper>

在JUnit Test中,編寫一種方法來測試關聯加載。

public void getUserById() 
{SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession();try{UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.getUserById(1);System.out.println(user.getBlog());}finally{sqlSession.close();}
}


一對多結果映射:

在BlogMapper.xml中,如下配置Blog to Posts關系:

<mapper namespace='com.sivalabs.mybatisdemo.mappers.BlogMapper'><resultMap type='Blog' id='BlogResult'><id property='blogId' column='blog_id'/><result property='blogName' column='BLOG_NAME'/><result property='createdOn' column='CREATED_ON'/><collection property='posts' ofType='Post' resultMap='PostResult' columnPrefix='post_'></collection></resultMap><resultMap type='Post' id='PostResult'><id property='postId' column='post_id'/><result property='title' column='title'/><result property='content' column='content'/><result property='createdOn' column='created_on'/></resultMap><select id='getBlogById' parameterType='int' resultMap='BlogResult'>SELECT b.blog_id, b.blog_name, b.created_on, p.post_id as post_post_id, p.title as post_title, p.content as post_content, p.created_on as post_created_onFROM blog b left outer join post p on b.blog_id=p.blog_idWHERE b.BLOG_ID=#{blogId}</select><select id='getAllBlogs' resultMap='BlogResult'>SELECT b.blog_id, b.blog_name, b.created_on as blog_created_on, p.post_id as post_post_id, p.title as post_title, p.content as post_content, p.created_on as post_created_onFROM blog b left outer join post p on b.blog_id=p.blog_id</select></mapper>

在JUnit Test中,編寫一種測試方法來測試博客到帖子的關系映射。

public void getBlogById() 
{SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession();try{BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);Blog blog = blogMapper.getBlogById(1);System.out.println(blog);List<Post> posts = blog.getPosts();for (Post post : posts) {System.out.println(post);}}finally{sqlSession.close();}
}


支持 整合

MyBatis-Spring是MyBatis的子項目,并提供Spring集成支持,從而大大簡化了MyBatis的用法。 對于那些熟悉Spring依賴注入方法的人來說,使用MyBatis-Spring非常簡單。

首先讓我們看看不使用Spring的MyBatis的使用過程。

1.通過傳遞包含數據源屬性,映射器XML列表和TypeAliases等的mybatis-config.xml,使用SqlSessionFactoryBuilder創建SqlSessionFactory。

2.從SqlSessionFactory創建SqlSession對象

3.從SqlSession中獲取Mapper實例并執行查詢。

4.使用SqlSession對象提交或回滾事務。

使用MyBatis-Spring,可以在Spring ApplicationContext中配置上述大多數步驟,并且可以將SqlSession或Mapper實例注入到Spring Bean中。 然后,我們可以使用Spring的TransactionManagement功能,而無需在整個代碼中編寫事務提交/回滾代碼。

現在讓我們看看如何配置MyBatis + Spring集成的東西。

步驟#1:在pom.xml中配置MyBatis-Spring依賴項

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.1.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>3.1.1.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>3.1.1.RELEASE</version><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version><scope>runtime</scope></dependency><dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>2.2.2</version></dependency>


步驟#2:您不需要在mybatis-config.xml中配置數據庫屬性。

我們可以在Spring Container中配置DataSource并使用它來構建MyBatis SqlSessionFactory。

MyBatis-Spring使用org.mybatis.spring.SqlSessionFactoryBean代替SqlSessionFactoryBuilder來構建SqlSessionFactory。

我們可以將dataSource,Mapper XML文件位置,typeAliases等傳遞給SqlSessionFactoryBean。

<bean id='dataSource' class='org.apache.commons.dbcp.BasicDataSource'><property name='driverClassName' value='${jdbc.driverClassName}'/><property name='url' value='${jdbc.url}'/><property name='username' value='${jdbc.username}'/><property name='password' value='${jdbc.password}'/></bean><bean id='sqlSessionFactory' class='org.mybatis.spring.SqlSessionFactoryBean'><property name='dataSource' ref='dataSource' /><property name='typeAliasesPackage' value='com.sivalabs.mybatisdemo.domain'/><property name='mapperLocations' value='classpath*:com/sivalabs/mybatisdemo/mappers/**/*.xml' /></bean>

步驟#3:配置提供ThreadSafe SqlSession對象的SqlSessionTemplate。

<bean id='sqlSession' class='org.mybatis.spring.SqlSessionTemplate'><constructor-arg index='0' ref='sqlSessionFactory' /></bean>


步驟#4:為了能夠直接注入Mapper,我們應該注冊org.mybatis.spring.mapper.MapperScannerConfigurer并配置要在其中找到Mapper接口的包名稱。

<bean class='org.mybatis.spring.mapper.MapperScannerConfigurer'><property name='basePackage' value='com.sivalabs.mybatisdemo.mappers' /></bean>


步驟5:將 TransactionManager配置為支持基于注釋的事務支持。

<tx:annotation-driven transaction-manager='transactionManager'/><bean id='transactionManager' class='org.springframework.jdbc.datasource.DataSourceTransactionManager'><property name='dataSource' ref='dataSource' /></bean>


步驟#6:更新Service類并在Spring容器中注冊它們。

package com.sivalabs.mybatisdemo.service;import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import com.sivalabs.mybatisdemo.domain.User;
import com.sivalabs.mybatisdemo.mappers.UserMapper;@Service
@Transactional
public class UserService
{@Autowiredprivate SqlSession sqlSession; //This is to demonstrate injecting SqlSession objectpublic void insertUser(User user) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);userMapper.insertUser(user);}public User getUserById(Integer userId) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);return userMapper.getUserById(userId);}}

package com.sivalabs.mybatisdemo.service;import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sivalabs.mybatisdemo.domain.Blog;
import com.sivalabs.mybatisdemo.mappers.BlogMapper;@Service
@Transactional
public class BlogService
{@Autowiredprivate BlogMapper blogMapper; // This is to demonstratee how to inject Mappers directlypublic void insertBlog(Blog blog) {blogMapper.insertBlog(blog);}public Blog getBlogById(Integer blogId) {return blogMapper.getBlogById(blogId);}public List<Blog> getAllBlogs() {return blogMapper.getAllBlogs();}
}


注意:當我們可以直接注入Mappers時,為什么還要注入SqlSession對象? 因為SqlSession對象包含更細粒度的方法,所以有時會派上用場。

例如:如果我們想獲取更新查詢更新了多少條記錄,可以使用SqlSession,如下所示:

int updatedRowCount = sqlSession.update('com.sivalabs.mybatisdemo.mappers.UserMapper.updateUser', user);

到目前為止,我還沒有找到一種無需使用SqlSession對象即可獲取行更新計數的方法。

步驟#7編寫JUnit測試以測試UserService和BlogService。

package com.sivalabs.mybatisdemo;import java.util.List;import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.sivalabs.mybatisdemo.domain.User;
import com.sivalabs.mybatisdemo.service.UserService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations='classpath:applicationContext.xml')
public class SpringUserServiceTest 
{@Autowiredprivate UserService userService;@Testpublic void testGetUserById() {User user = userService.getUserById(1);Assert.assertNotNull(user);System.out.println(user);System.out.println(user.getBlog());}@Testpublic void testUpdateUser() {long timestamp = System.currentTimeMillis();User user = userService.getUserById(2);user.setFirstName('TestFirstName'+timestamp);user.setLastName('TestLastName'+timestamp);userService.updateUser(user);User updatedUser = userService.getUserById(2);Assert.assertEquals(user.getFirstName(), updatedUser.getFirstName());Assert.assertEquals(user.getLastName(), updatedUser.getLastName());}}

package com.sivalabs.mybatisdemo;import java.util.Date;
import java.util.List;import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.sivalabs.mybatisdemo.domain.Blog;
import com.sivalabs.mybatisdemo.domain.Post;
import com.sivalabs.mybatisdemo.service.BlogService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations='classpath:applicationContext.xml')
public class SpringBlogServiceTest 
{@Autowiredprivate BlogService blogService;@Testpublic void testGetBlogById() {Blog blog = blogService.getBlogById(1);Assert.assertNotNull(blog);System.out.println(blog);List<Post> posts = blog.getPosts();for (Post post : posts) {System.out.println(post);}}@Testpublic void testInsertBlog() {Blog blog = new Blog();blog.setBlogName('test_blog_'+System.currentTimeMillis());blog.setCreatedOn(new Date());blogService.insertBlog(blog);Assert.assertTrue(blog.getBlogId() != 0);Blog createdBlog = blogService.getBlogById(blog.getBlogId());Assert.assertNotNull(createdBlog);Assert.assertEquals(blog.getBlogName(), createdBlog.getBlogName());}}

參考: MyBatis教程:第3部分-映射關系 , ? MyBatis教程:第4部分–來自JCG合作伙伴 Siva Reddy的Spring Integration,來自My Experiments on Technology博客。

翻譯自: https://www.javacodegeeks.com/2012/11/mybatis-tutorial-crud-operations-and-mapping-relationships-part-2.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370642.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370642.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370642.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

position 的屬性值

理論上來說&#xff0c;全部 position 的取值有8個 包括&#xff1a;position&#xff1a;static | relative | absolute | fixed | sticky | initial | inherit | unset 其中最常用的是 static 、relative、absolute、fixed 和 sticky initial、inherit、unset 是css的關鍵…

[ JavaScript ] JavaScript 實現繼承.

對于javascript中的繼承&#xff0c;因為js中沒有后端語言中的類式繼承。所以js中的繼承&#xff0c;一般都是原型繼承(prototype)。 function P (name){this.name name;this.say function(){console.log(p);} }function S (name,id){this.id id;this.eat function(){conso…

mysql數據庫應用的權限層級_MySQL數據庫的用戶權限管理

嗨&#xff01;各位小伙伴今天翻了一下歷史記錄MySQL 數據庫還有點內容今天開始我們就來補上吧~用戶權限管理伙伴們要知道&#xff0c;在數據庫方面有兩個方向。一個是數據庫管理員(Database Administrator)簡稱DBA&#xff0c;一個是數據庫開發工程師(Database Developer)&…

linux i2c adapter 增加設備_Linux驅動之I2C驅動架構

一、Linux的I2C體系結構主要由三部分組成&#xff1a;(1) I2C核心提供I2C控制器和設備驅動的注冊和注銷方法&#xff0c;I2C通信方法&#xff0c;與適配器無關的代碼以及探測設備等。(2) I2C控制器驅動(適配器)(3) I2C設備驅動二、重要的結構體i2c_adapter//i2c控制器(適配器)i…

Alpha-end

前言 失心瘋病源10團隊代碼管理github個人感悟 肝不動了&#xff0c;肝不動了。明天如果見不到我&#xff0c;不要太想我。站立會議 隊名&#xff1a;PMS530雨勤&#xff08;組長&#xff09; 今天完成了那些任務 熬夜肝代碼代碼簽入github明天的計劃 肝到凌晨還剩下哪些任務 團…

html 01前沿-web介紹

1. 認識網頁 網頁主要由文字、圖像和超鏈接等元素構成。當然&#xff0c;除了這些元素&#xff0c;網頁中還可以包含音頻、視頻以及Flash等。 2. 瀏覽器&#xff08;顯示代碼&#xff09; 瀏覽器是網頁顯示、運行的平臺&#xff0c;常用的瀏覽器有IE、火狐&#xff08;Firefox…

避免寫慢SQL

最近在整理數據庫中的慢SQL&#xff0c;同時也查詢了相關資料。記錄一下&#xff0c;要學會使用執行計劃來分析SQL。 1. 為查詢緩存優化你的查詢 大多數的MySQL服務器都開啟了查詢緩存。這是提高性最有效的方法之一&#xff0c;而且這是被MySQL的數據庫引擎處理的。當有很多相同…

為什么子孫后代會討厭使用java.util.Stack

在我用無意義的重言式殺死你之前&#xff0c;這是要點 如果您的應用程序接近實時&#xff0c;或者將代碼發送到Mars&#xff0c;則需要保留Java中默認的Stack實現。 根據LinkedList編寫您自己的版本。 同樣&#xff0c;如果您的應用程序是關鍵任務&#xff0c;并且希望堆棧由…

play 連接mysql_Play framework 2.x 連接mysql | 學步園

筆者所使用的系統為64位 windows7。本文假設java1.5版本以上環境已經搭好&#xff0c;play 框架已經下載至本地。首先我們創建一個項目。命令行進入play的目錄命令&#xff1a;play new demo再次輸入項目名字輸入2 選擇java項目創建完成界面OK&#xff0c;一個play框架下的java…

rpm -e --nodeps_微課 | rpm的思維導圖

前導課程&#xff1a;微課 | rpm的查詢、升級與卸載命令本次微課將演示使用xmind繪制rpm思維導圖的過程&#xff0c;包括視頻文字&#xff0c;大約需要你10分鐘。另外&#xff0c;文末還有一則IT冷笑話&#xff0c;學習之余、會心一笑:)這個思維導圖將包含以下內容&#xff1a;…

CentOS7搭建lamp環境

Mysql安裝 CentOS 7 版本將MySQL數據庫軟件從默認的程序列表中移除&#xff0c;用mariadb代替了。MariaDB數據庫管理系統是MySQL的一個分支&#xff0c;主要由開源社區在維護&#xff0c;采用GPL授權許可。開發這個分支的原因之一是&#xff1a;甲骨文公司收購了MySQL后&#x…

border-sizing屬性詳解和應用

box-sizing用于更改用于計算元素寬度和高度的默認的 CSS 盒子模型。它有content-box、border-box和inherit三種取值。inherit指的是從父元素繼承box-sizing表現形式&#xff0c;不再冗贅。1. 屬性講解 content-box 默認值&#xff0c;也是css2.1中的盒子模型。在計算 width和…

Couchbase:使用Twitter和Java創建大型數據集

在播放/演示Couchbase或任何其他NoSQL引擎時&#xff0c;創建大型數據集的一種簡單方法是將Twitter feed注入到數據庫中。 對于這個小應用程序&#xff0c;我正在使用&#xff1a; Couchbase Server 2.0服務器 Couchbase Java SDK &#xff08;將由Maven安裝&#xff09; T…

查找標題已知的窗口句柄,遍歷窗口控件句柄

有了回調函數的概念及上面的例子,我們可以繼續了。其實想要找到一個標題已知的窗口句柄,用一個API函數就可以了:FindWindow. 其函數原形是: function FindWindow(lpClassName, lpWindowName: PChar): HWND; stdcall; lpClassName:窗口類名.如果只知道標題,可以為空.窗口類名可以…

西門子scl語言編程手冊_西門子SCL編程PEEK指令講解

單詞“peek”在英語中表示“偷看&#xff0c;瞥一眼”&#xff0c;在計算機編程中表示“讀取數據”。在西門子SCL編程中&#xff0c;PEEK指令可以用來讀取輸入緩存區(I)、輸出緩存區(Q)、位存儲區(M)及數據塊(DB)中的數據&#xff0c;常用作間接尋址。今天這篇文章&#xff0c;…

HTML第一章:初始HTML

設置ws字體大小&#xff1a;左上角file-->Settings--->在搜索框中輸入font網頁的第一行一定是<!DOCTYPE html>&#xff1a;網頁聲明&#xff0c;代表這個頁面是h5頁面html標簽中的leng"en"&#xff1a;意思是網頁中會用到英文 <meta>&#xff1a;…

Guava的Collections2:過濾和轉換Java集合

Groovy的便利之一是能夠通過Groovy的閉包支持輕松地對集合執行過濾和轉換操作。 Guava將對集合的過濾和轉換引入標準Java&#xff0c;這是本文的主題。 Guava的Collections2類具有兩個公共方法&#xff0c;這兩個方法都是靜態的。 方法filter&#xff08;Collection&#xff0…

釘釘機器人怎么設置自動回復_項目部署成功后觸發釘釘機器人發送消息提醒——入門配置...

釘釘建好一個群打開群設置, 找到群機器人添加一個你想要的機器人可以使用自定義自定義機器人可以自定義頭像,名字,生成一個webhook(https post的請求地址)到這里, 釘釘機器人設置好了,接下來我們對照文檔進行配置https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/XAzBI -…

mysql加鎖語法_MySql 加鎖問題

1、設置非自動提交 set autocommit0; 這時候 for update才會起作用2、一般用法 set autocommit0; for update(加鎖) ; commit/rollback; set autocommit1;首先看一下&#xff0c;set autocommit0 后&#xff0c;執行哪些語句會自動加鎖&#xff0c;加的是什么鎖&#xff1f…

td過長,將固定寬度table撐開

解決辦法&#xff1a; 在table上加上樣式: table{table-layout:fixed;word-break:break-all} table-layout:fixed tablle的列寬由表格寬度和列寬設定。 word-break:break-all 允許在單詞內換行。 正常情況下&#xff1a; table表格中td過長&#xff1a; 加上樣式之后&#…