SpringBoot入门(IDEA篇)(三)

一、什么是JPA

  JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate、TopLink等。

二、Mysql数据库示例

  1、在application.yml文件中增加数据库访问的配置

  

  ddl-auto:可选属性有以下几种。

  

  create   每次创建一个新表,那么之前表中的数据都会丢掉

  update  表不存在的时候才会建立新表,如果存在则不会新建,所以原有数据不会丢

  create-drop  每次新建一个表,而且服务停掉,那么所建立的表会随之删除

  none   见名知意,就是什么都不做,不会给帮你建表,只能使用现有的表

  validate  会将实体类和表进行一个验证,如果不一致会报错

  2、新建实体类

  

package com.zmfx.jpa;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;


@Entity
public class Dog {
    /*
        如果这些注解所在的包,javax.persistence不能导入。可能是缺少依赖
        可以在pom中加入Javax Persistence API 的依赖
     */
    @Id
    @GeneratedValue
    private Integer id;//编号
    private Integer age;//年龄
    private String name;//名字

    public Dog() {
    }

    public Dog(Integer id, Integer age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

  3、编写Repository接口类

    这里需要继承JpaRepository这个类,这样我们就可以使用底层帮我们实现好的一些代码

    相当于我们之前了解到的持久层(数据访问层),用于获取数据库中的数据。

  4、编写Serivce层

    按照策略模式,我们应当一个接口,然后对应实现类。由于这里业务比较简单,我们就不那么费事了。可能这层我在下面都不写。

  5、编写Controller层

    根据访问信息,进行相应的业务处理,页面展示。

三、RestFul API

  1、查询所有,findAll()方法的使用。GET请求

    Repository接口类

package com.zmfx.jpa;

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

/**
 * 这个接口需要继承一个接口JpaRepository
 * 这样就可以使用底层为我们编写好的一些通用方法
 */
public interface DogRepository extends JpaRepository<Dog,Integer> {
}

    Controller层

package com.zmfx.jpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 控制层
 */
@RestController
public class DogController {
    //因为业务太简单,所有我们省略service层,直接调用数据访问层的代码
    @Autowired
    private DogRepository dogRepository;
    /**
     * 查询所有女生列表
     * @return
     */
    @GetMapping(value="/dogs")
    public List<Dog> dogList(){
        return dogRepository.findAll();//findAll()方法是底层帮我没实现好的
    }
}

  这里推荐一个软件PostMan,可以模拟前端的http访问,可以不用编写页面

 2、根据id查询一条记录,findById()的使用,GET请求

   在controller中新加以下代码

 /**
     * 根据id查询指定的Dog
     * @param id
     * @return
     */
    @GetMapping(value = "/dog/{id}")
    public Optional<Dog> findDogById(@PathVariable("id") Integer id){
        return dogRepository.findById(id);//注意这个方法的返回值
    }

然后,使用PostMan进行访问,展示如下:

  

 3、添加一个Dog,save()方法的使用,POST请求

  controller层中新加以下代码

 /**
     * 添加一个Dog
     * @param age
     * @param name
     * @return
     */
    @PostMapping(value = "/addDog")
    public Dog addDog(@RequestParam("age") Integer age,
                      @RequestParam("name") String name){
        Dog dog=new Dog();
        dog.setAge(age);
        dog.setName(name);
        return dogRepository.save(dog);
    }

然后用PostMan进行访问,展示效果如下:

 4、更新dog的信息,save()方法的使用,Put请求

  在controller增加下面代码

/**
     * 更新Dog信息
     * @param id
     * @param age
     * @param name
     * @return
     */
    @PutMapping(value = "updateDog/{id}")
    public Dog updateDog(@PathVariable("id") Integer id,
                         @RequestParam("age") Integer age,
                         @RequestParam("name") String name){
        Dog dog=new Dog();
        dog.setId(id);
        dog.setName(name);
        dog.setAge(age);
        System.out.println(dog);
        return dogRepository.save(dog);//注意这里使用save()方法,根据主键,所以主键不能更改
    }

  这里使用PostMan的PUT请求,注意使用x-www-form-urlencoded进行传参

  访问后的效果应当如下:

 5、删除一条记录,deleteById()方法,DELETE请求

  controller中加入以下代码:

/**
     * 删除一条记录
     * @param id
     */
    @DeleteMapping(value = "/del/{id}")
    public void delDogById(@PathVariable("id") Integer id){
        dogRepository.deleteById(id);
    }

  PostMan中使用DELETTE请求,因为没有返回值,所以需要到数据库中查看效果

  6、根据年龄来查询,自己在Repository中定义

  DogRepository中变为

package com.zmfx.jpa;

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

import java.util.List;

/**
 * 这个接口需要继承一个接口JpaRepository
 * 这样就可以使用底层为我们编写好的一些通用方法
 */
public interface DogRepository extends JpaRepository<Dog,Integer> {
    //通过年龄来查询
    List<Dog>  findByAge(Integer age);//注意方法名的格式,findBy+属性名。

}

  Controller中新增代码

/**
     * 根据年龄来查询
     */
    @GetMapping(value = "/dogs/{age}")
    public List<Dog> dogList(@PathVariable("age")Integer age){
        return dogRepository.findByAge(age);
    }

  然后使用PostMan进行访问,展示如下:

  

 四、事务管理

  1、加入事务之前

  controller层加入代码

//这里涉及到事务,所以我们加入service的依赖
    @Autowired
    private DogService dogService;
    /**
     * 事务测试的方法
     */
    @GetMapping(value = "/dogs/tx")
    public void txTest(){
        System.out.println("进入了controller");
        dogService.addTwoDog();
    }

  service层代码,这里用到了事务,所以要新建一个DogService类

package com.zmfx.jpa;

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

@Service
public class DogService {
    @Autowired
    private DogRepository dogRepository;
    /**
     * 同时添加两条记录
     */
    public void addTwoDog(){
        //模拟两条数据
        Dog dog1=new Dog();
        dog1.setAge(2);
        dog1.setName("小黑1");
        //模拟第二条数据
        Dog dog2=new Dog();
        dog2.setAge(2);
        dog2.setName("小黑2");
        System.out.println("进入了service");
        //将数据插入到数据库
        dogRepository.save(dog1);
        System.out.println(5/0);//模拟异常
        dogRepository.save(dog2);
    }
}

  然后使用 http://127.0.0.1:8083/dev/dogs/tx 进行访问,我们发现后台抛出异常,但是数据库还是添加了第一条的记录。

  

 2、加入事务之后

  我们就能够让小黑1 和 小黑2 同生共死了。

  其它的都不变,然后再需要添加事务的方法上,添加一个@Transactional注解。也就是service的 public void addTwoDog()上加入注解

  

package com.zmfx.jpa;

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

@Service
public class DogService {
    @Autowired
    private DogRepository dogRepository;
    /**
     * 同时添加两条记录
     */
    @Transactional  //加入事务控制
    public void addTwoDog(){
        //模拟两条数据
        Dog dog1=new Dog();
        dog1.setAge(2);
        dog1.setName("小黑1");
        //模拟第二条数据
        Dog dog2=new Dog();
        dog2.setAge(2);
        dog2.setName("小黑2");
        System.out.println("进入了service");
        //将数据插入到数据库
        dogRepository.save(dog1);
        System.out.println(5/0);//模拟异常
        dogRepository.save(dog2);
    }
}

  然后删除数据库中,小黑1这条记录,重启springboot服务,再次访问 http://127.0.0.1:8083/dev/dogs/tx 。

  还是那个异常,然后去看数据库,发现两条记录都没有添加进来。事务控制添加成功。

   

原文地址:https://www.cnblogs.com/zmfx/p/9020514.html