基于前文"Spring Boot初步学习02"(点击返回查看),曾经学习了Spring框架整合连接池的局部,连接池就是用于与数据库连贯的工具,那么本文就持续解说与数据库交互的局部---整合Mybatis框架.

Mybatis框架

MyBatis 本是apache的一个开源我的项目iBatis, 2010年这个我的项目由apache software foundation 迁徙到了google code,并且改名为MyBatis 。2013年11月迁徙到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的长久层框架。iBATIS提供的长久层框架包含SQL Maps和Data Access Objects(DAOs)

以上是百度中对于Mybatis框架的概述,在我了解来说,Mybatis框架是当初较为优良,应用较为宽泛的一个长久层框架,底层时基于JDBC去实现与数据库的交互,并且在应用的过程中,能够灵便去编写SQL语句,并且对于JDBC做了优化与封装,框架较小型,但很实用.

现在我的项目中应用Mybatis框架时,通常是由Spring框架进行整合,去实现数据交互操作,接下来就来说一下在Spring Boot中如何整合Mybatis.

整合过程

应用过程

测试类<-->mybatis<-->JDBC<-->Driver<-->数据库

须要留神的是:环节之间都是耦合于接口的,这样的设计更加灵便,更低耦合易保护批改.

创立我的项目

首先须要创立Spring Boot我的项目,创立过程可见Spring Boot疾速入门案例.

当然如果曾经有创立好的我的项目间接应用即可.

增加Mybatis依赖

增加依赖时,次要参考官网 mybatis.org/spring ,在springboot菜单中找到启动依赖,复制粘贴至pom.xml中

<dependency>    <groupId>org.mybatis.spring.boot</groupId>    <artifactId>mybatis-spring-boot-starter</artifactId>    <version>2.1.1</version></dependency>

另一种形式:右键我的项目中pom.xml-->spring-->Edit Starters-->搜寻Mybatis,增加依赖.
但要留神:springboot并没有为mybatis指定版本,以这种形式增加依赖,须要本人指定版本.

简略配置

Spring Boot特点就是零配置或简略配置,在mybatis官网中,尽管提供了一些配置,然而也都是可选的,不配置也能够失常运行,这里倡议配置几点

#spring.mybatismybatis.configuration.default-statement-timeout=30mybatis.configuration.map-underscore-to-camel-case=truelogging.level.com.cy=DEBUG

前两个配置别离是:设置sql超时工夫以及将数据库中的user_name(这类下划线命名)主动转换为userName(Java中的驼峰命名)
第三个配置是mybatis中的sql日志的输入:其中com.cy为我我的项目中的根包.

到这里对于mybatis与Springboot的整合就曾经实现了,很不便简略,前面是一些根底业务的实现.

业务实现

基于单个ID进行删除


创立数据层层接口

首先要创立数据层接口,代码如下:

@Mapperpublic interface GoodsDao {}

其中@Mapper注解是由Mybatis提供,形容数据层接口的的注解,用于通知Spring框架此接口的实现由mybatis创立,并将其实现类对象存储到spring容器,交由spring治理.

创立数据层业务办法

须要在数据层接口中,编写理论运行的业务办法,代码如下:

@Mapperpublic interface GoodsDao {    /**     * 基于商品id执行删除业务     * @param id     * @return 删除的行数     */      @Delete("delete from tb_goods where id=#{id}")     public int deleteById(Integer id);}

这种业务办法的编写模式,是将简略的sql语句通过注解的模式进行定义,写在办法上进行形容,然而简单的sql语句还是要写在映射文件中(xml文件中).

创立测试类

首先须要说的是,在测试类中咱们申明属性时只通过@Autowired注解申明接口(@Mapper形容的接口)不写实现类,是因为基于咱们曾经将springboot和mybatis整合,实现类会由mybatis创立再交由spring框架进行依赖注入(DI),所以咱们只有"面向接口"即可,理论创立由框架替咱们操心.

另外,如果你想要去确定框架创立的实现类到底是什么呢?
能够通过打桩(System.out.println(goodsDao.getClass().getName());)或是加断点的形式失去答案.

测试类代码如下:

@SpringBootTestpublic class GoodsDaoTests {    @Autowired    private GoodsDao goodsDao;    @Test    public void testDeleteById() {        int rows = goodsDao.deleteById(10);        System.out.println("rows="+rows);    }}

