博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Persistence with MyBatis 3(中国版) 第五章 与Spring集成
阅读量:7175 次
发布时间:2019-06-29

本文共 12311 字,大约阅读时间需要 41 分钟。

    MyBatis-Spring它是MyBatis子模块框。它用来提供流行的依赖注入框架Spring无缝集成。

    Spring框架是一个基于依赖注入(Dependency Injection)和面向切面编程(Aspect Oriented Programming,AOP)的Java框架,鼓舞使用基于POJO的编程模型。

另外,Spring提供了声明式和编程式的事务管理能力。能够非常大程度上简化应用程序的数据訪问层(data access layer)的实现。在本章中,我们将看到在基于Spring的应用程序中使用MyBatis而且使用Spring的基于注解的事务管理机制。

 

本章将包括下面话题:

  • 在Spring应用程序中配置MyBatis

           安装

           配置MyBatis Beans

  • 使用SqlSession
  • 使用映射器
  • 使用Spring进行事务管理

5.1 在Spring应用程序中配置MyBatis

本节将讨论怎样在基于Spring的应用程序中安装和配置MyBatis。

5.1.1 安装

假设你正在使用Maven构建工具,你能够配置MyBatis的spring依赖例如以下:

org.mybatis
mybatis-spring
1.2.0
org.springframework
spring-context-support
3.1.3.RELEASE
commons-logging
commons-logging
org.springframework
spring-jdbc
3.1.3.RELEASE
org.springframework
spring-test
3.1.3.RELEASE
test
org.aspectj
aspectjrt
1.6.8
org.aspectj
aspectjweaver
1.6.8
cglib
cglib-nodep
2.2
commons-dbcp
commons-dbcp
1.4

    假设你没有使用Maven。你能够从上下载mybatis-spring-1.2.0-boundle.zip。将其加入,将mybatis-1.2.0.jar包加入到classpath中。

    你能够从上下载Spring框架包spring-framework-3.1.3.RELEASE.zip。将其内全部jar包加入到classpath中。

    假设你仅仅使用MyBatis而没有使用Spring,在每个方法中,我们须要手动创建SqlSessionFactory对象,并且从SqlSessionFactory对象中创建SqlSession。并且我们还要负责提交或者回滚事务、关闭SqlSession对象。

    通过使用MyBatis-Spring模块,我们能够在Spring的应用上下文ApplicationContext中配置MyBatis Beans,Spring会负责实例化SqlSessionFactory对象以及创建SqlSession对象,并将其注入到DAO或者Service类中。而且,你能够使用Spring的基于注解的事务管理功能,不用自己在数据訪问层中书写事务处理代码了。

5.1.2 配置MyBatis Beans

为了让Spring来实例化MyBatis组件如SqlSessionFactory、SqlSession、以及映射器Mapper对象。我们须要在Spring的bean配置文件里配置它们,如果在applicationContext.xml中。配配置例如以下:

使用上述的bean定义,Spring会使用例如以下配置属性创建一个SqlSessionFactory对象:

  •         ž dataSource:它引用了dataSource bean
  •         ž typeAliases:它指定了一系列的全然限定名的类名列表,用逗号隔开。这些别名将通过默认的别名规则创建(将首字母小写的非无全然限定类名作为别名)。
  •         ž typeAliasesPackage:它指定了一系列包名列表,用逗号隔开,包内含有须要创建别名的JavaBeans。

  •         ž typeHandlers:它指定了一系列的类型处理器类的全然限定名的类名列表,用逗号隔开。

  •         ž typeHandlersPackage: 它指定了一系列包名列表。用逗号隔开。包内含有须要被注冊的类型处理器类。

  •         ž mapperLocations:它指定了SQL映射器Mapper XML配置文件的位置
  •          configLocation:它指定了MyBatisSqlSessionFactory配置文件所在的位置。

5.2 使用SqlSession

一旦SqlSessionFactory bean被配置,我们须要配置SqlSessionTemplate bean。SqlSessionTemplatebean 是一个线程安全的Spring bean,我们能够从中获取到线程安全的SqlSession对象。

因为SqlSessionTemplate提供线程安全的SqlSession对象,你能够在多个Spring bean实体对象中共享SqlSessionTemplate对象。从概念上看,SqlSessionTemplate和Spring的DAO模块中的JdbcTemplate很相似。

