• 玩转spring boot——结合JPA事务


     接着上篇

    一、准备工作


    修改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>
    View Code

    上篇的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系列目录

  • 相关阅读:
    Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
    BZOJ 1293 SCOI2009 生日礼物 堆
    Git小玩
    VM tools安装错误The path &quot;&quot; is not a valid path to the xx generic kernel headers.
    css hover对其包括的元素进行样式设置
    C#高级编程---暂停计划
    如何配置和使用Tomcat访问日志
    关于性能测试应该知道的一些事(转载)
    Linux 平台如何查看某个进程的线程数?
    《让LoadRunner走下神坛》
  • 原文地址:https://www.cnblogs.com/GoodHelper/p/6242957.html
Copyright © 2020-2023  润新知