首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring Boot 正确中使用JPA实战

Spring Boot 正确中使用JPA实战

作者头像
后端码匠
发布2019-10-24 16:56:21
发布2019-10-24 16:56:21
1.8K0
举报
文章被收录于专栏:后端码匠后端码匠

在这里我们先来了解一下jpa。

代码语言:javascript
复制
JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的 接口和抽象类 构成。
JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

jpa的优势

标准化

JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。

容器级特性的支持

JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。

简单方便

JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建 Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity 进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成。

查询能力

JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。

高级特性

JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。

基础操作

相关依赖

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.com.codingce</groupId>
    <artifactId>jpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>jpa</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置数据库连接信息和JPA配置(本地创建数据库springboot_jpa)

代码语言:javascript
复制
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_jpa?useSSL=false&serverTimezone=CTT
spring.datasource.username=root
spring.datasource.password=123456
# 打印出 sql 语句
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.open-in-view=false
# 创建的表的 ENGINE 为 InnoDB
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect

注意:

代码语言:javascript
复制
spring.jpa.hibernate.ddl-auto=create----每次运行该程序,没有表格会新建表格,表内有数据会清空
spring.jpa.hibernate.ddl-auto=create-drop----每次程序结束的时候会清空表
spring.jpa.hibernate.ddl-auto=update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
spring.jpa.hibernate.ddl-auto=validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错

只限本地测试玩。

实体类

代码语言:javascript
复制
package cn.com.codingce.jpa.entity;

import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * @Author: Jiangjun
 * @Date: 2019/10/22 13:01
 */
@Entity
@Data
@NoArgsConstructor
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true)
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

}

到此步运行相应的表即可创建,控制台输出语句如下:

数据库相应表创建:

创建操作数据库的 Repository 接口

代码语言:javascript
复制
package cn.com.codingce.jpa.repository;

import cn.com.codingce.jpa.entity.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;

import java.util.Optional;

/**
 * @Author: Jiangjun
 * @Date: 2019/10/22 13:04
 */
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {

    /**
     * 根据 name 来查找 Person
     *
     * @param name 用户姓名
     * @return
     */
    @Query("select p from Person p where p.name = :name")
    Optional<Person> findByNameCustomeQuery(@Param("name") String name);


    /**
     * 根据 id 更新Person name
     *
     * @param id 用户id
     * @return
     */
    @Query("select p.name from Person p where p.id = :id")
    String findPersonNameById(@Param("id") Long id);

}

这个接口和数据库操作有关,继承JpaRepository。JpaRepository继承自PagingAndSortingRepository接口,JpaRepository基于JPA的Repository接口,极大减少了JPA作为数据访问的代码,JpaRepository是实现Spring Data JPA技术访问数据库的关键接口。

代码语言:javascript
复制
@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);
}

继承了JpaRepository<Person, Long>就具有了JPA为我们提供好的增删改查、分页以及根据条件查询等方法。

jpa自带方法实战

service层

代码语言:javascript
复制
package cn.com.codingce.jpa.service;

import cn.com.codingce.jpa.entity.Person;
import cn.com.codingce.jpa.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * @Author: Jiangjun
 * @Date: 2019/10/22 13:07
 */
@Service
public class PersonService {

    @Autowired
    private PersonRepository repository;

    /**
     * 添加
     *
     * @param person
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(Person person) {
        repository.save(person);
    }

    /**
     * 查找用户
     *
     * @param id 用户id
     * @return
     */
    public Person findById(Long id) {
        Person person = repository.findById(id)
                .orElseThrow(RuntimeException::new);
        return person;
    }

    /**
     * 删除用户
     *
     * @param id 用户id
     */
    public void deleteById(Long id) {
        repository.deleteById(id);
    }

    /**
     * 删除用户
     *
     * @param person
     */
    public void delete(Person person) {
        repository.delete(person);
    }

}

测试添加

代码语言:javascript
复制
@SpringBootTest
class JpaApplicationTests {

    @Autowired
    private PersonService service;

    @Test
    void save() {
        Person person = new Person("SnailClimb", 23);
        service.save(person);
    }

}

条件查询

单表查询根据 JPA 提供的语法自定义的

带条件的查询

很多时候我们自定义 sql 语句会非常有用。

根据 name 来查找 Person:

代码语言:javascript
复制
    @Query("select p from Person p where p.name = :name")    
    Optional<Person> findByNameCustomeQuery(@Param("name") String name);

Person 部分属性查询,避免 select *操作:

代码语言:javascript
复制
   @Query("select p.name from Person p where p.id = :id")   
   String findPersonNameById(@Param("id") Long id);

当然也是写在PersonRepository内。

源代码地址:https://github.com/Mazongdiulejinguzhou/Java

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端码匠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • jpa的优势
    • 带条件的查询
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档