# 数据库操作

Spring-Data-Jpa:Spring 对 Hibernate 的整合(一脸懵(反正很牛逼就是了

实例(mysql):

# RESTful API 设计

原实例过于 hentai 所以改了一些内容 qwq

只能用一堆智乃了.. 不过到底有多少只智乃..(心爱叔狂喜 < img src="https://z3.ax1x.com/2021/06/27/RYCBmn.jpg" width="50px">

请求类型请求路径功能
GET/chino获取智乃列表
POST/chino创建新的智乃
GET/chino/id通过 id 查询智乃
PUT/chino/id通过 id 更新智乃
DELETE/chino/id通过 id 删除智乃

# 配置

pom.xml 添加依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

application.yml

spring:
  profiles:
    active: dev #dev 里边就写了个 localhost8080
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/chino
    username: root
    password: chino1204
  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true

配置完毕,创建数据库 chino,启动成功。

# 新建表

新建一个 java 类,命名为 chino,随便写点属性

package com.example.demo1;
import javax.persistence.Entity;
import javax.persistence.criteria.CriteriaBuilder;
@Entity // 表示这个类对应数据库里的一个表
public class chino {
    private Integer id;
    private String husband;
    private Integer height;
}

跑一下,进数据库瞧瞧自动创建了一张表 Chino。

手动插一条数据,再跑一遍程序,进数据库瞧瞧刚刚的数据没了 QAQ

Application.yml:

jpa:
    hibernate:
      ddl-auto: create
      create 换成 update
属性操作
create覆盖创建
create-drop程序运行结束后会自动删除表
update更新(不会清除数据)
none啥都不做
validate验证表结构,与类不同则报错

# Controller

新增接口 ChinoRepository.java:

package com.example.demo1;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ChinoRepository extends JpaRepository<Chino, Integer> {
}

ChinoController.java:

package com.example.demo1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class ChinoController {
    @Autowired
    ChinoRepository chinoRepository;
    /**
     * 获取智乃列表
     * @return
     */
    @GetMapping(value = "/chino")
    public List<Chino> chinoList() {
        return chinoRepository.findAll();
    }
    /**
     * 添加一只新的智乃
     * @param height
     * @param husband
     * @return
     */
    @PostMapping(value="/chino")
    public Chino addChino(@RequestParam() Integer height,
                          @RequestParam(required = false, defaultValue = "Cocoa") String husband) {
        Chino chino = new Chino();
        chino.setHeight(height);
        chino.setHusband(husband);
        return chinoRepository.save(chino);
    }
    /**
     * 根据 id 获取单只智乃信息
     * @param id
     * @return
     */
    @GetMapping(value = "/chino/{id}")
    public Chino getChinoById(@PathVariable("id") Integer id) {
        return chinoRepository.findById(id).orElse(null); // 为 null 就用 orElse 里的值(虽然还是写的 null..hhh..
    }
    /**
     * 根据 id 修改智乃信息
     * @param id
     * @param height
     * @param husband
     * @return
     */
    @PostMapping(value = "/chino/{id}")
    public Chino updateChino(@PathVariable("id") Integer id,
                            @RequestParam() Integer height,
                            @RequestParam(required = false) String husband) {
        Chino chino = chinoRepository.findById(id).orElse(null);;
        chino.setHeight(height);
        if (husband != null)
            chino.setHusband(husband);
        return chinoRepository.save(chino);
    }
    /**
     * 根据 id 删除智乃 (>_<)
     * @param id
     */
    @DeleteMapping(value = "/chino/{id}")
    public void deleteChino(@PathVariable(value = "id") Integer id) {
        chinoRepository.deleteById(id);
    }
}

扩展 - 通过 height 查询智乃:

接口中加入方法定义 ChinoRepository.java:

public interface ChinoRepository extends JpaRepository<Chino, Integer> {
    // 通过 height 查询,这里方法名必须是这样的
    public List<Chino> findByHeight(Integer height);
}

Controller 中添加:

/**
 * 根据 height 获取智乃信息
 * @param height
 * @return
 */
@GetMapping(value = "/chino/height/{height}")
public List<Chino> getChinoByHeight(@PathVariable("height") Integer height) {
    return chinoRepository.findByHeight(height);
}

# 事务管理

没学过数据库在这里瞎搞无所畏惧

举例,做一个电商平台,购买时要同时扣掉用户的钱和商家的库存,希望两者同时扣掉。其中一者扣除失败的话,希望另一者也不要被扣除。

实例:同时插入两个智乃。<img src="https://z3.ax1x.com/2021/06/27/RYCBmn.jpg" width="50px">

新建 ChinoService 类 ChinoService.java:

package com.example.demo1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ChinoService {
    @Autowired
    private ChinoRepository chinoRepository;
    public void insertTwoChino() {
        Chino chino1 = new Chino(), chino2 = new Chino();
        chino1.setHeight(144);
        chino1.setHusband("Cocoa");
        chinoRepository.save(chino1);
        chino2.setHeight(145);
        chino2.setHusband("Hoto Cocoa");
        chinoRepository.save(chino2);
    }
}

ChinoController 类中添加内容:

@Autowired
ChinoService chinoService;
@PostMapping(value="/chino/two")
public void addTwoChino() {
    chinoService.insertTwoChino();
}

运行,POST 一下 "localhost:8080/chino/two" 成功插入。

故意使其中一条(第二条)插入失败,修改数据库中 husband 字段长度限制为 9。

然后 insertTwoChino 方法前加注解:

@Transactional
public void insertTwoChino() {...}

测试没有插入任何一条数据(顺带一提 id 还是会自增的(并且增加了 2))。