接着上篇

一、准备工作


修改pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.github.carter659</groupId>
<artifactId>spring06</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent> <name>spring06</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

pom.xml

添加src/resources/application.properties文件

spring.datasource.initialize=false
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

application.properties

添加src/resources/templates/index.html文件

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>玩转spring boot——结合JPA</title>
<script src="//cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
var app = angular.module('app', []);
app.controller('MainController', function($rootScope, $scope, $http) { $scope.data = {};
$scope.rows = []; //添加
$scope.add = function() {
$scope.data = {
no : 'No.1234567890',
quantity : 100,
'date' : '2017-01-01'
};
} //保存
$scope.save = function() {
$http({
url : '/save',
method : 'POST',
data : $scope.data
}).success(function(r) {
//保存成功后刷新
window.location.reload();
});
} //初始化载入数据
$http({
url : '/findAll',
method : 'POST'
}).success(function(rows) {
for ( var i in rows) {
var row = rows[i];
$scope.rows.push(row);
}
}); }); /*]]>*/
</script>
</head>
<body ng-app="app" ng-controller="MainController">
<h1>玩转spring boot——JPA事务</h1>
<h4>
<a href="http://www.cnblogs.com/GoodHelper/">from 刘冬的博客</a>
</h4>
<input type="button" value="添加" ng-click="add()" />
<input type="button" value="保存" ng-click="save()" />
<br />
<br />
<h3>订单信息:</h3>
<input type="hidden" ng-model="data.id" />
<table cellspacing="1" style="background-color: #a0c6e5">
<tr>
<td>编号:</td>
<td><input ng-model="data.no" /></td>
<td>日期:</td>
<td><input ng-model="data.date" /></td>
<td>数量:</td>
<td><input ng-model="data.quantity" /></td>
</tr>
</table>
<br /> <h3>订单列表:</h3>
<table cellspacing="1" style="background-color: #a0c6e5">
<tr ng-repeat="row in rows" bgcolor='#F4FAFF'>
<td>{{row.no}}</td>
<td>{{row.date}}</td>
<td>{{row.quantity}}</td>
</tr>
</table> <br />
<a href="http://www.cnblogs.com/GoodHelper/">点击访问原版博客</a>
</body>
</html>

上篇的Order类

package com.github.carter659.spring06;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType; import org.hibernate.annotations.GenericGenerator; /**
* 博客出处:http://www.cnblogs.com/GoodHelper/
*
* @author 刘冬
*
*/
@Entity
@Table(name = "t_order")
public class Order { @Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "order_id", length = 36)
public String id; @Column(name = "order_no", length = 50)
public String no; @Temporal(TemporalType.DATE)
@Column(name = "order_date")
public Date date; @Column(name = "quantity")
public int quantity; /**
* 省略 get set
*/
}

Order.java

新建实现JpaRepository的OrderRepository接口

package com.github.carter659.spring06;

import org.springframework.data.jpa.repository.JpaRepository;

/**
* 博客出处:http://www.cnblogs.com/GoodHelper/
*
* @author 刘冬
*
*/
public interface OrderRepository extends JpaRepository<Order, String> { }

OrderRepository.java

新建OrderDao类

package com.github.carter659.spring06;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository; import com.mysql.jdbc.StringUtils; @Repository
public class OrderDao { @Autowired
private OrderRepository orderRepository; /**
* 获取全部
*
* @return
*/
public List<Order> findAll() {
return orderRepository.findAll();
} /**
* 持久化
*
* @param entity
* @return
*/
public void save(Order entity) throws Exception {
// 持久化
orderRepository.save(entity);
// 如果持久化成功,就抛出异常。如果开启事务,那么刚才持久化的数据应回滚
if (!StringUtils.isNullOrEmpty(entity.id))
throw new Exception("测试无法持久化第一条数据的异常");
}
}

假设:当成功insert一条数据后,抛出异常。如果事务生效,则数据会回滚。反之,则不回滚。

控制器:MainController

package com.github.carter659.spring06;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody; /**
* 博客出处:http://www.cnblogs.com/GoodHelper/
*
* @author 刘冬
*
*/
@Controller
public class MainController { @Autowired
private OrderDao orderDao; /**
* 处理日期类型
*
* @param binder
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
} @GetMapping("/")
public String index() {
return "index";
} /**
* 持久化
*
* @param entity
* @return
*/
@PostMapping("/save")
public @ResponseBody Map<String, Object> save(@RequestBody Order entity) {
Map<String, Object> result = new HashMap<>();
try {
orderDao.save(entity);
result.put("success", true);
} catch (Exception e) {
result.put("success", false);
}
return result;
} /**
* 获取全部
*
* @return
*/
@PostMapping("/findAll")
public @ResponseBody Object findAll() {
return orderDao.findAll();
}
}

