前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实用干货丨整合MyBatis的关键点及快速入门

实用干货丨整合MyBatis的关键点及快速入门

作者头像
博文视点Broadview
发布2020-06-10 16:35:23
3330
发布2020-06-10 16:35:23
举报
文章被收录于专栏:博文视点Broadview

对于从事Web应用开发人员,Java EE平台如今已经成为电信、金融、电子商务、保险、证券等各行业的大型应用系统的首选开发平台。在企业级应用的开发选择上,.NET已趋式微,PHP通常只用于开发一些企业展示站点或小型应用,因此这些开发语言、开发平台基本上已无法与Java EE进行对抗了。

目前轻量级Java EE企业开发平台中最核心的框架是Spring,而MVC框架大致存在两个选择:Spring MVC或Struts 2。由于技术方面的原因,Struts 2也渐趋没落;持久层框架则可选择JPA/Hibernate、MyBatis或Spring Data。

其中,MyBatis有它自己的优势:上手门槛低。即使是初级的Java开发者,上手MyBatis也很简单——直接把MyBatis当成单表数据库操作工具来用即可(在实际开发中确实有一些项目就是这么干的);而高级开发者依然可以利用MyBatis的关联映射和继承映射,而且可以灵活地对SQL语句进行优化,从而提高应用的数据库访问性能。

01

什么是MyBatis、Spring?

MyBatis是什么?它是一个SQL Mapping框架,它是一个持久化技术框架。再说得简单一点,它只不过是一个操作数据库的框架。

Spring是什么?Spring就是一个大容器,不管是IoC还是AOP,都是以Spring容器为基础的,因此,Spring不管整合什么框架,其关键都是利用Spring容器来管理其他框架的核心组件。

那么MyBatis编程的核心组件是什么?就是以下三个

  • SqlSessionFactory
  • Mapper组件
  • SqlSession

02

Java EE应用后端各层组件

此外,Java EE应用的后端大致可分为如图所示的几层。

Java EE应用后端分层

Java EE应用后端各层组件的大致功能如下。

DAO(Data Access Object)层:本层组件主要负责操作数据库,因此各种持久化技术(如MyBatis、JPA等)、索引技术(如Lucene、Solr等)主要集中在该层。

Service层:本层组件主要负责业务逻辑实现,该层组件向下依赖于DAO层的持久化功能,向上对控制器组件提供服务。

控制器层:本层组件主要负责分发、处理请求,该层组件向下依赖于Service层的业务逻辑功能。控制器组件既可对外提供RESTful API接口,也可直接与视图技术结合生成Web页面。

Spring框架是一个大容器,它的作用就是负责创建并管理容器中的所有DAO组件、Service组件、控制器组件等,并负责将DAO组件注入Service组件,将Service组件注入控制器组件。

MyBatis实现DAO组件的方式有两种

  • 传统的基于SqlSession实现DAO组件。
  • 使用Mapper组件充当DAO组件。

不管采用哪种方式,在整合Spring之后都会将DAO组件纳入Spring容器管理之下,并为DAO组件注入它所依赖的资源。比如基于SqlSession的DAO组件需要依赖SqlSession,而Mapper组件则需要依赖SqlSessionFactory—Spring会负责将SqlSessionFactory或SqlSession注入DAO组件。

此外,既然DAO组件和Service组件都在Spring容器管理之下,那么Spring容器也会将DAO组件注入Service组件。

归纳起来,在MyBatis整合Spring之后,Spring可为MyBatis完成如下事情。

  • Spring容器负责管理SqlSessionFactory。
  • Spring容器负责创建、管理Mapper组件或DAO组件。
  • Spring容器负责将Mapper组件或DAO组件注入Service组件。
  • Spring容器负责为Mapper组件或DAO组件注入所依赖的SqlSessionFactory或SqlSession。
  • Spring的AOP机制还可负责管理Service层的事务。

03

快速入门Spring与MyBatis的整合示例

