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.mzph.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; 加上样式之后&#…