(一)JPA的快速入门

## JPA简介

### JPA是什么

> JPA 是Java Persistence API的缩写,是一套由Java官方制定的ORM**标准**。当制定这套标准以后,市场上就出现很多JPA框架。如:OpenJPA(apache),EclipseTop(linktop)(eclipse),Hibernate。

### 1、如何使用

#### 引入依赖

```xml

  <properties>

        <maven.compiler.source>17</maven.compiler.source>

        <maven.compiler.target>17</maven.compiler.target>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <lombok.version>1.18.24</lombok.version>  <!--lombok版本-->

        <slf4j.version>1.7.25</slf4j.version>  <!--slf4j版本-->

        <spring.version>5.3.21</spring.version>

        <junit.version>5.8.2</junit.version>

        <mysql.version>8.0.30</mysql.version>

        <HikariCP.version>5.0.1</HikariCP.version>  <!--HikariCP连接池版本-->

        <jpa.version>3.1.0</jpa.version>  <!--jpa连接池版本-->

        <hibernateORM.version>6.1.0.Final</hibernateORM.version>  <!--HibernateORM 连接池版本-->

        <hibernate.version>5.6.9.Final</hibernate.version>  <!--Hibernate版本-->

    </properties>

<dependencies>

            <!--日志打印-->

            <dependency>

                <groupId>org.projectlombok</groupId>

                <artifactId>lombok</artifactId>

                <version>${lombok.version}</version>

            </dependency>

            <dependency>

                <groupId>org.slf4j</groupId>

                <artifactId>slf4j-api</artifactId>

                <version>${slf4j.version}</version>

            </dependency>

            <dependency>

                <groupId>org.slf4j</groupId>

                <artifactId>slf4j-log4j12</artifactId>

                <version>${slf4j.version}</version>

            </dependency>

            <!--日志打印-->

            <dependency>

                <groupId>org.springframework</groupId>

                <artifactId>spring-context</artifactId>

                <version>${spring.version}</version>

            </dependency>

            <dependency>

                <groupId>mysql</groupId>

                <artifactId>mysql-connector-java</artifactId>

                <version>${mysql.version}</version>

            </dependency>

            <dependency>

                <groupId>org.springframework</groupId>

                <artifactId>spring-test</artifactId>

                <version>${spring.version}</version>

            </dependency>

            <dependency>

                <groupId>org.junit.jupiter</groupId>

                <artifactId>junit-jupiter-api</artifactId>

                <version>${junit.version}</version>

            </dependency>

            <!-- HikariCP连接池 -->

            <dependency>

                <groupId>com.zaxxer</groupId>

                <artifactId>HikariCP</artifactId>

                <version>5.0.1</version>

            </dependency>

            <!--雅加达JPA规范-->

            <dependency>

                <groupId>jakarta.persistence</groupId>

                <artifactId>jakarta.persistence-api</artifactId>

                <version>${jpa.version}</version>

            </dependency>

            <!--JPA核心依赖-->

            <dependency>

                <groupId>org.hibernate</groupId>

                <artifactId>hibernate-core</artifactId>

                <version>${hibernateORM.version}</version>

            </dependency>

            <!--hibernate使用Hikaricp连接池-->

            <dependency>

                <groupId>org.hibernate.orm</groupId>

                <artifactId>hibernate-hikaricp</artifactId>

                <version>${hibernateORM.version}</version>

            </dependency>

            <dependency>

                <groupId>org.hibernate</groupId>

                <artifactId>hibernate-core-jakarta</artifactId>

                <version>${hibernate.version}</version>

            </dependency>

        </dependencies>

```

#### **数据库脚本**

```sql

use yootk;

create table course

(

    cid    bigint auto_increment comment '课程id',

    cname  varchar(50) comment '课程名称',

    start  date comment '课程开始时间',

    end    date comment '课程结束时间',

    credit int comment '课程学分',

    num    int comment '课程人数',

    constraint pk_cid primary key (cid)

)engine= innodb;

```

> 在JPA的开发过程之中是需要提供有一个**持久化类**的,而这个 持久化类 需要使用到一些特定的注解进行标记(JPA提供了所有可用的注解),同时这个类的结构要与数据表的结构完全对应。

