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

来源:互联网 发布:淘宝代购服装是真的吗 编辑:程序博客网 时间:2024/06/04 18:00

一、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 = custPhone;}@Overridepublic 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@Testpublic 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@Testpublic 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@Testpublic 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@Testpublic 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查询:立即加载方式@Testpublic 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查询:延迟加载方式@Testpublic 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)、带条件查询

//查询所有@Testpublic 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();}//查询所有带条件@Testpublic 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();}//查询返回唯一结果@Testpublic 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、删除

//删除@Testpublic 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: * 用此方式 */@Testpublic void test1(){//1.获取EnityManagerEntityManager em = JPAUtil.getEntityManager();//2.使用em的方法获取SessionSession session = em.unwrap(Session.class);//3.获取Connectionsession.doWork(new Work() {@Overridepublic void execute(Connection conn) throws SQLException {System.out.println(conn.getClass().getName());}});}}


原创粉丝点击