Spring Boot 如何集成JPA

372 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情

JPA简介

Jpa (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,Jpa 是一套规范,不是一套产品,像 Hibernate,TopLink,JDO 他们是一套产品,这些产品是基于Jpa 规范实现的产品。 Spring Boot Jpa 是 Spring 基于 ORM 框架、Jpa 规范的基础上封装的一套 Jpa 应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!Spring Data Jpa 可以极大提高开发效率!

基本集成

jar包引入

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.13</version>
		</dependency>

编写实体

@Entity
@Table(name="t_user")
public class User
{

    //使用自增长策略
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="oid")
    private Integer oid;
    
    @Column(name="name")
    private String name;
    
    @Column(name="age")
    private int age;
    //省略get、set方法
 }   

注解说明:

  • @Entity 声明类为实体或表。
  • @Table 声明表名。
  • @Basic 指定非约束明确的各个字段。
  • @Embedded 指定类或它的值是一个可嵌入的类的实例的实体的属性。
  • @Id 指定的类的属性,用于识别(一个表中的主键)。
  • @GeneratedValue 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。
  • @Transient 指定的属性,它是不持久的,即:该值永远不会存储在数据库中。
  • @Column 指定持久属性栏属性。
  • @SequenceGenerator 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列。
  • @TableGenerator 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表。
  • @AccessType 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量。
  • @JoinColumn 指定一个实体组织或实体的集合。这是用在多对一和一对多关联。
  • @UniqueConstraint 指定的字段和用于主要或辅助表的唯一约束。
  • @ColumnResult 参考使用select子句的SQL查询中的列名。
  • @ManyToMany 定义了连接表之间的多对多一对多的关系。
  • @ManyToOne 定义了连接表之间的多对一的关系。
  • @OneToMany 定义了连接表之间存在一个一对多的关系。
  • @OneToOne 定义了连接表之间有一个一对一的关系。
  • @NamedQueries 指定命名查询的列表。
  • @NamedQuery 指定使用静态名称的查询。

编写dao层,继承JpaRepository,已经包含了CRUD的相关方法

public interface UserDao extends JpaRepository<User, Integer>
{

}

测试代码主要包含的CRUD方法

@RestController
@RequestMapping("")
public class UserController
{
    private Logger logger =LoggerFactory.getLogger(UserController.class);
    @Autowired
    private UserDao userDao;
    
    @RequestMapping("/saveUser")
    public String saveUser(){
        
        User user =new User();
        user.setName("jpatest");
        user.setAge(100);
        userDao.save(user);
        return "成功";
    }
    
    @RequestMapping("/findById")
    public void getUserByOid(@RequestParam int oid)
    {
        Usesr user= userDao.findById(oid).orElas(null);
        logger.info("user:{}",user);
    }
    
    
    @RequestMapping("/deleteById")
    public String deleteById(@RequestParam int oid)
    {
       userDao.deleteById(oid);
       return "成功";
    }
}

JPA已经封装了许多通用的方法,例如findAll()、findone()、count()、exist()等方法。

自定义简单查询

有些特殊的需求需要自定查询来实现,自定义的简单查询就是根据方法名来自动生成 SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称。

简单查询支持:And、Or、Between、like、LessThan不一一列举,详情可以参考JPA文档说明

示例:

 //更加用户名查询
 User findByName(String name);
 User findByNameOrEmail(String name);
 //开启事务
 @Transactional
 Long deleteByName(String name);

复杂查询

在实际的项目中可能会用到分页、连表、删选等查询的时候,我们就需要一些特殊的方法或者自定义SQL

分页查询

 //分页查询
Page<User> findAll(Pageable pageable);
  

测试

 @RequestMapping("/testPageQuery")
    public String testPageQuery() throws Exception {
        int page=1,size=10;
        Pageable pageable = PageRequest.of(page, size);
        Page<User> page2=userDao.findAll(pageable);
        return JSON.toJSONString(page2);
    }

自定义SQL语句

Spring JPA能够满足大部分的SQL需求,但是由于一些特殊原因,我们还是需要自定义SQL语句来查询,SpringJPA也是能够很好的支持,在SQL查询上添加@Query注解,如果是修改或者删除需要添加@Modifying和@Transactional来支持事务

示例

 //通过user的oid更新用户名字段
   @Transactional
   @Modifying
   @Query(nativeQuery=true ,value="update t_user u set u.name = ?1 where u.oid = ?2")
   int modifyNameByOid(String  userName, Integer oid);

对于复杂的SQL语句都是通过SQL自定义的SQL来进行实现,尽量少用JPA的级联查询。

总结

本来讲解Spring Boot集成Jpa的相关功能,从上述的实现过程来看,JPA实现CRUD功能比Mybaties要简单许多,JPA虽然简单,SQL语句都是自动生成,但是在实际的项目运用中还会遇到很多其他的问题,在后续的文中中会重点说明,使用JPA我们应该注意那些问题。