文章目录

  • 一、自增操作
  • 1.数据库中的表是自增的
  • 2.Entity类的annatation和setter、getter方法
  • 3.Service
  • (1)saveAndFlush
  • (2)为何自增的id是非null
  • 二、删除操作
  • 1.service
  • 三、查找操作
  • 1.根据主键查找
  • 2.获取所有
  • 3.自定义查找
  • (1)按规则
  • 四、更新操作
  • 1.service
  • 2.saveAndFlush()机制
  • 五、自定义查询
  • 1.不传入参数
  • 2.指定静态参数
  • 3.传入动态参数
  • Reference



  • Model:User
  • DAO:UserDAO接口(继承JpaRepository<User, Integer>)
    只用写关于查找的自定义操作。
  • Service:UserService
    基本调用DAO的默认继承方法就行。


一、自增操作

1.数据库中的表是自增的

AI表示Auto Increme

jpa自定义StatementInspector_User

2.Entity类的annatation和setter、getter方法

  1. 关键是@GeneratedValue(strategy = GenerationType.IDENTITY)的声明,表示自增。如果没用这个的话,saveAndFlush()返回的对象中是不会获得自增的值的。
  2. setter、getter方法也是必须的。
  3. 其他基本的也得ok@Entity@Id@Column(name = "userid")
package com.sand.alphon.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import jdk.nashorn.internal.objects.annotations.Getter;

import javax.persistence.*;

@Entity
public class User {
    @Id
    @Column(name = "userid")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;

    private String password;

    private String name;

    private int sex;

    private int age;

    private String email;

    @Column(name = "phonenum")
    private String phoneNum;

    private String type;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

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

    public String getName() {
        return name;
    }

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

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

3.Service

不需要在DAO中写,默认生成的方法saveAndFlush()就好。

@Service
public class UserService {
    @Autowired
    UserDAO userDAO;

    /*
     * 增
     * 因为是不指定userId,而是自增,所以不检查存在与否
     * 使用save()不能获得新增的主键userId,因为没真正提交,要使用saveAndFlush
     */
    public User add(User user){
        return userDAO.saveAndFlush(user);
    }
}

(1)saveAndFlush

区别:

  • 使用saveAndFlush():此命令中的更改将立即刷新到DB。
  • 使用save():不一定了,它可能只暂时保留在内存中,直到发出flush或commit命令。

所以:

  • 使用saveAndFlush()方法就可以立即获取到这条数据的自增id
  • 使用save()方法,你不flush()或者commit,你得数据是暂时只在内存中保存,所以此时这条数据是没有主键id的。

(2)为何自增的id是非null

这样我在调用的时候,不用传userId,调用自增后就能获得自增的userId。(其实默认实例化后是0,但userId是主键非null,所以数据库判断后帮助我们自增一个非null 的useId。)

User user = new User();
user.setName(map.get("name").toString());
user.setPassword(map.get("password").toString());
user.setEmail(map.get("email").toString());
user.setPhoneNum(map.get("phonenum").toString());
user.setSex((int)Double.parseDouble(map.get("sex").toString()));
user.setAge((int)Double.parseDouble(map.get("age").toString()));
user.setType("reader");
// System.out.println(user.getUserId());	// 其实是0

User resultUser = userService.add(user);
System.out.println(resultUser.getUserId());

jpa自定义StatementInspector_主键_02

二、删除操作

1.service

直接用默认的deleteByXXX()existsByXXX()

/*
 * 删
 * 先返回存在与否(不存在就是删除失败),然后删除
 */
public boolean delete(int userId){
    // 表示没有,你删错了
    if(!userDAO.existsById(userId)){
        return false;
    }
    userDAO.deleteById(userId);
    return true;
}

三、查找操作

1.根据主键查找

如果只用根据主键查找的话,不用DAO中写东西。
因为有默认的查找主键的方法,findById()

这个函数返回一个容器Optional对象。
optional.orElse(null)的意思是:

  • 如果要查找的userId存在,则返回对应的User对象;
  • 如果不存在,则返回orElse()中的东西,我这里让返回null

代码:

  • Service:
/*
 * 查
 * 返回User类
 */
public User findByUserId(User user){
    return userDAO.findById(user.getUserId()).orElse(null);
}

2.获取所有

不用DAO中写东西,用默认的findAll()

userDAO.findAll()

3.自定义查找

(1)按规则

jpa自定义StatementInspector_自增_03


按照findByXXX,组合列名和逻辑旧行了,都不用实现。比如,

public interface UserDAO extends JpaRepository<User,Integer> {
    // 根据userName查找
    List<User> findAllByName(String name);

    // 根据userId和name一起查找都符合的
    User findByUserIdAndName(int userId,String name);	
}

jpa自定义StatementInspector_主键_04

四、更新操作

1.service

直接用默认的existsByXXX()saveAndFlush()

/*
 * 改
 * saveAndFlush()本来就能做到不存在插入新的,存在更新旧的。
 * 我们只想更新一个旧值,而不是整一个新的输错的值。
 */
public boolean edit(User user){
    if(userDAO.existsById(user.getUserId())){
        userDAO.saveAndFlush(user);
        return true;
    }else {
        return false;
    }
}

2.saveAndFlush()机制

我们之所以不直接使用saveAndFlush(),是因为它的机制:

  • 如果没有这个userId,即要插入新记录:那么就会调用DB的insert语句
  • 如果已有这个userId,即要更新旧记录:那么就会调用DB的update语句

所以,先判断userId存在吗,再决定更新。

五、自定义查询

1.不传入参数

@Query(value = "select * from book",nativeQuery = true)
List<String> myFindCategory();

函数名不要和默认函数重复。
两个:value是sql语句和nativeQuery=true表示使用sql原生语句

2.指定静态参数

@Query(value = "select * from book where book.bookname = '高数1'", nativeQuery = true)
List<Book> findAllByBookName(String bookName);

将其值用''包括起来。

3.传入动态参数

@Query(value = "select * from book where bookid = ?1",nativeQuery = true)
List<String> myFindCategory(int bookid);

?1就是函数传进来的第一个参数,以此类推?2……