本章完成数据列表显示功能

ORM 和 JPA

ORM (Object Relation Mapping) 是对象/关系映射,它将数据库中的表
和内存中的对象建立映射关系。

对象和关系型数据是业务实体的两种表现形式。
业务实体在内存中表现为对象,在数据库中表现为关系型数据。
内存中的对象不会被永久保存,关系型数据库中的对象会被永久保存。

JPA 概念

  • JPA (Java Persistence API) 是一种 Java 持久化 API,用于对象的持久化,是一种非常强大的 ORM 解决方案。
  • JPA 通过简单约定好接口方法的规则自动生成相应的 JPQL 语句,然后映射成 POJO 对象。

JPA 基本用法

数据库启动有问题的见本人另一篇博客!
启动MySQL:net start mysql出现问题+本地Mysql忘记密码的修改方法

  1. 准备工作
  • 新建 Spring Boot 项目:jpademo
  • 添加相关依赖:
  • pom.xml
<!-- Spring Data 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>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
  • 添加完依赖,要重启IDEA

  • 数据库连接配置(这个很重要!)

  • 在 application.properties 添加数据库连接配置:(username和password记得填自己的!推荐全写root,好记!)

#自动生成数据库表(关键)update表示更新或者创建数据表结构(首次)
spring.jpa.hibernate.ddl-auto=update
#mysql数据库连接配置(非常重要)
#端口号,数据库名,时区信息
spring.datasource.url = jdbc:mysql://localhost:3306/testdb?serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = root
#mysql数据库驱动程序(重要)
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
#jpa配置:在控制台显示Hibernate的sql(可选)
spring.jpa.show-sql = true
#其他配置:关闭Thymeleaf 的缓存
spring.thymeleaf.cache = false
  • 运行项目,自动生成表。
  • 图中是Navicat和MySQL Workbench两个的界面,别看混了。
  • (因为我的老师使用的是MySQL Workbench,但是我比较喜欢用Navicat,所以就都用了试下。)
  • 怎么看?见本人另外一篇博客:MySQL新建数据库+用Navcat查看MySQL的方法

  1. 创建实体类
    在 entity 包中新建 User 类:用于映射数据库表
  • user.java
  • 自己敲的时候的顺序:
    先写以下内容:
import javax.persistence.*;
import java.util.Date;

@Entity //声明类为实体类,不能掉!
public class User implements Serializable {
   

private Long id; // Long 对应MySQL数据库 bigint 类型

private String username;

private String password;

private Date regdate; // Date 对应MySQL数据库 datetime 类型

private int status;
// getter/setter
}
  • 再加上注解(就是@的内容)
  • 再加上getter和setter
  • (不会还有人手动敲吧?不会还不会generate吧?)

  • 这里要按住shift全选
  • 点击ok,自动生成getter
  • setter同理~
  • 完成后的代码:
package com.example.demo.entity;

import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Entity
public class User implements Serializable {
   
    @Id //表示该属性作为表的主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//设定主键生成策略:IDENTITY表示由数据库自动生成
    private Long id;// Long 对应MySQL数据库 bigint 类型

    @Column(nullable = false,unique = true,length = 20)//列字段,非空且唯一,字符最大长度20
    private String username;

    @Column(nullable = false,length = 20)//列字段,非空,字符最大长度20
    private String password;

    @Column(nullable = false)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//声明日期格式
    private Date regdate;// Date 对应MySQL数据库 datetime 类型

    @Column(nullable = false)
    private int status;//状态:0是离线,1是在线,等。

    public Long getId() {
   
        return id;
    }

    public String getUsername() {
   
        return username;
    }

    public String getPassword() {
   
        return password;
    }

    public Date getRegdate() {
   
        return regdate;
    }

    public int getStatus() {
   
        return status;
    }

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

    public void setUsername(String username) {
   
        this.username = username;
    }

    public void setPassword(String password) {
   
        this.password = password;
    }

    public void setRegdate(Date regdate) {
   
        this.regdate = regdate;
    }

    public void setStatus(int status) {
   
        this.status = status;
    }
}
  • 添加记录:

    如果用的是MySQL Workbench:


  1. 创建数据接口访问层(repository仓库)
  • JPA 提供了操作数据库的接口。在开发过程中继承和使用这些接口,可
    简化持久化开发工作。
  • Spring能够找到自定义接口,并生成代理类,在开发过程中可以不写相
    关SQL操作,由代理类自动生成。
  • JPA接口:JpaRepository

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>
其中:T表示实体类,ID表示主键类型,ID必须实现序列化

创建过程:repository仓库

  • 新建 repository 包,并新建接口:UserRepository(仓库接口)
  • 该接口要 extends JpaRepository<User, Long> 接口(User:实体模型类,Long:主键类型)


UserRepository.java

package com.example.demo.repository;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
   
// JpaRepository 自动实现了很多内置的CURD方法 (厉害啊!)
// 这些方法以后可直接调用,例如:
// List<T> findAll();
// Optional<T> findById(id);
// User save(user);
// void delete(user);
// void deleteById(id);
// long count();
// boolean existsById(id);
}

  1. 调用Repository完成业务控制
  • 在 controller 包中新建 UserController 控制器。

  • 代码顺序还是和上文介绍的一样,不复制粘贴总是有好处的~

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
   
    //@Autowired:自动注入,即对象只需声明,不用new就能使用(Spring IoC技术体现,厉害呀!)
    @Autowired
    UserRepository userRepository;

    @RequestMapping("/get/{id}")
    public User getUserById(@PathVariable Long id){
   
        //Repository内置的方法,可直接使用,根据 id 查找对象
        //注:findById(id)返回的是Optional类(一个可以为null的容器对象),如果对象存在则调用get()方法返回该对象
        User user =userRepository.findById(id).get();
        return user;
    }

    @RequestMapping("/list")
    public List<User> list(){
   
        //Repository内置的方法,可直接使用,查找所有对象
        List<User> users = userRepository.findAll();
        return users;
    }
}
  • 请求试试
    http://localhost:8080/get/1

    在postman中测试:

http://localhost:8080/list