目录

一、Hibernate的基本操作

1、添加依赖

2、添加建表实体类

3、添加hibernate配置依赖

4、测试类

 二、SpringData实现JPA的功能

1、添加persistence.xml配置文件

 2、JPA测试

3、切换持久化单元的演示

 4、*HibernateJPI常见操作,测试案例*


一、Hibernate的基本操作

1、添加依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.2.RELEASE</version>
        <artifactId>spring-boot-starter-parent</artifactId>
        <relativePath/>
    </parent>

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <junit.version>4.13</junit.version>
        <hibernate.version>5.4.32.Final</hibernate.version>
        <mysql.version>5.1.22</mysql.version>
    </properties>

<dependencies>
        <!--hibernate对jpa的依赖包-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <!--Mysql and MariaDB-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
<!--junit4-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、添加建表实体类

hibernate可以通过实体类自动生成对应的表

package com.dragonwu.entity;


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

/**
 * @author DragonWu
 * @date 2022-09-20 11:17
 **/
@Entity //作为hibernate的实体类
@Table(name="tb_customer")//映射的表名
public class Customer {

    /**
     * @Id 主键声明
     * @GeneratedValue: 配置主键的生成策略
     *      strategy
     *          GenerationType.IDENTITY: 自增,mysql
     *              *底层数据库必须支持自动增长
     *          GenerationType.SEQUENCE: 序列oracle
     *              *底层数据库必须支持序列
     *          GenerationType.TABLE: jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键
     *          GenerationType.AUTO: 由程序自动地帮助我们选择主键生成策略
     * @Cloumn 配置属性和表字段的映射关系
     *      name: 数据库表中字段的名称
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id",length = 20)
    private Long id;

    @Column(name="cus_name",columnDefinition = "varchar(32) default null comment '客户名'")
    private String name;//客户名

    @Column(name="cus_address",length = 200)
    private String address;//客户地址

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

3、添加hibernate配置依赖

这里建议命名为hibernate.cfg.xml,我存放的目录在resource/hibernate/hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!--配置数据库连接信息-->
        <property name="connection.url">jdbc:mysql://my-server:3306/test</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.username">root</property>
        <!-- 数据库的登陆密码 -->
        <property name="hibernate.connection.password">WXL1214</property>
        <!-- 指定连接数据库的编码 -->
        <property name="connection.characterEncoding">utf8</property>
        <!-- 指定数据库方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>
        <!-- 显示Hibernate持久化操作所生成的SQL -->
        <property name="show_sql">true</property>
        <!-- 将SQL脚本进行格式化后再输出 -->
        <property name="format_sql">true</property>
        <!-- 指定自动生成数据表的策略
        默认是none 不自动生成
        update 如果没有表会创建,有会检查更新
        create 每次运行都会创建新表-->
        <property name="hbm2ddl.auto">update</property>
        <!-- DB schema will be updated if needed -->
        <!-- 指定哪些实体类需要进行ORM映射 -->
        <mapping class="com.dragonwu.entity.Customer"/>

        <!--        <!–使用xml来进行映射时书写如下–>-->
        <!--        <mapping resource="hibernate.xml.Customer.xml"/>-->
    </session-factory>

</hibernate-configuration>

4、测试类

package com.dragonwu.test;

import com.dragonwu.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

/**
 * @author DragonWu
 * @date 2022-09-20 12:52
 **/
public class HibernateTest {

    //Session工厂 Session:数据库会话 代码持久化操作数据库的一个桥梁
    private SessionFactory sf;

    @Before
    public void init() {
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("/hibernate/hibernate.cfg.xml").build();

        //2、根据服务注册类持久一个元数据资源集,同时构建元数据并生成应用一般唯一的session工厂

        sf = new MetadataSources(registry).buildMetadata().buildSessionFactory();
    }

    @Test
    public void testC() {
        //session进行持久化操作
        try (Session session = sf.openSession()) {
            Transaction tx = session.beginTransaction();

            Customer customer = new Customer();
            customer.setName("DragonWu");

            session.save(customer);

            tx.commit();
        }
    }

    @Test
    public void testR() {
        //session进行持久化操作
        try (Session session = sf.openSession()) {
            Transaction tx = session.beginTransaction();

            Customer customer = session.find(Customer.class, 1L);
            System.out.println("===================");
            System.out.println(customer);

            tx.commit();
        }
    }

