目录
一、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
表已自动生成。
单元测试testR
单元测试testR_lazy懒加载,load懒加载当执行到对应查询时系统才会执行查询,而find会先执行查询。
二、SpringData实现JPA的功能
用之前的hibernate,如果我们需要修改持久化层,需要修改很多配置以及代码,由此SpringData推出了JPA的功能。JPA同样是钟规范,需要依赖于他的实现。
1、添加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>
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来实现的。
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();
}
}