![image-20220919231950903](https://img2022.cnblogs.com/blog/2233272/202209/2233272-20220919232003085-144080553.png)

**创建实体类**

```java

package look.word.po;

import jakarta.persistence.*;

import lombok.*;

import org.hibernate.Hibernate;

import java.util.Date;

import java.util.Objects;

@Entity // 一个基于JPA规范的实体类

@Table(name = "course") //指定当前实体类关联的表

@Getter

@Setter

@ToString

@RequiredArgsConstructor

public class Course {

    @Id // 标识为主键

    @GeneratedValue(strategy = GenerationType.IDENTITY) //指定主键生成策略

    private Long cid;

    // @Column注解,设置属性关联的数据库表字段

    // 注意:如果属性名和表字段名相同,可以不设置

    private String cname;

    @Temporal(TemporalType.DATE) // 定义时间类型

    private Date start;

    @Temporal(TemporalType.DATE)

    private Date end;

    private Integer credit;

    private Integer num;

    // equels() hashCode()

}

```

**常用注解**

![image-20220919222249620](https://img2022.cnblogs.com/blog/2233272/202209/2233272-20220919222254127-1331760535.png)

#### **创建JAP配置文件**

> resources/META-INF/persistence.xml

>

> **注意:** 配置很多,但不用记 记得修改数据库,我这里是基于Hikari连接池的,不需要可以直接使用简化版

```xml

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.1"

            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_1.xsd">

    <persistence-unit name="YootkJPA">            <!-- 持久化单元 -->

        <class>look.word.po.Course</class>            <!-- 实体类 -->

        <properties> <!-- 使用Hikari连接池实现数据库连接管理 -->

            <property name="hibernate.connection.provider_class"

                      value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider"/>

            <property name="hibernate.dialect"

                      value="org.hibernate.dialect.MySQLDialect"/>    <!-- 数据库方言 -->

            <property name="hibernate.hikari.dataSourceClassName"

                      value="com.zaxxer.hikari.HikariDataSource"/> <!-- Hikari数据源 -->

            <property name="hibernate.hikari.minimumIdle"

                      value="5"/>                <!-- 空闲时连接池数量 -->

            <property name="hibernate.hikari.maximumPoolSize"

                      value="10"/>                <!-- 连接池最大数量 -->

            <property name="hibernate.hikari.idleTimeout"

                      value="3000"/>                <!-- 连接最小维持时长 -->

            <property name="hibernate.hikari.dataSource.driverClassName"

                      value="com.mysql.cj.jdbc.Driver"/>    <!-- 驱动程序 -->

            <property name="hibernate.hikari.dataSource.jdbcUrl"

                      value="jdbc:mysql://localhost:3306/yootk"/>    <!-- 连接地址 -->

            <property name="hibernate.hikari.dataSource.username"

                      value="root"/>                <!-- 用户名 -->

            <property name="hibernate.hikari.dataSource.password"

                      value="317311"/>            <!-- 密码 -->

            <property name="hibernate.show_sql"

                      value="true"/>                <!-- 显示执行SQL -->

            <property name="hibernate.format_sql"

                      value="false"/>                <!-- 格式化SQL -->

        </properties>

    </persistence-unit>

</persistence>

```

**简化版:**

```

<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">

    <!-- 持久单元,配置一个数据库连接 -->

    <persistence-unit name="mysql-jpa">

        <!-- DB连接四要素 -->

        <properties>

            <!-- 这里使用Hibernate-JPA -->

            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>

            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/yootk"/>

            <property name="hibernate.connection.username" value="root"/>

            <property name="hibernate.connection.password" value="317311"/>

            <!-- 格式化输出SQL语句 -->

            <property name="hibernate.format_sql" value="true"/>

        </properties>

    </persistence-unit>

</persistence>

```

> **Hibernate可移植性配置核心:** hibernate.dialect, 配置不同的方言就可以实现不同的数据库移植处理

**创建日期工具类:**

> 知道用就好,不需要知道其原理。字符串转日期对象

```java

package look.word.util;

import java.time.Instant;

import java.time.LocalDate;

import java.time.ZoneId;

import java.time.format.DateTimeFormatter;

import java.util.Date;

/**

* @author : look-word

* 2022-09-19 22:38

**/

public class DateUtil {

    /**

    * 转换格式

    */

    private static final String DATA_PATTERN = "yyyy-MM-dd";

    /**

    * 日期格式化

    */

    private static final DateTimeFormatter DATE_FORMATTER =

            DateTimeFormatter.ofPattern(DATA_PATTERN);

    private static final ZoneId ZONE_ID = ZoneId.systemDefault();

    public static Date stringToDate(String date) {

        LocalDate localDate = LocalDate.parse(date, DATE_FORMATTER);

        Instant instant = localDate.atStartOfDay().atZone(ZONE_ID).toInstant();

        return Date.from(instant);

    }

}

```

#### **测试:**

> 测试文件夹下,创建测试文件,因为我们引入了 Junit 依赖,可以直接使用。

```java

import jakarta.persistence.EntityManager;

import jakarta.persistence.EntityManagerFactory;

import jakarta.persistence.Persistence;

import look.word.po.Course;

import look.word.util.DateUtil;

import org.junit.jupiter.api.Test;

/**

* @author : look-word

* 2022-09-19 22:44

**/

public class TestCoursePersistence {

    @Test

    public void testAdd() {

        // 创建JPA Entity工厂

        EntityManagerFactory factory =

                Persistence.createEntityManagerFactory("YootkJPA");

        // JPA操作对象

        EntityManager entityManager = factory.createEntityManager();

        // 开启事务

        entityManager.getTransaction().begin();

        Course course = new Course(); // 创建实体对象

        course.setCname("Spring编程实战");

        course.setStart(DateUtil.stringToDate("2022-09-19"));

        course.setEnd(DateUtil.stringToDate("2022-12-30"));

        course.setCredit(2);

        course.setNum(88);

        entityManager.persist(course); // 类似于插入

        entityManager.getTransaction().commit(); // 提交事务

        factory.close();// 关闭连接

    }

}

// 执行结果  需要往下翻 才能看到

// Hibernate: insert into course (cname, credit, end, num, start) values (?, ?, ?, ?, ?) 执行的sql

// 在JPA配置文件中有配置

```

> 一定要及得提交事务。

>

> - 执行错误的话,一定要是上面哪一步出现错误了,请仔细查看

> - 执行 没有日志输出,提示log4j日志配置的话,是由于我们没有配置日志信息

**配置日志: **log4j.properties

```properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码

log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置

log4j.appender.console=org.apache.log4j.ConsoleAppender

log4j.appender.console.Threshold=DEBUG

log4j.appender.console.ImmediateFlush=true

log4j.appender.console.Target=System.err

log4j.appender.console.layout=org.apache.log4j.PatternLayout

log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

#文件输出的相关设置

log4j.appender.file = org.apache.log4j.RollingFileAppender

log4j.appender.file.File=./log/logFile.log

log4j.appender.file.MaxFileSize=10mb

log4j.appender.file.Threshold=DEBUG

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别

log4j.logger.org.mybatis=DEBUG

log4j.logger.java.sql=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.ResultSet=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG

```

###

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容