    @Test
    public void testR_lazy() {
        //session进行持久化操作
        try (Session session = sf.openSession()) {
            Transaction tx = session.beginTransaction();

            Customer customer = session.load(Customer.class, 1L);
            System.out.println("===================");
            System.out.println(customer);

            tx.commit();
        }
    }

    @Test
    public void testU() {
        //session进行持久化操作
        try (Session session = sf.openSession()) {
            Transaction tx = session.beginTransaction();

            Customer customer = new Customer();
            customer.setId(1L);
            customer.setAddress("杭州");

            //session.save()插入
            //session.update()更新
            session.saveOrUpdate(customer);//存在id时更新,不存在id时创建

            tx.commit();
        }
    }

    @Test
    public void testD() {
        //session进行持久化操作
        try (Session session = sf.openSession()) {
            Transaction tx = session.beginTransaction();

            Customer customer = new Customer();
            customer.setId(1L);

            session.remove(customer);

            tx.commit();
        }
    }

    @Test
    public void testR_HQL() {
        //session进行持久化操作
        try (Session session = sf.openSession()) {
            Transaction tx = session.beginTransaction();

            String hql = " FROM Customer where id=:id";

            List<Customer> resultList = session
                    .createQuery(hql, Customer.class)
                    .setParameter("id",2L)
                    .getResultList();
            System.out.println(resultList);

            tx.commit();
        }
    }
}

在对应连接里创建对应数据库,运行单元测试类testC

springData JPA整合SQLite spring data jpa hibernate_java

表已自动生成。 

单元测试testR

springData JPA整合SQLite spring data jpa hibernate_hibernate_02

 单元测试testR_lazy懒加载,load懒加载当执行到对应查询时系统才会执行查询,而find会先执行查询。

springData JPA整合SQLite spring data jpa hibernate_java_03

 二、SpringData实现JPA的功能

用之前的hibernate,如果我们需要修改持久化层,需要修改很多配置以及代码,由此SpringData推出了JPA的功能。JPA同样是钟规范,需要依赖于他的实现。

1、添加persistence.xml配置文件

目录结构如图:

springData JPA整合SQLite spring data jpa hibernate_spring_04

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">

    <!--需要配置persistence-unit节点
        持久化单元:
            name: 持久化单元名称
            transaction-type: 事务管理的方式
                JTA: 分布式事务管理
                RESOURCE_LOCAL: 本地事务管理
    -->
    <persistence-unit name="hibernateJPA" transaction-type="RESOURCE_LOCAL">

        <!--jpa的实现方式-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <!--需要进行ORM的实体类-->
        <class>com.dragonwu.entity.Customer</class>
        <!--可选配置:配置jpa实现方的配置信息-->
        <properties>
            <!--数据库信息
                用户名,javax.persistence.jdbc.user
                密码,javax.persistence.jdbc.password
                驱动,javax.persistence.jdbc.driver
                数据库地址 javax.persistence.jdbc.url
            -->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="WXL1214"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://my-server:3306/test?characterEncoding=UTF-8"/>

            <!--配置jpa实现方(hibernate)的配置信息
                显示sql : false|true
                自动创建数据库表 : hibernate.hbm2ddl.auto
                    create : 程序运行是创建数据库表(如果有表,先删除再创建)
                    update: 程序运行是创建表(如果有表,不会创建表)
                    none: 不会创建表-->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

 2、JPA测试

package com.dragonwu.test;

import com.dragonwu.entity.Customer;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 * @author DragonWu
 * @date 2022-09-20 15:13
 **/
public class JPATest {

    EntityManagerFactory factory;

    @Before
    public void before(){
        factory= Persistence
                .createEntityManagerFactory("hibernateJPA");

    }

    @Test
    public void testC(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer = new Customer();
        customer.setName("龘龘");

        em.persist(customer);

        tx.commit();
    }
}

3、切换持久化单元的演示

添加另一种jpa的依赖

<!--openjpa-->
        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa-all</artifactId>
            <version>3.2.0</version>
        </dependency>

添加openjpa单元项后的persistence.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">

    <!--需要配置persistence-unit节点
        持久化单元:
            name: 持久化单元名称
            transaction-type: 事务管理的方式
                JTA: 分布式事务管理
                RESOURCE_LOCAL: 本地事务管理
    -->
    <persistence-unit name="hibernateJPA" transaction-type="RESOURCE_LOCAL">

