您的位置:首页 > 编程语言 > Java开发

java总结:Spring Boot整合Mybatis框架

2020-07-16 05:50 369 查看

java总结:Spring Boot整合Mybatis框架

1.Mybatis概述

Mybatis是一个优秀的持久层框架,底层基于JDBC实现与数据库的交互。并在JDBC操作的基础上做了封装和优化,它借助灵活的SQL定制,参数及结果集的映射方式,更好的适应了当前互联网技术的发展。Mybatis框架的简单应用架构,如下图所示:

在当今的互联网应用中项目,mybatis框架通常会由spring框架进行资源整合,作为数据层技术实现数据交互操作。

2.初始配置

1 添加mybatis启动依赖
参考官网mybatis.org/spring,找到springboot菜单选项.基于菜单项找到MyBatis启动依赖。

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

注意:在添加此依赖时,一定指定其版本(version),因为在springboot默认配置中没有设置mybatis框架版本。
2 Mybatis配置
我们添加了mybatis依赖以后,spring框架启动时会对mybatis进行自动配置。例如SqlSessionFactory工厂对象的创建。需要对mybatis框架进行简易配置,打开src/main/resources/application.properties文件,在此文件中配置spring datasource

#spring datasource
spring.datasource.url=jdbc:mysql:///dbgoods?serverTimezone=GMT%2B8&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

3 业务分析及实现

1 基本业务实现及单元测试
基于Spring对MyBatis框架的整合,实现对商品库中数据的删除操作。
第一步:业务API架构设计

第二步:基于id执行商品信息删除,其业务时序

第三步:定义商品业务数据层接口及业务方法。

package com.cy.pj.goods.dao;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
/**
* @Mapper是由Mybatis框架中定义的一个描述数据层接口对象的注解(所有的注解起到一个描述性的作用)
* 系统底层启动mybatis框架会基于@Mapper注解的描述,创建其接口的实现类,并将其实现类对象交给spring管理
*/
@Mapper
public interface GoodsDao {
/**
* 基于id删除数据库中商品信息
* @param id
* @return
*/
@Delete("delete from tb_goods where id=#{id}")
int deleteById(Integer id);
}

第四步:定义测试类,对GoodsDao对象进行应用测试

@SpringBootTest
public class GoodsDaoTests {
@Autowired
private GoodsDao goodsDao;

@Test
public void testDeleteById() {
int rows=goodsDao.deleteById(10);
System.out.println("rows="+rows);
}

}

第五步:删除业务时序图增强分析(了解SqlSession应用):

第六步:MyBatis API 对象应用过程分析

在上图中,展示业务设计中API对象的一种调用关系。例如我们的数据访问对象调用MyBatis API,然后MyBatis API底层通过使用用JDBC API(两大部分:java.sql.,
javax.sql.)访问数据库。
2 业务进阶分析及实现

在MyBatis框架中定义SQL映射的方式有两种:一种是将SQL映射定义在我们的xml映射文件中,一种方式是借助注解将其声明在接口方法上。我们在实际项目中对于简单的SQL映射可以直接以注解方式进行声明即可,复杂SQL还是要写到xml中,充分利用动态SQL进行设计会更好一些。

本小节,基于XML方式定义GoodsDao接口中的方法映射,实现批量删除操作,并进行单元测试:

Step01:在GoodsDao中,定义删除方法,具体代码如下:

/**
* 基于id进行批量删除操作
* @param ids
* @return
*/
//int deleteObjects(@Param("ids")Integer...ids);早期版本需要基于@Param注解
int deleteObjects(Integer...ids);//sql映射中可使用array,ids参数名来接收方法参数

说明:当接口方法对应的映射语句相对比较复杂时,建议将映射语句写到对应映射文件。

Step02:在src/main/resources目录下创建mapper目录,然后在其目录中添加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 namespace="com.cy.pj.goods.dao.GoodsDao">
<delete id="deleteObjects">
delete from tb_goods
where id in <!-- (1,2,3,4,5) -->
<foreach collection="ids"
open="("
close=")"
separator=","
item="id">
#{id}
</foreach>
</delete>
</mapper>

Step03:在application.properties文件中添加如下配置:

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

Step04:在GoodsDaoTests类中添加如下单元测试方法进行单元测试:

@Test
void testDeleteObjects(){
/**
* 执行goodsDao.deleteObjects方法时
* 系统会1)基于接口类全名找到namespace对应的映射文件
*/
int rows=goodsDao.deleteObjects(17,18);
System.out.println(rows);
}

常见异常:

思考:对于本小节映射文件中deleteObjects元素的定义,是否还有更好的方式。例如增强其健壮性(可靠性-无论传什么数据,都可以保证sql的语法的正确),性能。

<?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="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,5) -->
<foreach collection="ids"
open="(" close=")" separator="," item="id">
#{id}
</foreach>
</if>
or 1=2
</where>
</delete>
</mapper>

4 构建业务层接口及实现类

参考下图的设计,进行代码实现,具体业务自己设计(例如查询)。

我们的测试类GoodsServiceTest,通过耦合与GoodsService接口实现具体商品业务处理。
而在GoodsService接口的实现GoodsServiceImpl中通过耦合GoodsDao接口完成具体的数据逻辑处理。

实现商品信息的查询,并将查询到的数据在测试类中进行输出。具体步骤如下:
第一步:定义pojo对象(Goods)用于存储从数据库查询到的商品信息.

package com.cy.pj.goods.pojo;

import java.util.Date;
/**
* pojo对象,基于此对象封装从数据库查询到的数据
* 思考:对象靠什么存储数据?属性
*/
public class Goods {
private Long id;
private String name;
private String remark;
private Date createdTime;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}

public Date getCreatedTime() {
return createdTime;
}

public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}

@Override
public String toString() {
return "Goods{" +
"id=" + id +
", name='" + name + '\'' +
", remark='" + remark + '\'' +
", createdTime=" + createdTime +
'}';
}
}

第二步:定义dao方法,用于查询数据库数据。(一行记录映射为一个Goods对象)

@Select("select id,name,remark,createdTime from tb_goods")
List<Goods> findObjects();

第三步:定义业务层接口以及实现类,然后在类中添加商品查询的业务方法。

package com.cy.pj.goods.service;

import com.cy.pj.goods.pojo.Goods;

import java.util.List;

public interface GoodsService {
List<Goods> findGoods();
}
package com.cy.pj.goods.service.impl;

import com.cy.pj.goods.dao.GoodsDao;
import com.cy.pj.goods.pojo.Goods;
import com.cy.pj.goods.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
/**
* 商品业务层对象,负责业务逻辑处理
*/
@Service
public class GoodsServiceImpl implements GoodsService {
@Autowired
private GoodsDao goodsDao;
@Override
public List<Goods> findGoods() {
Long start=System.currentTimeMillis();
List<Goods> list=goodsDao.findObjects();
long end=System.currentTimeMillis();
System.out.println("query time:"+(end-start));
return list;
}
}

第四步:定义单元测试类,对业务层方法进行单元测试

package com.cy.pj.goods.service;

import com.cy.pj.goods.pojo.Goods;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class GoodsServiceTests {
@Autowired
private GoodsService goodsService;
@Test
public void testFindGoods(){
List<Goods> list=goodsService.findGoods();
list=goodsService.findGoods();
//System.out.println(list);//toString()
for (Goods g:list) {
System.out.println(g);//toString()
}
}
}

运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: