天天看点

Spring Boot(二):整合 JPA 及 事务控制

一、什么是JPA?

JPA(Java Persistence API) Java 持久层API,是JDK5.0注解或XML描述 对象-关系表的映射关系,并将运行期内的实体对象持久化到数据库中。

JPA的总体思想和现有Hibernate、TopLink、Jdo等ORM框架大体一致,总的来说,JPA 包括以下3方面的技术:

1、ORM映射元数据

JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;

2、API

用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。

3、查询语言

这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

二、环境搭建流程

1、创建工程的时候,添加JPA 的依赖;或者在pom.xml文件中添加

<!--jpa  依赖-->
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-data-jpa </artifactId>
</dependency>

<!--mysql 依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.5</version>
</dependency>

<!--hibernate 依赖-->
<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.0-api</artifactId>
    <version>1.0.1.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.0.7.Final</version>
</dependency>
           

2、配置数据源,在application.yml 文件中 添加

server:
    port: 
    context-path: /Boot


spring:
    profiles:
        active: dev #可设置使用哪个配置文件

datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://:/user_boot?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    username: root
    password: root

jpa:
    hibernate:
        ddl-auto: update
    show-sql: true
           

hibernate 自动减表方式有五个 (前提要把数据库建好):

update:表示自动根据model对象来更新表结构,启动 hibernate 时会自动检查数据库,如果缺少表则自动建表;缺少列则自动添加列;

create: 启动hibernate时,自动删除原来的表,新建所有的表,所以每次启动后的以前数据都会丢失。

create-drop:应用停下来的时候,自动会把表和数据删掉、

none: 什么也不做;

validate:会验证类里的属性和表字段是否一致,不一致,则会报错;

3、实体映射 entity类

@Entity   //注解的包 都是引用的 javax.persistence 下的
public class User {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    @Min(value = , message = "禁止添加未成年人员!")
    private String age;

    @NotNull(message = "金额必传")
    private Double money;

getter()  setter()   toString()

}
           

@Enitty 表明是一个映射的实体类

@Id 表名字段id

@GeneratedValue 字段自动生成

属性名字和表字段是一致的。

4、接口访问 dao 层

/**
* Created by Advancer on 2017/12/29 10:41.
* auth: lbh
*/
public interface UserRepository extends JpaRepository<User, Integer> {

    //通过年龄来查询数据
    public List<User> findUserByAge(String age);

}
           

直接继承 JpaRepository 接口就可以了,里面内置了一些简单的CRUD操作,也可自定义,查看源码

@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();

List<T> findAll(Sort var1);

List<T> findAll(Iterable<ID> var1);

<S extends T> List<S> save(Iterable<S> var1);

void flush();

<S extends T> S saveAndFlush(S var1);

void deleteInBatch(Iterable<T> var1);

void deleteAllInBatch();

T getOne(ID var1);

<S extends T> List<S> findAll(Example<S> var1);

<S extends T> List<S> findAll(Example<S> var1, Sort var2);
}
           

5、测试数据 controller层

package com.lbh.Controller;

import com.lbh.Dao.UserRepository;
import com.lbh.Service.UserService;
import com.lbh.entity.User;
import com.lbh.util.ResultUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
* Created by Advancer on 2017/12/29 10:36.
* auth: lbh
*/
@RestController
@RequestMapping("/user")
public class UserController {

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

        @Autowired
        private UserRepository userRepository;

        @Autowired
        private UserService userService;

        /**
        * 查询用户的全部列表
        * @return
        */
        @GetMapping(value = "/getUsers")
        public List<User> getUserList(){
            logger.info("getUserList()");
            return userRepository.findAll();
        }

        /**
        * 新增一条记录
        * @param user
        * @return
        */
        @PostMapping(value = "/addUser")
        public Object addUser(@Valid User user, BindingResult bindingResult){
            if (bindingResult.hasErrors()){
            return ResultUtils.error(, bindingResult.getFieldError().getDefaultMessage());
        }
            user.setAge(user.getAge());
            user.setMoney(user.getMoney());

            return ResultUtils.success(userRepository.save(user));
        }

        /**
        * 查询一个用户
        * @param id
        * @return
        */
        @GetMapping(value = "/getUser/{id}")
        public User findUserById(@PathVariable("id") Integer id){
            return userRepository.findOne(id);
        }

        /**
        * 更新一个用户
        * @param id
            * @param name
        * @param age
        * @return
        */
        @PutMapping(value = "/updUser/{id}")
        public User updUser(@PathVariable("id") Integer id,
                                            @RequestParam("name") String name,
                                            @RequestParam("age") String age){
                User user = new User();
                user.setId(id);
                user.setName(name);
                user.setAge(age);
            return userRepository.save(user);
}

            /**
            * 删除用户
            * @param id
            */
            @DeleteMapping(value = "/delUser/{id}")
            public void delUser(@PathVariable("id") Integer id){
                userRepository.delete(id);
            }

            /**
            * 通过年龄来查询用户
            * @param age
            * @return
            */
        @GetMapping(value = "/findUserByAge/{age}")
        public List<User> findUserByAge(@PathVariable("age") String age){
                return userRepository.findUserByAge(age);
        }

            /**
                * 事务测试 写入两条数据
            */
        @PostMapping("/insertUserTwo")
        public void insertUserTwo(){
            userService.insertUsers();
        }

        /**
        * 根据id 查年龄
        * @param id
        */
        @GetMapping("/getAge/{id}")
        public void getAge(@PathVariable("id") Integer id) throws Exception {
                userService.getAge(id);
         }

}
           

获取数据测试效果:

Spring Boot(二):整合 JPA 及 事务控制

三、事务控制

springboot开启事务很简单,只需要一个注解@Transactional 就可以了。因为在springboot中已经默认对jpa、jdbc、mybatis开启了事事务,引入它们依赖的时候,事物就默认开启。当然,如果你需要用其他的orm,比如beatlsql,就需要自己配置相关的事物管理器。

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional(rollbackFor = Exception.class)
    public void insertUsers(){
        User user = new User();
        user.setAge("24");
        user.setName("jkj");
        userRepository.save(user);

        User user1 = new User();
        user1.setAge("24");
        user1.setName("wyy");
        userRepository.save(user1);
    }
}
           

继续阅读