happy birthday BNTang!

(一)JPA的快速入门

JPA简介

JPA是什么

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

1、如何使用

引入依赖

   <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>

数据库脚本

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

创建实体类

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

创建JAP配置文件

resources/META-INF/persistence.xml

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

<?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, 配置不同的方言就可以实现不同的数据库移植处理

创建日期工具类:

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

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 依赖,可以直接使用。

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

#将等级为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

posted @ 2022-09-21 22:32  look-word  阅读(346)  评论(0编辑  收藏  举报