JPA 入门实战(2)–简单使用

本文主要介绍 JPA 的实际使用,相关的环境及软件信息如下:JPA 2.2(eclipselink 2.7.10、hibernate-entitymanager 5.6.10.Final、openjpa 3.2.2),JPA 3.0(eclipselink 3.0.2、hibernate-core-jakarta 5.6.10.Final)。

1、JPA 2.2 使用

工程目录结构如下:

JPA 入门实战(2)--简单使用

1.1、引入依赖

这里使用 eclipselink 作为 JPA 的实现框架。

<dependency>
    <groupId>org.eclipse.persistencegroupId>
    <artifactId>org.eclipse.persistence.jpaartifactId>
    <version>2.7.10version>
dependency>

其他的依赖可自行引入,如数据库驱动、lombok 等。

1.2、创建实体类

1.2.1、Student.java

package com.abc.demojpa.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.time.LocalDateTime;

@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Table(name = "a_student")
@NamedQuery(name = "queryAll", query = "select s from Student s")
public class Student {
    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "create_time")
    private LocalDateTime createTime;

    @Column(name = "modify_time")
    private LocalDateTime modifyTime;

    private String name;

    private Integer age;

    @Column(name = "home_address")
    private String homeAddress;
}

1.2.2、BaseEntity.java

package com.abc.demojpa.entity;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Data
//该类的属性都将映射到其子类的数据库字段中
@MappedSuperclass
public class BaseEntity {
    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "create_time")
    private LocalDateTime createTime;
}

1.2.3、Teacher.java

Teacher 继承了 BaseEntity,主要为了测试属性的继承。

package com.abc.demojpa.entity;

import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@NoArgsConstructor
@Data
@Entity
@Table(name = "a_teacher")
public class Teacher extends BaseEntity {
    private String name;

    private Integer age;
}

1.3、编写 JPA 配置文件 (persistence.xml)

该配置文件需放在 META-INF 目录下。

xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="myUnit">
        <provider>org.eclipse.persistence.jpa.PersistenceProviderprovider>
        <class>com.abc.demojpa.entity.Studentclass>
        <class>com.abc.demojpa.entity.Teacherclass>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://10.49.196.10:3306/test?useUnicode=true&characterEncoding=UTF-8"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="123456"/>
            <property name="eclipselink.logging.level" value="INFO" />
            <property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
        properties>
    persistence-unit>
persistence>

eclipselink 开头的配置是 eclipselink 自带的扩展配置,用于实现功能的增强;详细的扩展配置说明可参考官网说明:https://www.eclipse.org/eclipselink/documentation/2.7/jpa/extensions/toc.htm。

1.4、使用例子

1.4.1、插入实体

@Test
public void persist() {
    entityManager.getTransaction().begin();
    Student student = new Student();
    student.setName("小明");
    student.setCreateTime(LocalDateTime.now());
    student.setModifyTime(LocalDateTime.now());
    student.setAge(15);
    student.setHomeAddress("江苏");

    Student student2 = new Student();
    student2.setName("小红");
    student2.setAge(18);
    student2.setHomeAddress("广东");

    Teacher teacher = new Teacher();
    teacher.setCreateTime(LocalDateTime.now());
    teacher.setName("张三");
    teacher.setAge(35);

    entityManager.persist(student);
    entityManager.persist(student2);
    entityManager.persist(teacher);

    entityManager.getTransaction().commit();
}

1.4.2、查询实体

@Test
public void find() {
    Student student = entityManager.find(Student.class, 1501L);
    logger.info("student={}", student);
}

1.4.3、更新实体(先查再更新)

@Test
public void modify() {
    entityManager.getTransaction().begin();
    Student student = entityManager.find(Student.class, 1501L);
    student.setName("小明2");
    entityManager.getTransaction().commit();
}

1.4.4、更新实体(直接根据id更新)

@Test
public void merge() {
    entityManager.getTransaction().begin();
    Student student = new Student();
    student.setId(1501L);
    student.setName("小明3");
    student.setAge(16);
    entityManager.merge(student);
    entityManager.getTransaction().commit();
}

1.4.5、删除实体

@Test
public void remove() {
    entityManager.getTransaction().begin();
    Student student = entityManager.find(Student.class, 1501L);
    entityManager.remove(student);
    entityManager.getTransaction().commit();
}

