SpringBoot之Spring Data JPA入门学习2

本文介绍了如何使用SpringBoot的SpringDataJPA模块,通过@CreationTimestamp和@UpdateTimestamp注解自动管理实体的创建和更新时间。同时,展示了在更新数据时遇到的问题,以及如何通过自定义数据层操作避免不必要的字段清除。最后,文章还探讨了多种查询方法,包括按ID、用户名和模糊匹配的LIKE查询。
摘要由CSDN通过智能技术生成

我们继续使用上一章的环境。SpringBoot之Spring Data JPA入门学习

一、自动生成数据

我们修改一下实体 增加了几个注解:

@CreationTimestamp 自动生成创建时间。

@UpdateTimestamp 自动生成更新时间。

使用这两个注解我们还需要在类上加上两个注解@DynamicInsert和@DynamicUpdate

import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: 用户实体
 */
@Entity
@Table(name = "t_user")
@Data
@DynamicInsert
@DynamicUpdate
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 姓名
     */
    @Column(name = "name")
    private String name;

    /**
     * 年龄
     */
    @Column(name = "age")
    private Integer age;

    /**
     * 余额
     */
    @Column(name = "money")
    private BigDecimal money;

    /**
     * 是否删除
     */
    @Column(columnDefinition = "bit default 0 COMMENT '是否删除'")
    private Boolean deleted;


    /**
     * 创建时间
     */
    @Column(name = "create_at")
    @CreationTimestamp
    private Date createAt;

    /**
     * 更新时间
     */
    @Column(name = "update_at")
    @UpdateTimestamp
    private Date updateAt;
}

测试:

import com.example.quartzdemo.entity.User;
import com.example.quartzdemo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: JPA的使用
 */
@SpringBootTest
public class JpaTest {

    @Autowired
    private UserRepository userRepository;

    /**
     * 新增数据
     */
    @Test
    void test1() {
        User user = new User();
        user.setName("张三");
        user.setMoney(BigDecimal.TEN);
        user.setAge(20);
        userRepository.save(user);
    }
}

控制台显示sql执行语句

Hibernate: insert into t_user (age, create_at, money, name, update_at) values (?, ?, ?, ?, ?)

我们查看数据库,数据表自动生成了创建时间和更新时间,deleted字段使用了默认值。

我们修改数据,更新时间也相应的进行了修改

    /**
     * 修改数据
     */
    @Test
    void test4() {
        // 修改ID为1的数据
        User user = userRepository.findById(1L).get();
        user.setAge(21);
        userRepository.save(user);
    }
Hibernate: select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.create_at as create_a3_1_0_, user0_.deleted as deleted4_1_0_, user0_.money as money5_1_0_, user0_.name as name6_1_0_, user0_.update_at as update_a7_1_0_ from t_user user0_ where user0_.id=?
Hibernate: select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.create_at as create_a3_1_0_, user0_.deleted as deleted4_1_0_, user0_.money as money5_1_0_, user0_.name as name6_1_0_, user0_.update_at as update_a7_1_0_ from t_user user0_ where user0_.id=?
Hibernate: update t_user set age=?, update_at=? where id=?

二、数据修改

 如果我们不是通过先查询出数据,再修改对应值的情况,有可能会导致一些没有要修改的数据从有值变没有数值了,会导致出现想不到的结果。如果我们只想更新某个元素,而不是先查询数据再修改的情况,那么我们可以在数据层实现自定义的操作。

import com.example.quartzdemo.entity.User;
import com.example.quartzdemo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: JPA的使用
 */
@SpringBootTest
public class JpaTest {

    @Autowired
    private UserRepository userRepository;

    /**
     * 修改数据
     */
    @Test
    void test4() {
        // 修改ID为1的数据
        User user =  new User();
        user.setId(1L);
        user.setName(null);
        user.setAge(21);
        userRepository.save(user);
    }
}

如果我们只更新其他的一些数据,执行后我们查看数据库,一些原来的数据被清空掉了,这不是我们想要的结果。

Hibernate: select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.create_at as create_a3_1_0_, user0_.deleted as deleted4_1_0_, user0_.money as money5_1_0_, user0_.name as name6_1_0_, user0_.update_at as update_a7_1_0_ from t_user user0_ where user0_.id=?
Hibernate: update t_user set age=?, create_at=?, deleted=?, money=?, name=?, update_at=? where id=?

 我们在数据层创建自定义的操作方法

import com.example.quartzdemo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: 用户数据层
 */
public interface UserRepository extends JpaRepository<User, Long> {

    /**
     * 根据ID修改用户姓名和年龄
     *
     * @param name 姓名
     * @param age  年龄
     * @param id   ID
     */
    @Modifying
    @Query("update User u set u.name=?1,u.age=?2 where u.id=?3")
    void updateNameAndAgeById(String name, Integer age, Long id);

}

涉及到数据修改、删除操作,需要使用 @Modifying 注解。如果是查询就是要@Query注解书写语句就可以了。

  /**
     * 修改数据
     */
    @Test
    @Transactional
    @Rollback(value = false)
    void test4() {
        // 修改ID为1的数据
        userRepository.updateNameAndAgeById(null,21,1L);
    }
Hibernate: update t_user set name=?, age=? where id=?

 我们在数据库看到现在可以实现只更新某些元素了,其他元素没有受到影响。