如今我肯能够将SqlSessionbean实体对象注射到随意的Springbean实体中,然后使用SqlSession对象调用SQL映射语句。

public class StudentDaoImpl implements StudentDao{    private SqlSession sqlSession;    public void setSqlSession(SqlSession session)    {        this.sqlSession = session;    }    public void createStudent(Student student)    {        StudentMapper mapper =            this.sqlSession.getMapper(StudentMapper.class);        mapper.insertStudent(student);    }}
假设你正在使用基于XML来配置Spring beans,你能够将SqlSessionbean实体对象注射到StudenDaoImpl bean 实体对象中。例如以下:

假设你使用基于注解的方式配置Spring beans。你例如以下将SqlSession bean实体对象注入到StudentDaoImplbean实体对象中:

@Repositorypublic class StudentDaoImpl implements StudentDao{    private SqlSession sqlSession;    @Autowired    public void setSqlSession(SqlSession session)    {        this.sqlSession = session;    }    public void createStudent(Student student)    {        StudentMapper mapper =            this.sqlSession.getMapper(StudentMapper.class);        mapper.insertStudent(student);    }}

还有第二种注入Sqlsession对象的方法,即。通过拓展继承SqlSessionDaoSupport。这样的方式让我们能够在运行映射语句时,增加不论什么自己定义的逻辑。

public class StudentMapperImpl extends SqlSessionDaoSupport implements    StudentMapper{    public void createStudent(Student student)    {        StudentMapper mapper =            getSqlSession().getMapper(StudentMapper.class);        mapper.insertAddress(student.getAddress());        //Custom logic        mapper.insertStudent(student);    }}

在以上的这些方式中。我们注入了SqlSession对象,获取Mapper实例,然后运行映射语句。

这里Spring会为我们提供一个线程安全的SqlSession对象,以及当方法结束后关闭SqlSession对象。

然而。MyBatis-Spring模块提供了更好的方式,我们能够不通过SqlSession获取映射器Mapper,直接注射Sql映射器Mapper bean。我们下节将讨论它。

5.3 使用映射器

我们能够使用MapperFactoryBean将映射器Mapper接口配置成Spring bean实体。

例如以下所看到的:

public interface StudentMapper{    @Select("select stud_id as studId, name, email, phone from            students where stud_id=#{id}")    Student findStudentById(Integer id);}
如今StudentMapper bean实体对象能够被注入到随意的Spring bean实体对象中,并调用映射语句方法,例如以下所看到的:
public class StudentService{    private StudentMapper studentMapper;    public void setStudentMapper (StudentMapperstudentMapper)    {        this. studentMapper = studentMapper;    }    public void createStudent(Student student)    {        this.studentMapper.insertStudent(student);    }}

分别配置每个映射器Mapper接口是一个很单调的过程。

我们能够使用MapperScannerConfigurer来扫描包(package)中的映射器Mapper接口。并自己主动地注冊。

假设映射器Mapper接口在不同的包(package)中,你能够为basePackage属性指定一个以逗号分隔的包名列表。

MyBatis-Spring-1.2.0介绍了两种新的扫描映射器Mapper接口的方法:

  • l   使用<mybatis:scan/>元素
  • l   使用@MapperScan注解(需Spring3.1+版本号)

5.3.1 <mybatis:scan />

<mybatis:scan>元素将在特定的以逗号分隔的包名列表中搜索映射器Mapper接口。使用这个新的MyBatis-Spring名空间你须要加入下面的schema声明:

<mybatis:scan>元素提供了下列的属性来自己定义扫描过程:

  •         annotation: 扫描器将注冊全部的在base-package包内而且匹配指定注解的映射器Mapper接口。

  •         factory-ref:当Spring上下文中有多个SqlSessionFactory实例时。须要指定某一特定的SqlSessionFactory来创建映射器Mapper接口。

    正常情况下,仅仅有应用程序中有一个以上的数据源才会使用。