1.4.6、JPQL 查询

@Test
public void select() {
    //查询一个字段
    Query query = entityManager.createQuery("select s.name from Student s where s.age>10", String.class);
    List result = query.getResultList();
    logger.info("result={}", result);

    //查询多个字段 (?n 占位符:传统 ? 占位符的改良占位符,仅仅适应 JPQL 查询)
    query = entityManager.createQuery("select s.name,s.homeAddress from Student s where s.age>?1 and s.name like ?2", Object[].class);
    query.setParameter(1, 10);
    query.setParameter(2, "%小%");
    List result2 = query.getResultList();
    for (Object[] arr : result2) {
        String s = "";
        for (Object o : arr) {
            s += o.toString() + ",";
        }
        logger.info(s);
    }

    //查询对象 (:name 占位符:变量名形式的占位符,仅仅适应 JPQL 查询)
    query = entityManager.createQuery("select s.name,s.homeAddress from Student s where s.age between :min and :max and s.name like '%小%' order by s.id", Student.class);
    query.setParameter("min", 10);
    query.setParameter("max", 40);
    //设置结果的开始位置,最大记录条数,可用来实现分页
    query.setFirstResult(0);
    query.setMaxResults(10);
    List result3 = query.getResultList();
    logger.info("result3={}", result3);

    //聚合操作
    query = entityManager.createQuery("select max(s.age) from Student s");
    Object result4 = query.getSingleResult();
    logger.info("result4={}", result4);

    //对应Student实体类中定义的静态查询"queryAll"
    query = entityManager.createNamedQuery("queryAll");
    List result5 = query.getResultList();
    logger.info("result5={}", result5);
}

1.4.7、JPQL 更新

@Test
public void update() {
    entityManager.getTransaction().begin();
    Query query = entityManager.createQuery( "update Student SET age=16 where name='小明'");
    query.executeUpdate();
    entityManager.getTransaction().commit();
}

1.4.8、JPQL 删除

@Test
public void delete() {
    entityManager.getTransaction().begin();
    Query query = entityManager.createQuery( "delete from Student where id=1501");
    query.executeUpdate();
    entityManager.getTransaction().commit();
}

1.4.9、JPQL 本地查询,直接 SQL 语句查询数据

@Test
public void nativeSelect() {
    Query query = entityManager.createNativeQuery("select s.* from a_student s where s.age>?", Student.class);
    query.setParameter(1, 10);
    List result = query.getResultList();
    logger.info("result={}", result);
}

1.4.10、JPA 标准 API 使用一

类似 SQL:select name from student where name=’小明’

@Test
public void criteria() {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(String.class);
    Root root = criteriaQuery.from(Student.class);
    criteriaQuery.select(root.get("name"));
    criteriaQuery.where(criteriaBuilder.equal(root.get("name"), "小明"));
    TypedQuery query = entityManager.createQuery(criteriaQuery);
    List list = query.getResultList();
    logger.info(list.toString());
}

1.4.11、JPA 标准 API 使用二

类似 SQL:select id,name,age from student where age>=10 order by age,name desc

@Test
public void criteria2() {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Student.class);
    Root root = criteriaQuery.from(Student.class);
    //Student 实体类需要有对应的构造方法
    criteriaQuery.multiselect(root.get("id"), root.get("name"), root.get("age"), root.get("homeAddress"));
    criteriaQuery.where(criteriaBuilder.ge(root.get("age"), 10));
    criteriaQuery.orderBy(criteriaBuilder.asc(root.get("age"))).orderBy(criteriaBuilder.desc(root.get("name")));
    TypedQuery query = entityManager.createQuery(criteriaQuery);
    List list = query.getResultList();
    logger.info(list.toString());
}

1.4.12、JPA 标准 API 使用三

类似 SQL:select age,count(*) from student group by age having age