三、多种查询方式

我们在使用查询的时候,批量插入多条测试数据

insert into t_user(id,name,age,money,deleted,create_at,update_at)
values
(1, '一qxblog',25,100, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(2, '一qx2',22, 200, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(3, '一qx3',23, 300, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(4, '一qx4',24, 400, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(5, '一qx5',28, 500, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(6, 'Batch 一qxblog',29, 100, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(7, 'Batch 一qxblog 2',30, 100, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(8, 'Batch 一qx 3',35, 200, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(9, 'Batch 一qx 4',45, 200, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(10, 'batch 一qx5',29, 1498, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:58'),
	(11, 'batch 一qx6',31, 1498, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:58'),
	(12, 'batch 一qx7',32, 400, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40'),
	(13, 'batch 一qx8',34, 400, 0, '2019-04-18 17:01:40', '2019-04-18 17:01:40');

1.根据ID查询

import com.example.quartzdemo.entity.User;
import com.example.quartzdemo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;


/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: JPA的使用
 */
@SpringBootTest
public class JpaTest {

    @Autowired
    private UserRepository userRepository;

    /**
     * 根据ID查询
     */
    @Test
    void test1(){
        Optional<User> userOptional = userRepository.findById(1L);
        // User(id=1, name=一qxblog, age=25, money=100.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0)
        System.out.println(userOptional.get());
    }

}

2.根据用户名查询

public interface UserRepository extends JpaRepository<User, Long> {

    /**
     * 根据用户名查询
     * @param name 用户名
     */
    User findByName(String name);

    /**
     * 根据用户名查询
     * @param name 用户名
     * @return
     */
    User queryByName(String name);

}
import com.example.quartzdemo.entity.User;
import com.example.quartzdemo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;


/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: JPA的使用
 */
@SpringBootTest
public class JpaTest {

    @Autowired
    private UserRepository userRepository;

    /**
     * 根据ID查询
     */
    @Test
    void test1() {
        User user1 = userRepository.queryByName("一qx2");
        // 输出User(id=2, name=一qx2, age=22, money=200.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0)
        System.out.println(user1);

        User user2 = userRepository.findByName("一qx2");
        // 输出User(id=2, name=一qx2, age=22, money=200.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0)
        System.out.println(user2);
    }

}

3.like查询

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

import java.util.List;

/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: 用户数据层
 */
public interface UserRepository extends JpaRepository<User, Long> {

    /**
     * 根据用户名查询
     * @param name 用户名
     */
    User findByName(String name);

    /**
     * 根据用户名查询
     * @param name 用户名
     * @return
     */
    User queryByName(String name);

    /**
     * 根据用户名模糊查询
     * @param name 用户名
     */
    List<User> findByNameLike(String name);

}
import com.example.quartzdemo.entity.User;
import com.example.quartzdemo.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;


/**
 * @author qinxun
 * @date 2023-06-07
 * @Descripion: JPA的使用
 */
@SpringBootTest
public class JpaTest {

    @Autowired
    private UserRepository userRepository;

    /**
     * 根据ID查询
     */
    @Test
    void test1() {
        List<User> userList = userRepository.findByNameLike("%qx%");
        System.out.println(userList);
    }

}

查询后返回

Hibernate: select user0_.id as id1_1_, user0_.age as age2_1_, user0_.create_at as create_a3_1_, user0_.deleted as deleted4_1_, user0_.money as money5_1_, user0_.name as name6_1_, user0_.update_at as update_a7_1_ from t_user user0_ where user0_.name like ? escape ?
[User(id=1, name=一qxblog, age=25, money=100.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=2, name=一qx2, age=22, money=200.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=3, name=一qx3, age=23, money=300.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=4, name=一qx4, age=24, money=400.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=5, name=一qx5, age=28, money=500.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=6, name=Batch 一qxblog, age=29, money=100.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=7, name=Batch 一qxblog 2, age=30, money=100.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=8, name=Batch 一qx 3, age=35, money=200.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=9, name=Batch 一qx 4, age=45, money=200.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=10, name=batch 一qx5, age=29, money=1498.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:58.0), User(id=11, name=batch 一qx6, age=31, money=1498.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:58.0), User(id=12, name=batch 一qx7, age=32, money=400.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0), User(id=13, name=batch 一qx8, age=34, money=400.00, deleted=false, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0)]

其他的一些常用的JPA用法

方法名说明等效sql
findByXxx表示根据列Xxx等于传参构建sqlwhere xxx= ?
findByXxxAndYyy根据多个列进行查询where xxx=? and yyy=?
findByXxxOrYyy根据多个列实现or查询where xxx=? or yyy=?
findByXxxLikelike查询,需要注意查询条件中加%where xxx like
findByXxxInin查询where Xxx in ()
findByXxxGreaterThan大于where xxx > ?
findByXxxGreaterThanEqual大于等于where xxx >= ?
findByXxxLessThan小于where xxx < ?
findByXxxLessThanEqual小于等于where xxx <= ?
findByXxxNot不等于where xxx != ?
findByXxxIsBetweenbetween查询where xxx between ? and ?
OrderByXxxDesc排序order by xxx desc
topN分页,表示获取最前面的n条limit n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinxun2008081

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值