测试类是通过创立的实现类对象去调用@Mapper接口的业务办法,实现对数据库的操作.

基于多个ID批量删除


上文中也有提到简单的sql语句还是要写在映射文件中(xml文件中)利用动静SQL进行映射的,这个案例就要实际操作一下.

创立xml映射文件

首先创立xml映射文件,springboot我的项目中有严格的目录分类,须要将xml文件放在src/main/resource目录下,咱们能够再创立mapper/goods目录,而后将咱们的GoodsMapper.xml映射文件放入其中.

在映射文件中,首先须要增加官网中给出的头标签:

<?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>标签并在其中增加sql标签及其语句,此案例是依据ID批量删除,代码如下:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">      <delete id="deleteObjects">          delete from tb_goods where id in         <foreach collection="ids" open="("              item="id" separator="," close=")">              #{id}                </foreach>    </delete></mapper>

创立接口办法

在@Mapper接口中定义批量删除多个元素的办法,代码如下:

@Mapperpublic interface GoodsDao {/**     * 基于多个商品id删除     * @param ids     * @return 删除的行数     */    public int deleteObjects(@Param("ids")Integer... ids);}

办法中传参为"(@Param("ids")Integer... ids)",这是可变参数,能够了解为一类非凡的数组,能够传入0/1/2...n个数都可.个别最新版本的mybatis能够不加"@Param("ids")"这部分.

留神:xml文件中的namespace与接口的全限定类名对应,SQL标签的ID要与对应的接口办法名对应.

配置映射文件

当初咱们曾经写好了映射文件,以及接口办法,可如果有多个xml文件,spring框架如何晓得那个是咱们要它进行治理的呢?

就须要在application.properties配置文件中增加配置如下:

mybatis.mapper-locations=classpath:/mapper/*/*.xml

"*"为通配符,象征所有的,咱们的xml映射文件门路是在根目录下的mapper/goods/GoodsMapper.xml,就在配置的范畴内.

创立测试类

在src/test/java目录下编写测试类,代码如下:

@SpringBootTestpublic class GoodsDaoTests {    @Autowired    private GoodsDao goodsDao;    @Test    public void testDeleteObjects() {        int rows = goodsDao.deleteObjects(6,7,8,9);        System.out.println("rows="+rows);    }}

底层的执行程序是:
测试方法执行时,咱们调用接口实现类的办法,实现类外部会检测接口办法上是否有定义sql映射;如果没有会基于接口类全名找到对应的配置的映射文件,而后再基于办法名找到对应映射文件中的标签,进而获取sql映射.

加强SQL语句可靠性

以上曾经实现了咱们的要求,然而在xml映射文件中写简单SQL语句时,咱们须要增强SQL语句的可靠性,尤其是删除语句,在对数据库进行操作时,删除语句永远是咱们最须要小心的!

咱们须要思考到传入各种数据的状况,如上文所写的:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">      <delete id="deleteObjects">          delete from tb_goods where id in           <foreach collection="ids" open="("              item="id" separator="," close=")">              #{id}                  </foreach>    </delete></mapper>

当咱们如果什么都不传时,SQL语句就变为:delete from tb_goods where id in ;这样就会报错,所以咱们能够增加动静SQL欠缺!如下:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">      <delete id="deleteObjects">          delete from tb_goods            <if test="ids!=null and ids.length>0">                where id in                <foreach collection="ids" open="("                        item="id" separator="," close=")">                    #{id}                        </foreach>            </if>    </delete></mapper>

退出<if>标签进行判断,排除了传入null的状况,然而又发现ids不为null时能够失常执行,但如果ids为null,没进入判断,SQL语句是没有语法问题,然而执行就变为:delete from tb_goods,删除整个表,在工作中这就是铸成大错了!所以还须要进一步改良,如下再退出<where>标签:

<mapper namespace="com.cy.pj.goods.dao.GoodsDao">    <delete id="deleteObjects">        delete from tb_goods        <where>            <if test="ids!=null and ids.length>0">                id in <!-- (1,2,3,4) -->                <foreach collection="ids" open="("                        item="id" separator="," close=")">                    #{id}                        </foreach>            </if>            or 1=2        </where>    </delete>  </mapper>

这样就解决了所有状况能够平安应用了.