Original: https://www.cnblogs.com/wuyongyin/p/16516717.html
Author: 且行且码
Title: JPA 入门实战(2)–简单使用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/620568/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Jenkins Shared Library 添加第三方包支持

    我们在写 Jenkins 的 Shared Library 时,有时候需要引用外部的一些 jar 包,比如 maven central 的一些 lib 等。具体到我们的例子,需要引…

    Java 2023年6月9日
    068
  • SpringCloud 上

    Spring Cloud 是在 Spring Boot 基础上构建的, 用于检查分布式系统构建的工具集. 工具集包括 配置管理, 服务发现, 智能路由,断路器,为代理和控制总线. …

    Java 2023年5月30日
    058
  • 迭代器Iterator的使用方法(Java)

    迭代器是一种经典的设计模式。 用于在不需要暴漏数据是如何保存在数据结构中的细节的情况下,遍历一个数据结构。Collection接口继承自Iterable接口。所以说,实现了Coll…

    Java 2023年6月5日
    082
  • 使用spire.doc免费版SDK导出word只支持500行问题解决

    我们在之前版本中调研导出支持编辑Latex公式的word中,采用了spire.doc的组件,但是在英语试卷生成的时候,由于题目较多在生成word的时候报错了,错误的信息很明确,就是…

    Java 2023年6月7日
    084
  • JAVA-URLDNS链分析

    JAVA-URLDNS链分析 1.从ysoserial工具中看exp https://github.com/frohoff/ysoserial/blob/master/src/ma…

    Java 2023年6月6日
    088
  • 设计模式—桥接模式

    类型:结构型 目的:通过抽离出多个维度相互组合(聚合)来代替继承,简化系统。 话不多说,看个优化案例。 优化案例 现有系统中,对于画面窗口的边框有一套样式来控制是否有圆角。因为新的…

    Java 2023年6月7日
    060
  • 代码审计(1)

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/rayob1/p/16353751.htmlAuthor…

    Java 2023年6月6日
    084
  • Mybatis基本流程及配置文件解析

    Mybatis基本流程 1、利用Resources工具类加载配置文件,并转换成输入输出流 2、利用解析的配置,创建SqlSessionFactory工厂 3、生产SqlSessio…

    Java 2023年6月5日
    083
  • Android BLE 蓝牙开发——扫码枪基于BLESSED

    一、蓝牙模式HID与BLE 当扫码枪与手机连接时,通常采用的是 蓝牙HID(Human Interface Device)模式。本质上是一个把扫码枪作为一个硬件键盘,按照键盘协议把…

    Java 2023年6月15日
    075
  • java.lang.ClassNotFoundException: com.*.*.entity.time.Q*

    添加依赖 1、添加DSL依赖 2、添加插件 Original: https://www.cnblogs.com/tianciliangen/p/11693647.htmlAutho…

    Java 2023年5月29日
    077
  • RPC学习

    设计协议 相对于 HTTP 的用处,RPC 更多的是负责应用间的通信,所以性能要求相对更高。但 HTTP 协议的数据包大小相对请求数据本身要大很多,又需要加入很多无用的内容,比如换…

    Java 2023年6月8日
    0112
  • Spring Boot 读取配置文件

    Spring Boot 读取配置文件 Spring Boot 读取配置文件有两种方式: 加载多个 @ConfigurationProperties(xxx) 加载单个 @Value…

    Java 2023年6月5日
    063
  • 哈工大软件构造Lab3(2022)

    (防扒小助手) 本人CSDN博客: https://blog.csdn.net/m0_61753302 ; 本人博客园博客(同步CSDN): 何以牵尘 – 博客园 (c…

    Java 2023年6月9日
    065
  • Synchronized底层实现逻辑原理解析

    什么是同步的 如果一个资源被多个线程共享,我们需要同步线程,以避免资源抢占造成的资源数据混乱。在Java中,synchronized是实现线程同步的关键字。 使用synchroni…

    Java 2023年5月29日
    070
  • ffmpeg文档4:创建线程

    综述前面我们利用SDL的音频函数实现了对音频解码和播放的支持,我们定义一个包含音频回调函数callbacks的线程函数,当我们需要音频的时候就使SDL启动这个线程。现在我们将要对视…

    Java 2023年5月29日
    067
  • JavaWeb-MVC、过滤器

    一、MVC架构图 Model 业务处理:业务逻辑(Service) 数据持久层:CRUD(Dao) View 展示数据 提供连接发起Servlet请求(a,form,img&#82…

    Java 2023年6月13日
    0111
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球