spring-boot-starter-data-jpa 的使用。

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是什么等等,感兴趣直接看他源码就知道了。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值