您的位置:首页 > 其它

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

2017-08-03 13:38 549 查看

一、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包



三、代码开发

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 = custPho
4000
ne;
}
@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());
}
});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