Hibernate学习笔记 -- day12 使用JPA实现综合案例

一、JPA和Hibernate中的操作方法对照

1、操作方法对照表


2、JPA主配置文件persistence.xml说明

<?xml version="1.0" encoding="UTF-8"?>  
<persistence xmlns="http://java.sun.com/xml/ns/persistence"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  
    version="1.0">  
    <!--Name属性用于定义持久化单元的名字 (name必选,空值也合法);   
     	transaction-type 指定事务类型(可选)    
     		取值:
     			JTA:默认值
     			RESOURCE_LOCAL
	-->  
    <persistence-unit name="myPersistUnit" transaction-type="RESOURCE_LOCAL">  
        <!-- 描述信息.(可选)   -->
	   <description></description>  
	  
	   <!-- javax.persistence.PersistenceProvider接口的一个实现类(可选) -->  
	   <provider>org.hibernate.ejb.HibernatePersistence</provider>    
	  
	   <!-- Jta-data-source和 non-jta-data-source用于分别指定持久化提供商使用的JTA和/或non-JTA数据源的全局JNDI名称(可选)  --> 
	   <jta-data-source></jta-data-source>  
	   <non-jta-data-source> </non-jta-data-source>  
	  
	   <!-- 声明映射文件的xml所在位置.(可选)  --> 
	   <mapping-file>product.xml</mapping-file>  
	  
	   <!-- 以包含persistence.xml的jar文件为基准的相对路径,添加额外的jar文件.(可选)-->
	   <jar-file>../lib/model.jar</jar-file>  
	  
	   <!-- 显式列出实体类,在Java SE 环境中应该显式列出.(可选)     -->
	   <class>com.domain.Customer</class>  
	   <class>com.domain.LinkMan</class>
	  
	   <!-- 声明是否扫描jar文件中标注了@Enity类加入到上下文.若不扫描,则如下:(可选)  --> 
	   <exclude-unlisted-classes/>  
	  
	   <!--厂商专有属性(可选)   
	   	   我们用的Hibernate,后面都是hibernate.cfg.xml中一些配置
	   -->         
	  <properties>    
       		<!-- 生成DDL的策略 -->
               <property name="hibernate.hbm2ddl.auto" value="update" />  
               <!-- 数据库的连接信息 -->    
               <property name="hibernate.connection.driver_class" 
					    value="com.mysql.jdbc.Driver" />    
               <property name="hibernate.connection.url" 
						value="jdbc:mysql://localhost:3306/hibernate_jpa"/>  
               <property name="hibernate.connection.username" value="root" />    
               <property name="hibernate.connection.password" value="1234" />   
               <!-- 指定方言 -->   
               <property name="hibernate.dialect" 
					    value="org.hibernate.dialect.MySQL5Dialect" />
               <!-- 是否显示SQL语句 -->    
               <property name="hibernate.show_sql" value="false" />
               <!-- 是否格式化SQL语句 -->    
               <property name="hibernate.format_sql" value="true" />   
        </properties>    
    </persistence-unit>  
</persistence>

3、关于JTA和RESOURCE_LOCAL的区别

(1)、JTA

JTA事务(Java Transaction API)是J2EE规范中有关事务的标准。它是容器级别的事务,只能运行在J2EE服务器中。它的最大优势是可以支持分布式的事务,如果系统采用的是分布式的数据库,那么只能选择JTA管理EntityManager事务。

使用JTA管理EntityManager事务时,需要注意以下几个问题。

        JTA事务只能运行在J2EE的环境中,即EJB容器中和Web容器中;而在J2SE环境中只能使用RESOURCE_LOCAL管理事务。

        容器托管的EntityManager对象只能采用JTA的事务,而不能采用RESOURCE_LOCAL事务。

(2)、RESOURCE_LOCAL

RESOURCE_LOCAL事务数据库本地的事务。它是数据库级别的事务,只能针对一种数据库,不支持分布式的事务。对于中小型的应用,可以采用RESOURCE_LOCAL管理EntityManager事务。

使用RESOURCE_LOCAL管理EntityManager事务时需要注意以下几个问题。

        在J2SE环境中,只能使用RESOURCE_LOCAL管理EntityManager事务,并且EntityManager对象是以应用托管方式获得的。

        代码中使用RESOURCE_LOCAL管理事务时,要通过调用EntityManager的getTransaction()方法获得本地事务。

二、搭建环境

1、创建数据库
2、创建java项目,导入jar包



注意:使用maven环境开发只需要导入以下坐标即可导入hibernateJPA所有的包:


<dependencies>
  	<dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-entitymanager</artifactId>
  		<version>5.0.7.Final</version>
  	</dependency>
  	<dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-c3p0</artifactId>
  		<version>5.0.7.Final</version>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>5.1.6</version>
  	</dependency>
  	<dependency>
  		<groupId>junit</groupId>
  		<artifactId>junit</artifactId>
  		<version>4.10</version>
  	</dependency>
  	<dependency>
  		<groupId>log4j</groupId>
  		<artifactId>log4j</artifactId>
  		<version>1.2.12</version>
  	</dependency>
  </dependencies>


