JPA入门,Spring Boot 整合 JPA 操作数据库

知了小站
2022-06-01 / 0 评论 / 561 阅读

简单了解

Jpa(java Persistence API,java持久化 api),它定义了对象关系映射(ORM)以及实体对象持久化的标准接口。在 Spring boot中 JPA 是依靠 Hibernate才得以实现对的,Hibernate 在 3.2 版本中对 JPA 的实现有了完全的支持。
Spring Boot 整合 JPA 可使开发者用极简的代码实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!

添加依赖

#这里添加 Jpa 和 Mysql 的依赖
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

开发Jpa

编写实体类

定义用户实体类 User

//@Entity 表明这个是一个实体类
@Entity
//指定表名
@Table(name = "user")
public class User {

    /**
     * 表明这个字段是主键,并且ID是自增的
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 这样则表示该属性,在数据库中的名称是 username,并且使唯一的且不能为空的
     */
    @Column(name = "username",unique = true,nullable = false)
    private String username;

    private Integer age;

    private String sex;

    //get set略
}

配置文件说明

Spring Boot 配置文件 application.yml 内容如下

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/jpa
    username: root
    password: 123456

  jpa:
    hibernate:
      #注入方式
      ddl-auto: update
      naming:
        #Hibernate 命名策略,这里修改下
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

    properties:
      hibernate:
        #数据库方言
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

ddl-auto属性说明

l45bhlc3.png

常用属性:
自动创建|更新|验证数据库表结构。
**create:**
每次启动时都会删除上一次的生成的表,然后根据你的实体类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
**create-drop :**
每次加载 hibernate 时根据 model 类生成表,但是 sessionFactory 一关闭,表就自动删除。
**update:**
最常用的属性,第一次加载启动时根据实体类会自动建立起表的结构(前提是先建立好数据库),以后以后再次启动时会根据实体类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。
**validate :**
每次应用启动时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

这里我们使用 update,让应用启动时自动给我们生成 User 表

基础操作

1、编写 UserRepo 继承 JpaRepository
import me.zhengjie.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepo extends JpaRepository<User,Long> {
    
}
2、使用默认方法

在 test 目录中,新建 UserTests


@RunWith(SpringRunner.class)
@SpringBootTest
public class UserTests {

    @Autowired
    private UserRepo userRepo;

    @Test
    public void test1() {

        User user=new User();
        //查询全部
        List<User> userList = userRepo.findAll();

        //根据ID查询
        Optional<User> userOptional = userRepo.findById(1L);

        //保存,成功后会返回成功后的结果
        user = userRepo.save(user);

        //删除
        userRepo.delete(user);
        //根据ID删除
        userRepo.deleteById(1L);

        //计数
        Long count = userRepo.count();
        
        //验证是否存在
        Boolean b = userRepo.existsById(1l);
    }

}

自定义简单查询

自定义的简单查询就是根据方法名来自动生成 SQL,主要的语法是 findXXBy, readAXXBy, queryXXBy, countXXBy, getXXBy 后面跟属性名称:

public interface UserRepo extends JpaRepository<User,Long> {

    /**
     * 根据 username 查询
     * @param username
     * @return
     */
    User findByUsername(String username);

    /**
     * 根据 username 和 age 查询
     * @param username
     * @param age
     * @return
     */
    User findByUsernameAndAge(String username,Integer age);
}

具体的关键字,使用方法和生产成 SQL 如下表所示

KeywordSampleJPQL snippet
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age ⇐ ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull… where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection age)… where x.age not in ?1
TRUEfindByActiveTrue()… where x.active = true
FALSEfindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

分页查询

Page<User> findALL(Pageable pageable);
    
Page<User> findByUserName(String userName,Pageable pageable);

Pageable 是 spring 封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则

@Test
public void test2() {
    //页码,Pageable中默认是从0页开始
    int page = 0;

    //每页的个数
    int size = 10;
    Sort sort = new Sort(Sort.Direction.DESC,"id");
    Pageable pageable = PageRequest.of(page,size,sort);
    Page<User> list = userRepo.findAll(pageable);
}

限制查询

有时候我们只需要查询前N个元素

     /**
     * 限制查询
     */
    List<User> queryFirstByAge(Integer age);

    List<User> queryFirst10ByAge(Integer age);

自定义SQL

如果项目中由于某些原因 Jpa 自带的已经满足不了我们的需求了,这个时候我们就可以自定义的 SQL 来查询,只需要在 SQL 的查询方法上面使用@Query注解,如涉及到删除和修改在需要加上 @Modifying

    /**
     * 自定义SQL,nativeQuery = true,表明使用原生sql
     */
    @Modifying
    @Query(value = "update User u set u.userName = ?1 where u.id = ?2",nativeQuery = true)
    void modifyUsernameById(String userName, Long id);

    @Modifying
    @Query(value = "delete from User where id = ?1",nativeQuery = true)
    void deleteByUserId(Long id);

    @Query(value = "select u from User u where u.id = ?1",nativeQuery = true)
    User findByUserId(Long id);

本文主要讲解了 Jpa 的一些简单的操作,下篇文章将讲解 Jpa 如何使用 Specification 实现复杂的查询,如多表查询,模糊查询,日期的查询等

本文共 810 个字数,平均阅读时长 ≈ 3分钟
4

打赏

评论 (0)

取消