在开始整合之前,需要先下载MyBatis与Spring整合的插件,该插件由MyBatis团队提供(不是由Spring提供的,MyBatis官网提供了一个MyBatis-Spring项目,该项目用于支持MyBatis与Spring的整合。

登录 链接9 站点下载MyBatis-Spring的最新版本,不要下载1.x系列的最新版本(1.x支持Spring 3.2及以上版本和Java 1.6及以上版本),要下载2.x系列(2.x支持Spring 5.0及以上版本和Java 1.8及以上版本),本书下载的是MyBatis-Spring 2.0.2,下载完成后得到一个mybatis-spring-2.0.2.jar文件,它就是MyBatis整合Spring的插件JAR包。

此外,既然要让Spring整合MyBatis,那么当然还需要为项目添加Spring的21个JAR包,以及MyBatis的核心JAR包:mybatis-3.5.2.jar。

接下来按照前面介绍的方式开发Mapper组件:Mapper接口+XML Mapper(或注解)。下面是Mapper接口的代码。

代码语言:javascript
复制
public interface BookMapper{    int saveBook(Book book);
    Book getBook(int id);}

该Mapper组件对应的XML Mapper映射文件如下。

代码语言:javascript
复制
<?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="org.crazyit.app.dao.BookMapper">    <insert id="saveBook">        insert into book_inf values(null, #{title}, #{author}, #{price})    </insert>    <select id="getBook" resultType="book">        select book_id id, book_title title, book_author author,        book_price price from book_inf where book_id=#{id}    </select></mapper>

为了更好地模拟Java EE应用的架构,本示例也为应用提供了Service组件(接口+实现类)。下面是BookService接口的代码。

代码语言:javascript
复制
public interface BookService{    int saveBook(Book book);
    Book getBook(int id);}

可能有读者感到疑惑:该Service组件内定义的两个方法与DAO组件内定义的两个方法是完全相同的吗?此时确实是这样的,这是由于本例只是一个演示技术的示例,它不涉及业务逻辑。

对于实际项目而言,Service组件的每个方法应该负责处理、实现一个业务逻辑功能,这个业务逻辑功能通常需要组合调用多个DAO组件的方法—具体来说,比如实现一个转账逻辑,该Service方法要调用DAO组件修改转出账户的余额,还要修改转入账户的余额,还要调用DAO组件插入一条转账记录。

总之,实现一个业务逻辑方法,通常需要按顺序调用多个DAO组件的方法。

本示例的Service组件很简单,它不涉及任何业务功能,因此它的每个方法只要调用一次DAO组件的方法即可。下面是该Service组件的实现类。

代码语言:javascript
复制
public class BookServiceImpl implements BookService{    private BookMapper bookMapper;    // 依赖注入Mapper组件所需的setter方法    public void setBookMapper(BookMapper bookMapper){        this.bookMapper = bookMapper;    }    @Override    public int saveBook(Book book){        return bookMapper.saveBook(book);    }    @Override    public Book getBook(int id){        return bookMapper.getBook(id);    }}

该Service组件定义了BookMapper变量代表它所依赖的DAO组件。为了让Spring容器为Service组件注入它所依赖的DAO组件,程序还为该DAO组件提供了setter方法—如果Service组件需要调用多个DAO组件的方法,就为每个DAO组件都定义对应的成员变量,并提供setter方法即可。至此,本示例的Mapper组件(DAO组件)和Service组件都已开发完成。

接下来需要将它们配置在Spring容器中,并让Spring容器来管理它们之间的依赖关系。下面是本示例的Spring配置文件。

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- 定义数据源Bean,使用C3P0数据源实现 -->    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"        destroy-method="close"        p:driverClass="com.mysql.cj.jdbc.Driver"        p:jdbcUrl="jdbc:mysql://localhost:3306/spring?serverTimezone=UTC"        p:user="root"        p:password="32147"/>    <!-- 配置MyBatis的核心组件:SqlSessionFactory,        并为该SqlSessionFactory配置它依赖的DataSource,        还指定将类加载路径下的mybatis-config.xml文件作为MyBatis的核心配置文件 -->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"        p:dataSource-ref="dataSource"        p:configLocation="classpath:mybatis-config.xml"/>    <!-- 使用MapperFactoryBean工厂Bean配置Mapper组件,        并为该Mapper组件配置它所依赖的SqlSessionFactory -->    <bean id="bookMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"        p:mapperInterface="org.crazyit.app.dao.BookMapper"        p:sqlSessionFactory-ref="sqlSessionFactory"/>    <!-- 配置Service组件,并为该Service组件配置它所依赖的Mapper组件 -->    <bean id="bookService" class="org.crazyit.app.service.impl.BookServiceImpl"        p:bookMapper-ref="bookMapper"/></beans>

上面配置文件中一共配置了4个Bean,其中第一个Bean是一个基于C3P0的数据源Bean,这与前面配置的数据源Bean并没有任何区别。

第二个Bean是SqlSessionFactoryBean,它是一个工厂Bean,它负责配置MyBatis的核心组件:SqlSessionFactory。

配置SqlSessionFactory为它注入了两个属性:dataSource和configLocation,其中configLocation指定MyBatis的核心配置文件,本示例指定使用类加载路径下的mybatis-config.xml作为MyBatis的核心配置文件。该文件的代码如下。

代码语言:javascript
复制
<?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>        <!-- 为org.crazyit.app.domain包下的所有类指定别名 -->        <package name="org.crazyit.app.domain"/>    </typeAliases></configuration>

将该配置文件与MyBatis独立应用的mybatis-config.xml进行对比,可以看到该文件主要少了两个元素:<environments.../>和<mappers.../>—这是由于Spring已为SqlSessionFactory注入了dataSource(数据源),不再需要配置数据源环境。另外,Spring容器接管了Mapper组件的发现、注册,也就不需要在mybatis-config.xml文件中配置<mappers.../>元素了。

Spring配置文件中的第三个Bean是Mapper组件(DAO组件),此处使用MapperFactoryBean来配置Mapper组件—所有的Mapper组件都使用该工厂Bean配置,程序获取该Bean时,实际返回的只是该工厂Bean的产品。

在使用MapperFactoryBean工厂Bean配置Mapper组件时,需要通过mapperInterface指定该Mapper组件的接口,并通过sqlSessionFactory属性为Mapper组件注入它所依赖的SqlSessionFactory。

Spring配置文件中的第四个Bean是Service组件,它已经没有任何特别之处了,就是简单地配置该Service组件,并为它注入所依赖的Mapper组件。

接下来,主程序即可获取Spring容器中配置的Service组件,并调用它的业务方法。

上面程序通过Spring容器获取了Service组件,并调用了Service组件的方法—Service组件依赖于DAO组件(Mapper组件),而Mapper组件则由MyBatis实现,该程序运行完成后将会看到book_inf表多了一条记录,并看到程序显示了id为1的Book实体的title、price,这说明Spring与MyBatis整合成功。

代码语言:javascript
复制
public class SpringTest{    public static void main(String[] args) throws Exception    {        var ctx = new ClassPathXmlApplicationContext("beans.xml");        // 获取容器中的Service组件        var bookService = ctx.getBean("bookService", BookService.class);        // 调用Service组件的方法        bookService.saveBook(new Book(null, "疯狂Java讲义", "李刚", 109.0));        var b = bookService.getBook(1);        System.out.println(b.getTitle() + "-->" + b.getPrice());    }}

李刚 著

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档