Springboot版本为2.1.8.RELEASE

本文包含内容,怎么使用SpringBoot-JPA进行数据查询。不定期更新。

 

依赖

        <!--springboot 整合的数据连接-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <!--主角JPA-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--web框架用于页面测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

配置文件application.properties

# mysql 数据库连接
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://IP地址:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&autoReconnect=true
spring.datasource.username =用户名
spring.datasource.password =密码
spring.datasource.hikari.max-lifetime=120000

#
#如果数据库中没有这个表 则根据entity直接创建
Spring.jpa.hibernate.ddl-auto =update
Spring.jpa.show-sql =true

spring.main.allow-bean-definition-overriding=true

怎么使用jpa


创建一个entity实体类。    new entity.Student

在类上标识@Entity 表名这是一个Entity类         @Table(name="数据库中对应的表名")

对于属性:  主键给@Id 表名这是一个主键            @GeneratedValue(stratefy=GenerationType.IDENTITY)设置自增策略为自动

注意Entity一定需要一个空的构造方法,不然springboot没法创建这个类。(源码为反射的无参构造,clazz.newInstance();)。

其余属性可以给@Column,包含长短、表结构中对应的列名等等。

  

 

 

package com.huangyichun.jpalearn.entity;

import javax.persistence.*;

@Entity
@Table(name = "user") // 不配置为驼峰
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column
    private String name;
    private Integer old;

    public Student() {
    }

    public Student(String name, Integer old) {
        this.name = name;
        this.old = old;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", old=" + old +
                '}';
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getOld() {
        return old;
    }

    public void setOld(Integer old) {
        this.old = old;
    }
}

创建repository.StudentRepository.interface extends JpaRepository<Student, Integer>   

关注JpaRepository<对应的类, 类中主键的类型>

创建就已经完毕。


在使用处,比如直接在controller中

    @Autowired
    StudentRepository studentRepository;


    @ResponseBody
    @RequestMapping("/")
    public String root(){
        Student student= new Student("姓名", 年龄);
        studentRepository.save(student);
        System.out.println(student.toString());
        return student.toString();
    }

    @ResponseBody
    @RequestMapping("/delete/{id}")
    public String delete(@PathVariable Integer id){
        Optional<Student> s = studentRepository.findById(id);
        studentRepository.deleteById(id);
        return s.get().toString() + "已经被删除";
    }

    @ResponseBody
    @RequestMapping("/update/{id}/{name}")
    public String update(@PathVariable Integer id, @PathVariable String name){
        /*获取以后,再重新赋值 其实有其他更好的办法*/
        Student student = studentRepository.findById(id).get();
        student.setName(name);
        studentRepository.save(student);
        return student.toString();
    }

    @ResponseBody
    @RequestMapping("/{id}")
    public String find(@PathVariable Integer id){

        Optional<Student> s = studentRepository.findById(id);

        return s.get().toString();
    }

以上分别对应增删改查。

用到的指令也就只有 .save() / .deleteById() / .findById()


为什么我们什么sql语句都没有写就能实现这些呢?

原因是jpa已经帮我们定制了这些方法。查看JpaRepository接口

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

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

    List<T> findAll(Sort var1);

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

    <S extends T> List<S> saveAll(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);
}

可以看到,已经帮我们定制了一些最常用的方法,但是,你会发现并没有实现的类。为什么在接口里面定义了方法就能使用呢?

反射,利用定义的方法名,来生成sql语句。这里原理不扯远,我们只谈使用方法。

以上的方法不够用怎么办?在我们自己定义的StudentRepository中自己定义方法即可。

public interface StudentRepository extends JpaRepository<Student, Integer> {

    public Optional<Student> findById(Integer id);
    
    public List<Student> findByOld(Integer old);

    @Query(nativeQuery = true, value = "select * from user where id=?1")
    public Optional<Student> findById2(Integer id);
}

注意点:

  • 怎么定义名字:如果是查询的话直接find,如果要添加条件By什么条件Id
  • 如果能确认返回值只有一个或者0个,推荐使用Optional包装返回的Entity
  • 如果返回值可能有多个,则需要List来封装
  • 为什么有个方法上面添加了@Query?  这个是用来定义一些自己的参数 比如查询的sql是什么等等,感兴趣直接看他源码就知道了。

 

GitHub 加速计划 / sp / spring-boot
39
7
下载
spring-projects/spring-boot: 是一个用于简化Spring应用开发的框架。适合用于需要快速开发企业级Java应用的项目。特点是可以提供自动配置、独立运行和内置的Tomcat服务器,简化Spring应用的构建和部署。
最近提交(Master分支:2 个月前 )
bd5264e2 Closes gh-48219 14 小时前
d4408ab9 * pr/48169: Polish "Revise "Use Liquibase for test-only migrations" section" Revise "Use Liquibase for test-only migrations" section Closes gh-48169 14 小时前
Logo

新一代开源开发者平台 GitCode,通过集成代码托管服务、代码仓库以及可信赖的开源组件库,让开发者可以在云端进行代码托管和开发。旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