三、代码开发

1、编写JPA配置文件

在src下创建 META-INF 文件夹,并创建xml文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"  
    version="2.0">  
    
    <persistence-unit name="myPersistenceUtil" transaction-type="RESOURCE_LOCAL">
    	<!-- 1.配置JPA规范的实现提供者 -->
    	<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    	<!-- 2.实体类的位置 -->
    	<class>cn.itcast.domain.Customer</class>
    	<!-- 3.其余配置都是Hibernate中的配置,只不过配置到了此处 -->
    	<properties>
    		<!-- 1、连接数据库的信息 -->
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa" />
			<property name="hibernate.connection.username" value="root" />
			<property name="hibernate.connection.password" value="1234" />
			<!-- 2、hibernate的基本配置 -->
			<!-- 数据库的方言 -->
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
			<!-- 是否显示SQL语句 -->
			<property name="hibernate.show_sql" value="true" />
			<!-- 是否格式化SQL语句 -->
			<property name="hibernate.format_sql" value="false" />
			<!-- 选择生成DDL语句的策略 -->
			<property name="hibernate.hbm2ddl.auto" value="update" />
			
    	</properties>
    </persistence-unit>
</persistence>

2、编写实体类

package cn.itcast.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
 * 客户的实体类
 *
 */
@Entity
@Table(name="cst_customer")
public class Customer implements Serializable {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="cust_id")
	private Long custId;
	@Column(name="cust_name")
	private String custName;
	@Column(name="cust_source")
	private String custSource;
	@Column(name="cust_industry")
	private String custIndustry;
	@Column(name="cust_level")
	private String custLevel;
	@Column(name="cust_address")
	private String custAddress;
	@Column(name="cust_phone")
	private String custPhone;
	
	
	public Long getCustId() {
		return custId;
	}
	public void setCustId(Long custId) {
		this.custId = custId;
	}
	public String getCustName() {
		return custName;
	}
	public void setCustName(String custName) {
		this.custName = custName;
	}
	public String getCustSource() {
		return custSource;
	}
	public void setCustSource(String custSource) {
		this.custSource = custSource;
	}
	public String getCustIndustry() {
		return custIndustry;
	}
	public void setCustIndustry(String custIndustry) {
		this.custIndustry = custIndustry;
	}
	public String getCustLevel() {
		return custLevel;
	}
	public void setCustLevel(String custLevel) {
		this.custLevel = custLevel;
	}
	public String getCustAddress() {
		return custAddress;
	}
	public void setCustAddress(String custAddress) {
		this.custAddress = custAddress;
	}
	public String getCustPhone() {
		return custPhone;
	}
	public void setCustPhone(String custPhone) {
		this.custPhone = custPhone;
	}
	@Override
	public String toString() {
		return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
				+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
				+ ", custPhone=" + custPhone + "]";
	}
}

3、编写JPA工具类

package cn.itcast.utils;

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

/**
 * JPA的工具类:
 * 	它里面要做的事情和hibernate的工具类是一样的
 * 		1、创建EnitytManagerFactory(就相当于Hibernate的SessionFactory)
 * 		2、使用工厂生产一个EntityManager,并返回。(就相当于Hibernate的Session)
 *
 */
public class JPAUtil {
	
	private static EntityManagerFactory factory;
	/**
	 * 初始化实体管理器工厂
	 */
	static{
		factory = Persistence.createEntityManagerFactory("myPersistenceUtil");
	}
	
	/**
	 * 返回一个实体管理器
	 * @return
	 */
	public static EntityManager getEntityManager(){
		return factory.createEntityManager();
	}
	
	
	public static void main(String[] args) {
		getEntityManager();
	}
}

四、JPA的CRUD操作

1、保存

	//保存1
	@Test
	public void test1(){
		Customer c = new Customer();
		c.setCustName("传智播客");
		c.setCustLevel("VIP客户");
		c.setCustSource("网络");
		c.setCustIndustry("IT教育");
		c.setCustAddress("昌平区北七家");
		c.setCustPhone("010-43583489");
		
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行保存操作
		em.persist(c);
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}
	//保存2
	@Test
	public void test2(){
		Customer c = new Customer();
		c.setCustName("TBD云集中心");
		c.setCustLevel("VIP客户");
		c.setCustSource("网络");
		c.setCustIndustry("商业办公");
		c.setCustAddress("昌平区北七家");
		c.setCustPhone("010-43583489");
		
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行保存操作
		em.merge(c);
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}

