Spring Boot整合Mybatis及事务处理

MyBatis为了方便与Spring Boot集成,专门提供了一个符合其规范的starter项目mybatis-spring-boot-starter。因此,我们只需在pom.xml添加相关依赖即可轻松集成。下面介绍了Spring Boot整合Mybatis的具体步骤以及事务使用(包含解决事务失效的坑),本项目依赖Spring Boot版本为2.X,mybatis为3.X。

1、mysql数据库准备

创建数据库mybatis,并创建sys_user表

CREATE TABLE `sys_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) DEFAULT NULL,
  `user_password` varchar(50) DEFAULT NULL,
  `user_email` varchar(50) DEFAULT NULL,
  `user_info` text,
  `head_img` blob,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
)
INSERT INTO `sys_user` VALUES ('1', 'admin', '123456', '[email protected]', '管理员', null, '2019-06-12 14:44:59');
INSERT INTO `sys_user` VALUES ('2', 'test', '123456', '[email protected]', '测试用户', null, '2019-06-11 13:56:03');

2、pom.xml中添加依赖


	org.springframework.boot
	spring-boot-starter-web


	mysql
	mysql-connector-java


	org.mybatis.spring.boot
	mybatis-spring-boot-starter
	1.3.2


	junit
	junit
	test

3、application.properties

#数据源配置
spring.datasource.url=jdbc:mysql://XXXX:3306/mybatis?userUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=XXXX

#mybatis配置
#映射文件的路径,多个配置可以使用英文逗号隔开
mybatis.mapperLocations=classpath:mapper/*.xml
#类型别名包配置,只能指定具体的包,多个配置可以使用英文逗号隔开
mybatis.typeAliasesPackage=com.henry.springboot.model
#日志等级
logging.level.com.henry.springboot.mapper=debug

4、logback.xml日志配置



	

	
	
		
			[%-5level] %d{HH:mm:ss.SSS} [%thread] %logger - %msg%n
			
		
	

	
	
		${APP_HOME}/common/log.log
		
			${APP_HOME}/logs/common/log-%d{yyyy-MM-dd}.%i.log
			
			10000
			
				10GB
			
		
		
			[%-5level] %d{HH:mm:ss.SSS} [%thread] %logger - %msg%n
			
		
	

	
	
		
		
		
	

  

 至此配置已经基本完成(除mapper.xml文件),在写代码之前先看下项目结构:

Spring Boot整合Mybatis及事务处理_第1张图片

 

5、项目代码

(1)mapper接口及配置

UserMapper类

package com.henry.springboot.mapper;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.henry.springboot.model.SysUser;

public interface UserMapper {
	/**
	 * 查询全部数据
	 * 
	 * @return
	 */
	List selectAll();
	
	/**
	 * 根据指定条件查询数据
	 * @return
	 */
	SysUser selectById(Long id);
	
	/**
	 * 插入记录
	 * @param sysUser
	 * @return
	 */
	int insert(SysUser sysUser);
}

在src/main/resources中新建mapper文件夹并创建UserMapper.xml文件




    
	
	
		insert into sys_user(
		id, user_name, user_password, user_email, user_info, head_img, create_time) values(
		#{id}, #{userName}, #{userPassword}, #{userEmail}, #{userInfo}, #{headImg, jdbcType=BLOB},
		#{createTime, jdbcType=TIMESTAMP})
	

(2)服务层代码

服务接口UserService:

package com.henry.springboot.service;

import java.util.List;

import com.henry.springboot.model.SysUser;

public interface UserService {
	SysUser findById(Long id);
	
	List findAll();
	
	void insert(SysUser sysUser) throws Exception;
}

 服务接口实现类:

package com.henry.springboot.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.henry.springboot.mapper.UserMapper;
import com.henry.springboot.model.SysUser;
import com.henry.springboot.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserMapper UserMapper;

	@Override
	public SysUser findById(Long id) {
		return UserMapper.selectById(id);
	}

	@Override
	public List findAll() {
		return UserMapper.selectAll();
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void insert(SysUser sysUser) throws Exception {
		int i = UserMapper.insert(sysUser);
		throw new Exception("发生异常了");
	}
}

(3)controller代码

UserController类

package com.henry.springboot.controller;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.henry.springboot.model.SysUser;
import com.henry.springboot.service.impl.UserServiceImpl;

@RestController
public class UserController {

	private static final Logger logger = LoggerFactory.getLogger(UserController.class);

	@Autowired
	private UserServiceImpl userService;

	@RequestMapping("users/{id}")
	SysUser user(@PathVariable("id") Long id) {
		return userService.findById(id);
	}

	@RequestMapping("users")
	List user() {
		return userService.findAll();
	}

	@RequestMapping("insert")
	public String insert() {
		SysUser user = new SysUser();
		user.setUserName("test");
		user.setUserPassword("123456");
		user.setUserEmail("[email protected]");
		user.setUserInfo("测试1");
		user.setHeadImg(new byte[] { 1, 2, 3 });
		user.setCreateTime(new Date());
		try {
			userService.insert(user);
		} catch (Exception e) {
			logger.error("", e);
		}
		return "success";
	}
}

(4)model层代码

SysUser类

package com.henry.springboot.model;

import java.util.Date;

public class SysUser {
	private Long id;

	private String userName;

	private String userPassword;

	private String userEmail;

	private String userInfo;

	private byte[] headImg;

	private Date createTime;

	public Long getId() {
		return id;
	}

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

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public String getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}

	public String getUserInfo() {
		return userInfo;
	}

	public void setUserInfo(String userInfo) {
		this.userInfo = userInfo;
	}

	public byte[] getHeadImg() {
		return headImg;
	}

	public void setHeadImg(byte[] headImg) {
		this.headImg = headImg;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
}

6、运行

启动Spring Boot

(1)浏览器访问localhost:8080/users获取所有用户

Spring Boot整合Mybatis及事务处理_第2张图片

(2)localhost:8080/users/1

Spring Boot整合Mybatis及事务处理_第3张图片

7、事务处理
Spring Boot2.X事务处理非常简单,只需要在Service层添加@Transactional注解即可,上面代码中已经添加了。继续在浏览器中输入:localhost:8080/insert

Spring Boot整合Mybatis及事务处理_第4张图片

后台:

 

数据库:

 Spring Boot整合Mybatis及事务处理_第5张图片

 数据中数据依旧是两条,可以看到数据并没有真正插入到数据库中,因为事务遇到异常回滚了。

8、事务处理中的坑

坑1:上面服务层的Transaction后面我们加了(rollbackFor = Exception.class),如果不加会怎么样呢?

我们去掉后重新运行项目后,浏览器继续访问localhost:8080/insert,再看项目后台及数据库:

Spring Boot整合Mybatis及事务处理_第6张图片

 Spring Boot整合Mybatis及事务处理_第7张图片

 Spring Boot整合Mybatis及事务处理_第8张图片

 

数据库中记录插入成功了,事务回滚失败!

这是因为Spring的默认事务规则是遇到运行异常(RuntimeException及其子类)和程序错误(Error)才会进行事务回滚,显然throw new Exception("发生异常了");直接抛出不会进行事务回滚,但是可以在@Transactional注解中使用rollbackFor属性明确指定异常。

坑2:mysql的表是有事务安全( 比如:InnoDB)和非事务安全(比如:ISAM、MyISAM)之分的。如果自己的表是MyISAM类型的,那么久改为InnoDB,以支持事务处理。参见文章:https://blog.csdn.net/kaifaxiaoliu/article/details/79990357

最后附上该项目的下载地址:https://download.csdn.net/download/jcy1009015337/11290055,没有积分的私信我~~

你可能感兴趣的:(Spring,Boot)