  •         ž marker-interface: 扫描器将注冊在base-package包中的而且继承了特定的接口类的映射器Mapper接口
  •         ž template-ref: 当Spring上下文中有多个SqlSessionTemplate实例时。须要指定某一特定的SqlSessionTemplate来创建映射器Mapper接口。正常情况下,仅仅有应用程序中有一个以上的数据源才会使用。
  •          name-generator:BeannameGenerator类的全然限定类名,用来命名检測到的组件。

5.3.2 MapperScan

Spring 框架3.x+版本号支持使用@Configuration和@Bean 注解来提供基于Java 的配置。假设你倾向于使用基于Java的配置,你能够使用@MapperScan注解来扫描映射器Mapper接口。@MapperScan和<mybatis:scan/>工作方式同样,而且也提供了相应的自己定义选项。

@Configuration@MapperScan("com.mybatis3.mappers")public class AppConfig{    @Bean    public DataSource dataSource()    {        return new PooledDataSource("com.mysql.jdbc.Driver",                                    "jdbc:mysql://localhost:3306/elearning", "root", "admin");    }    @Bean    public SqlSessionFactory sqlSessionFactory() throws Exception    {        SqlSessionFactoryBeansessionFactory = new        SqlSessionFactoryBean();        sessionFactory.setDataSource(dataSource());        return sessionFactory.getObject();    }}

@MapperScan注解有下面属性供自己定义扫描过程使用:

      ž annotationClass: 扫描器将注冊全部的在base-package包内而且匹配指定注解的映射器Mapper接口。

      ž markerInterface: 扫描器将注冊在base-package包中的而且继承了特定的接口类的映射器Mapper接口

      ž sqlSessionFactoryRef:当Spring 上下文中有一个以上的SqlSesssionFactory时,用来指定特定SqlSessionFactory

      ž sqlSessionTemplateRef: 当Spring 上下文中有一个以上的sqlSessionTemplate时,用来指定特定sqlSessionTemplate

      ž nameGenerator:BeanNameGenerator类用来命名在Spring容器内检測到的组件。

      ž basePackageClasses:basePackages()的类型安全的替代品。包内的每个类都会被扫描。

      ž basePackages:扫描器扫描的基包,扫描器会扫描内部的Mapper接口。注意包内的至少有一个方法声明的才会被注冊。详细类将会被忽略。

5.4 使用Spring进行事务管理

仅仅使用MyBatis。你须要写事务控制相关代码,如提交或者回退数据库操作。

public Student createStudent(Student student){    SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().                            openSession();    try    {        StudentMapper mapper =            sqlSession.getMapper(StudentMapper.class);        mapper.insertAddress(student.getAddress());        mapper.insertStudent(student);        sqlSession.commit();        return student;    }    catch (Exception e)    {        sqlSession.rollback();        throw new RuntimeException(e);    }    finally    {        sqlSession.close();    }}

我们能够使用Spring的基于注解的事务处理机制来避免书写上述的每一个方法中控制事务的冗余代码。

为了能使用Spring的事务管理功能,我们须要在Spring应用上下文中配置TransactionManagerbean实体对象:

事务管理器引用的dataSource和SqlSessionFactory bean使用的dataSource同样。

在Spring中使用基于注解的事务管理特性,例如以下:

如今你能够在Spring service bean上使用@Transactional注解。表示在此service中的每个方法都应该在一个事务中执行。假设方法成功执行完成,Spring会提交操作。假设有执行期异常发生,则会执行回滚操作。另外,Spring会将MyBatis 的异常转换成合适的DataAccessExceptions,这样会为特定错误上提供额外的信息。

@Service@Transactionalpublic class StudentService{    @Autowired    private StudentMapper studentMapper;    public Student createStudent(Student student)    {        studentMapper.insertAddress(student.getAddress());        if(student.getName().equalsIgnoreCase(""))        {            throw new RuntimeException("Student name should not be                                       empty.");        }        studentMapper.insertStudent(student);        return student;    }}

以下是一个Spring的applicationContext.xml完毕配置:

如今让我们写一个独立的測试client来測试StudentService,例如以下:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:applicationContext.xml"                     )public class StudentServiceTest{    @Autowired    private StudentService studentService;    @Test    public void testCreateStudent()    {        Address address = new Address(0, "Quaker Ridge                                      Rd.", "Bethel", "Brooklyn", "06801", "USA");        Student stud = new Student();        long ts = System.currentTimeMillis();        stud.setName("stud_" + ts);        stud.setEmail("stud_" + ts + "@gmail.com");        stud.setAddress(address);        Student student = studentService.createStudent(stud);        assertNotNull(student);        assertEquals("stud_" + ts, student.getName());        assertEquals("stud_" + ts + "@gmail.com", student.getEmail());        System.err.println("CreatedStudent: " + student);    }    @Test(expected = DataAccessException.class)    public void testCreateStudentForException()    {        Address address = new Address(0, "Quaker Ridge                                      Rd.", "Bethel", "Brooklyn", "06801", "USA");        Student stud = new Student();        long ts = System.currentTimeMillis();        stud.setName("Timothy");        stud.setEmail("stud_" + ts + "@gmail.com");        stud.setAddress(address);        studentService.createStudent(stud);        fail("You should not reach here");    }}
这里在testCreateStudent()方法中,我们为Address和Student赋上了合适的数据,所以Address和Student会被分别插入到表ADDRESSES和STUDENTS中。在testCreateStudentForException()方法我们设置了名字为Timothy,该名称在数据库中已经存在了,所以当你尝试将此student记录插入到数据库中。MySQL会抛出一个UNIQUE KEY 冲突的异常。Spring会将此异常转换成DataAccessException异常。而且将插入ADDRESSES表中的数据回滚(rollback)掉。

5.5 总结

在本章中我们学习了如何将MyBatis与Spring框架集成。我们还学习了如何安装Spring类库而且在Spring 的应用上下文ApplicationContext上注冊MyBatis bean实体对象。

我们还看到如何配置和注入SqlSession和Mapper bean实体对象以及调用映射语句。我们还学习了利用Spring基于注解的事务处理机制来使用MyBatis。

 

你已经读完本书,祝贺你!

如今,你应该知道如何高效地使用MyBatis与数据库工作。你学会了如何发挥你的Java和SQL技巧的优势使MyBatis更富有成效。

你知道了如何以更清晰的方式使用MyBatis写出数据持久化代码,不用管被MyBatis框架处理的全部底层细节。

另外,你学会了如何在最流行的依赖注入框架-Spring中使用MyBatis。

 

MyBatis框架很易于使用,但它提供了强大的特性。因此它对于基于Java的项目而言。是一个很好的数据库持久化解决方式。

MyBatis也提供了一些工具如MyBatis Generator(http://www.mybatis.org/generator/),能够被用来从已经存在的数据库schema中,产生持久化代码如数据库实体(databaseentities),映射器Mapper 接口,MapperXML配置文件,使MyBatis入门很方便。另外,MyBatis还有它的姊妹项目如MyBatis.NET和MyBatis-Scala,分别为.NET 和Scala编程语言提供了一样强大的特性。

 

MyBatis随着每个版本号的公布。添加了一些特性。正变得越来越好。想了解很多其它的新特性,你能够訪问MyBatis官方站点.订阅MyBatis 的使用者邮件列表是一个不错的想法。我们祝你一切顺利,编码快乐!(We wish you all the best, and happy coding!)

《Java Persistence with MyBatis 3(中文版)》导航:

-----------------------------------------------------------------------------------------------------------------------
作者声明:这篇文章是源http://blog.csdn.net/luanlouis,如需转载。转载请注明出处。

你可能感兴趣的文章
微信亿级用户异常检测框架的设计与实践
查看>>
全然用linux工作,放弃windows
查看>>
QT中VideoProbe的简介和实现
查看>>
HDU 3595 GG and MM(Every-SG)
查看>>
打造html右键菜单
查看>>
Bmob实现android云端存储
查看>>
关于JS里的函数作用域链的总结
查看>>
Python的sys.argv使用说明 通过终端写入环境变量
查看>>
在Windows上安装Nexus
查看>>
Future模式 总结
查看>>
为什么我再也不想和 Google HR 交谈了
查看>>
byzx
查看>>
虫洞漏洞挖掘研究
查看>>
用mysql查询某字段是否有索引
查看>>
ubuntu 查看进程,查看服务
查看>>
Cisco DHCP Snooping + IPSG 功能实现
查看>>
Linux命令_用户身份切换
查看>>
学习在.NET Core中使用RabbitMQ之启动和基础(一)
查看>>
支付业务的数据库表的设计
查看>>
php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结)...
查看>>