为了说明这一点,我们正在考虑以下示例域模型:

会有用户,每个用户可能都有一个博客,每个博客可以包含零个或多个帖子。

这三个表的数据库结构如下:

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

MyBatis教程– CRUD操作和映射关系–第2部分相关推荐

  1. MyBatis教程– CRUD操作和映射关系–第1部分

    CRUD操作 MyBatis是一个SQL Mapper工具,与直接使用JDBC相比,它极大地简化了数据库编程. 步骤1:创建一个Maven项目并配置MyBatis依赖项. <project xm ...

  2. mybatis crud_MyBatis教程– CRUD操作和映射关系–第1部分

    mybatis crud CRUD操作 MyBatis是一个SQL Mapper工具,与直接使用JDBC相比,它极大地简化了数据库编程. 步骤1:创建一个Maven项目并配置MyBatis依赖项. & ...

  3. mybatis crud_MyBatis教程– CRUD操作和映射关系–第2部分

    mybatis crud 为了说明这一点,我们正在考虑以下示例域模型: 会有用户,每个用户可能都有一个博客,每个博客可以包含零个或多个帖子. 这三个表的数据库结构如下: CREATE TABLE us ...

  4. 2021年3月8日:MyBatis框架学习笔记02:利用MyBatis实现CRUD操作

    MyBatis框架学习笔记02:利用MyBatis实现CRUD操作 在第一节课中我们在UserMapper.xml里定义了两个查询语句:findById和findAll,对应的在UserMapper接 ...

  5. 使用MyBatis实现CRUD操作

    MyBatis 1.使用MyBatis实现CRUD操作 1.1 根据id查询信息 1.2 实现存入用户信息 1.3 更新用户信息 1.4 删除用户信息 1.5 模糊查询 1.6 #{}和${}的区别 ...

  6. mybatis进行CRUD操作时返回值不为影响的条数,为null

    对应自己的情况多试试看,总有一种方法可以解决吧! 1.如果报期望的返回值为null而原始返回值类型为int的错误 则将Dao/mapper接口中的函数的返回值类型改为Integer,在方法调用时使用. ...

  7. 利用MyBatis实现CRUD操作

    文章目录 一.打开MyBatisDemo项目 二.查询表记录 (一)在映射器配置文件里引入结果映射元素 (二)添加按姓名查询用户记录功能 1.在UserMapper.xml里添加映射语句 - find ...

  8. MyBatis框架学习笔记02:使用MyBatis实现CRUD操作

    文章目录 Ⅰ.查询表记录 (Ⅰ).在映射器配置文件里引入结果映射元素 (Ⅱ).添加按姓名查询用户记录功能 1).在UserMapper.xml里添加映射语句 - findByName 2).在User ...

  9. Mybatis实现CRUD操作

    项目实现的功能 查询所有用户信息 通过Id查询用户信息 添加用户(回显主键) 修改用户信息 删除用户信息 通过用户名字模糊查询 一.引入依赖和工程结构 <?xml version="1 ...

最新文章

  1. docker-registry的定制和性能分析
  2. fdquery update
  3. 辛苦了一个下午和晚上,给Blog换了个新皮肤
  4. LeetCode 406 Queue Reconstruction by Height
  5. echarts——父元素宽度100%,但canvas宽度100px
  6. python axes_python matplotlib中axes与axis的区别?
  7. mac 安装laravel Valet环境
  8. Ubuntu安装Curl的方法
  9. Whl自助搜索下载器
  10. 微软Azure云服务故障超过24小时,原因竟是——被雷劈了
  11. 【leetcode学习笔记】leecode是什么?
  12. Java笔记第五篇 文本编辑器初见面
  13. [译]Java 设计模式之组合
  14. 人体静止存在雷达探测,雷达感应模组技术,物联网智能化发展
  15. 《机会的数学》--陈希孺
  16. 约翰·冯·诺依曼的开挂人生
  17. Web前端期末大作业--中国港珠澳大桥网页设计(HTML+CSS+JavaScript)实现
  18. 中国传媒大学计算机课程表,课 程 表 - 中国传媒大学
  19. 如何让电脑连接上手机的无线网
  20. win10解决,你没有权限打开该文件,请向文件的所有者或管理员申请权限

热门文章

  1. java程序连接kafka_Java的Kafka:构建安全,可扩展的消息传递应用程序
  2. flowable背压 取消_使用Flowable.generate()生成可感知背压的流– RxJava常见问题解答...
  3. 注释嵌套注释_DIY注释
  4. java g1 收集调优_Java性能调优:充分利用垃圾收集器
  5. java不支持发行版本12_主要发行版本后Java开发人员应使用的15种工具
  6. git maven 发布_Maven Git发布
  7. javafx透明边框_JavaFX技巧6:使用透明颜色
  8. AWS Messaging Services:选择合适的服务
  9. 使用Caffeine和Spring Boot的多个缓存配置
  10. maven 部署nexus_Maven部署到Nexus