2、更新

	//更新1
	@Test
	public void test5(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行查询操作:使用的是立即加载的策略
		Customer c = em.find(Customer.class, 1L);
		//Customer c1 = em.find(Customer.class, 1L);此时不会去查询,因为缓存中有数据
		//System.out.println(c == c1);返回的是true
		//修改内容
		c.setCustName("传智专修学院");
		
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}
	
	
	//更新2
	@Test
	public void test6(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行查询操作:使用的是立即加载的策略
		Customer c = em.find(Customer.class, 1L);//持久态
		//清空:清空EntityManager中的所有缓存对象。
		em.clear();//一级缓存中没有数据了
		//修改内容
		c.setCustName("传智播客");//脱管态
		//合并两个对象
		em.merge(c);//合并操作
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}

3、查询

(1)、根据id查询

	//根据id查询:立即加载方式
	@Test
	public void test3(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行查询操作:使用的是立即加载的策略
		Customer c = em.find(Customer.class, 1L);
		System.out.println(c);
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}
	
	
	//根据id查询:延迟加载方式
	@Test
	public void test4(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行查询操作:使用的是延迟加载的策略
		Customer c = em.getReference(Customer.class, 1L);
		System.out.println(c);
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}

(2)、带条件查询

	//查询所有
	@Test
	public void test8(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		/*
		 * 4.使用JPA的Query实现查询所有
		 * 		em.createQuery(String JPQL);
		 * 		参数是JPQL  JPA Query Language
		 * 		写法:
		 * 			SQL: select * from cst_customer c
		 * 			HQL: from Customer
		 * 			JPQL:select c from Customer c
		 *  JPQL也是把表名称换成实体类名称,把列名换成实体类的属性名称。
		 *  JPQL不支持select *,要想查询所有,需要写别名
		 */
		Query query = em.createQuery("select c from Customer c ");
		//获取结果集
		List list = query.getResultList();
		for(Object o : list){
			System.out.println(o);
		}
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}
	
	
	//查询所有带条件
	@Test
	public void test9(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.使用JPA的Query实现查询所有
		Query query = em.createQuery("select c from Customer c where custName like ? and custLevel = ? ");
		//设置参数占位符
		query.setParameter(1, "%传%");
		query.setParameter(2, "VIP客户");
		//获取结果集
		List list = query.getResultList();
		for(Object o : list){
			System.out.println(o);
		}
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}
	
	
	
	//查询返回唯一结果
	@Test
	public void test10(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.使用JPA的Query实现查询所有
		Query query = em.createQuery("select count(c) from Customer c ");
		//获取唯一的结果
		Object result = query.getSingleResult();
		System.out.println(result);
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}

4、删除

	//删除
	@Test
	public void test7(){
		//1.获取实体类管理器
		EntityManager em = JPAUtil.getEntityManager();
		//2.获取事务对象
		EntityTransaction tx = em.getTransaction();
		//3.开启事务
		tx.begin();
		//4.执行查询操作:使用的是立即加载的策略
		Customer c = em.find(Customer.class, 1L);//持久态
		//删除操作
		em.remove(c);
		//5.提交事务
		tx.commit();
		//6.释放资源
		em.close();
	}

五、JPA使用C3P0连接池

1、在xml配置文件中加入连接池提供者

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"  
    version="2.0">  
    
    <persistence-unit name="myPersistenceUtil" transaction-type="RESOURCE_LOCAL">
    	<!-- 1.配置JPA规范的实现提供者 -->
    	<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    	<!-- 2.实体类的位置 -->
    	<class>cn.itcast.domain.Customer</class>
    	<!-- 3.其余配置都是Hibernate中的配置,只不过配置到了此处 -->
    	<properties>
    		<!-- 1、连接数据库的信息 -->
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/day39_ee247_jpa" />
			<property name="hibernate.connection.username" value="root" />
			<property name="hibernate.connection.password" value="1234" />
			<!-- 2、hibernate的基本配置 -->
			<!-- 数据库的方言 -->
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
			<!-- 是否显示SQL语句 -->
			<property name="hibernate.show_sql" value="true" />
			<!-- 是否格式化SQL语句 -->
			<property name="hibernate.format_sql" value="false" />
			<!-- 选择生成DDL语句的策略 -->
			<property name="hibernate.hbm2ddl.auto" value="update" />
			<!-- 配置连接池的提供商 -->
			<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
    	</properties>
    </persistence-unit>
</persistence>

2、编写测试类

package cn.itcast.test;

import java.sql.Connection;
import java.sql.SQLException;

import javax.persistence.EntityManager;

import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.junit.Test;

import cn.itcast.utils.JPAUtil;

/**
 * JPA的C3P0配置验证
 * @author zhy
 *
 */
public class JPADemo2 {

	/**
	 * 当我们使用JPA规范,同时使用的是Hibernate实现时
	 * 在这之中想要使用Session:
	 * 	用此方式
	 */
	@Test
	public void test1(){
		//1.获取EnityManager
		EntityManager em = JPAUtil.getEntityManager();
		//2.使用em的方法获取Session
		Session session = em.unwrap(Session.class);
		//3.获取Connection
		session.doWork(new Work() {
			@Override
			public void execute(Connection conn) throws SQLException {
				System.out.println(conn.getClass().getName());
			}
		});
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值