        <!--jpa的实现方式-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <!--需要进行ORM的实体类-->
        <class>com.dragonwu.entity.Customer</class>
        <!--可选配置:配置jpa实现方的配置信息-->
        <properties>
            <!--数据库信息
                用户名,javax.persistence.jdbc.user
                密码,javax.persistence.jdbc.password
                驱动,javax.persistence.jdbc.driver
                数据库地址 javax.persistence.jdbc.url
            -->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="WXL1214"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://my-server:3306/test?characterEncoding=UTF-8"/>

            <!--配置jpa实现方(hibernate)的配置信息
                显示sql : false|true
                自动创建数据库表 : hibernate.hbm2ddl.auto
                    create : 程序运行是创建数据库表(如果有表,先删除再创建)
                    update: 程序运行是创建表(如果有表,不会创建表)
                    none: 不会创建表-->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>

        </properties>
    </persistence-unit>

    <persistence-unit name="openJPA" transaction-type="RESOURCE_LOCAL">

        <!--jpa的实现方式-->
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

        <!--需要进行ORM的实体类-->
        <class>com.dragonwu.entity.Customer</class>
        <!--可选配置:配置jpa实现方的配置信息-->
        <properties>
            <!--数据库信息
                用户名,javax.persistence.jdbc.user
                密码,javax.persistence.jdbc.password
                驱动,javax.persistence.jdbc.driver
                数据库地址 javax.persistence.jdbc.url
            -->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="WXL1214"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://my-server:3306/test?characterEncoding=UTF-8"/>

            <!--配置jpa实现方(openjpa)的配置信息-->
            <!--可以自动生成数据库表-->
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
        </properties>
    </persistence-unit>
</persistence>

使用openJPA我们只需要改变单元项即可,代码耦合性很低,非常适合装配使用。

package com.dragonwu.test;

import com.dragonwu.entity.Customer;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 * @author DragonWu
 * @date 2022-09-20 15:13
 **/
public class JPATest {

    EntityManagerFactory factory;

    @Before
    public void before(){
        factory= Persistence
                .createEntityManagerFactory("openJPA");

    }

    @Test
    public void testC(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer = new Customer();
        customer.setName("DragonWu Master");

        em.persist(customer);

        tx.commit();
    }
}

查看效果:可以看到两种不同的单元项都可以对数据库进行操作,而底层都是基于hibernate来实现的。

springData JPA整合SQLite spring data jpa hibernate_java_05

 4、*HibernateJPI常见操作,测试案例*

package com.dragonwu.test;

import com.dragonwu.entity.Customer;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 * @author DragonWu
 * @date 2022-09-20 15:13
 **/
public class JPATest {

    EntityManagerFactory factory;

    @Before
    public void before(){
        factory= Persistence
                .createEntityManagerFactory("hibernateJPA");

    }

    @Test
    public void testC(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer = new Customer();
        customer.setName("DragonWu Master");

        em.persist(customer);

        tx.commit();
    }

    @Test
    public void testR(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer = em.find(Customer.class,4L);
        //find立即查询
        System.out.println("==============================");
        System.out.println(customer);

        tx.commit();
    }

    @Test
    public void testR_lazy(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer = em.getReference(Customer.class,4L);
        //load延时查询
        System.out.println("==============================");
        System.out.println(customer);

        tx.commit();
    }

    @Test
    public void testU(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer=new Customer();
        customer.setId(5L);
        customer.setName("Jack");

        //如果该id对应的数据存在则更新,否则添加;更新时会先查询是否有变化,若有变化才会更新
        em.merge(customer);

        tx.commit();
    }

    @Test
    public void testU_JPQL(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        //注意这里是类名
        String jpql="UPDATE Customer set name=:name where id=:id";
        em.createQuery(jpql)
                .setParameter("name","好人")
                .setParameter("id",5L)
                .executeUpdate();

        tx.commit();
    }

    @Test
    public void testU_SQL(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        //注意这里是表名
        String sql="UPDATE tb_customer set cus_name=:name where id=:id";
        em.createNativeQuery(sql)
                .setParameter("name","坏人")
                .setParameter("id",5L)
                .executeUpdate();

        tx.commit();
    }

    @Test
    public void testD(){
        EntityManager em=factory.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        tx.begin();

        Customer customer=em.find(Customer.class,5L);
        //这里不支持删除游离态的对象
        em.remove(customer);

        tx.commit();
    }
}