MainController.java

程序入口:App.java

package com.github.carter659.spring06;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; /**
* 博客出处:http://www.cnblogs.com/GoodHelper/
*
* @author 刘冬
*
*/
@SpringBootApplication
public class App { public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}

App.java

运行效果:

添加数据

点击保存按钮,并观察数据是否回滚:

虽然抛出异常,但数据并未回滚。

二、实现事务


这时,我修改OrderDao类,增加@Transactional(readOnly = false, rollbackFor = Throwable.class)注解:

package com.github.carter659.spring06;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import com.mysql.jdbc.StringUtils; @Repository
@Transactional(readOnly = false, rollbackFor = Throwable.class)
public class OrderDao { @Autowired
private OrderRepository orderRepository; /**
* 获取全部
*
* @return
*/
public List<Order> findAll() {
return orderRepository.findAll();
} /**
* 持久化
*
* @param entity
* @return
*/
public void save(Order entity) throws Exception {
// 持久化
orderRepository.save(entity);
// 如果持久化成功,就抛出异常。如果开启事务,那么刚才持久化的数据应回滚
if (!StringUtils.isNullOrEmpty(entity.id))
throw new Exception("测试无法持久化第一条数据的异常");
}
}

继续添加数据:

按钮保存按钮,发现:数据回滚

代码下载:https://github.com/carter659/spring-boot-06.git

如果你觉得我的博客对你有帮助,可以给我点儿打赏,左侧微信,右侧支付宝。

有可能就是你的一点打赏会让我的博客写的更好:)

玩转spring boot系列目录

玩转spring boot——结合JPA事务的更多相关文章

  1. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  2. 玩转spring boot——开篇

    很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...

  3. 玩转spring boot——properties配置

    前言 在以往的java开发中,程序员最怕大量的配置,是因为配置一多就不好统一管理,经常出现找不到配置的情况.而项目中,从开发测试环境到生产环境,往往需要切换不同的配置,如测试数据库连接换成生产数据库连 ...

  4. 玩转Spring Boot 集成Dubbo

    玩转Spring Boot 集成Dubbo 使用Spring Boot 与Dubbo集成,这里我之前尝试了使用注解的方式,简单的使用注解注册服务其实是没有问题的,但是当你涉及到使用注解的时候在服务里面 ...

  5. Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源

    本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题.在 Spring Boot 整合JbdcTemplate 多数据源. ...

  6. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  7. 玩转spring boot——结合redis

    一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...

  8. 玩转spring boot——AOP与表单验证

    AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...

  9. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

随机推荐

  1. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  2. 【每日一linux命令4】常用参数:

     下面所列的是常见的参数(选项)义: --help,-h                              显示帮助信息 --version,-V                        ...

  3. 【声明】前方不设坑位,不收费!~ 我为NET狂官方学习计划

    发个通知,过段时间学习计划相关的东西就出来了,上次写了篇指引文章后有些好奇心颇重的人跟我说:“发现最近群知识库和技能库更新的频率有点大,这是要放大招的节奏啊!” 很多想学习却不知道如何规划的人想要一个 ...

  4. 浅谈web攻防

    CSRF 跨站请求伪造(Cross-Site Request Forgery) -原理- 从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤: 1.登录受信任网站A,并在本地生成Coo ...

  5. Spring resource bundle多语言,单引号format异常

    Spring resource bundle多语言,单引号format异常 前言 十一假期被通知出现大bug,然后发现是多语言翻译问题.法语中有很多单引号,单引号在format的时候出现无法匹配问题. ...

  6. ASP.NET Core 中文文档 第五章 测试(5.2)集成测试

    原文: Integration Testing 作者: Steve Smith 翻译: 王健 校对: 孟帅洋(书缘) 集成测试确保应用程序的组件组装在一起时正常工作. ASP.NET Core支持使用 ...

  7. jquery学习(一)

    简单的jquery学习,首先在页面引入jquery <!-- 引入jquery --> <script src="js/jquery-1.8.3.js" type ...

  8. How to accept Track changes in Microsoft Word 2010?

    "Track changes" is wonderful and remarkable tool of Microsoft Word 2010. The feature allow ...

  9. 2016年中国微信小程序专题研究报告

    2016年12月29日,全球领先的移动互联网第三方数据挖掘和分析机构iiMedia Research(艾媒咨询)权威首发<2016年中国微信小程序专题研究报告>. 报告显示,82.6%手机 ...

  10. JavaScript中undefined与null的区别

    通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个undefined值.Javascript会自动将声明是没有进行初始化的变量设为undifined. 如果一个变量根本不存在会 ...