1. JPA规范与ORM框架之间的联系
JPA规范并不属于EJB3规范,它是一套完全独立的规范,不仅可以在基于EJB的JavaEE应用程序中使用,而且完全可以在普通JavaSE应用程序中使用。
JPA事务管理总结:
运行环境 类型 | J2EE环境 | J2SE环境 | |
EJB容器 | Web容器 | ||
应用托管的 EntityManager | JTA, RESOURCE_LOCAL | JTA, RESOURCE_LOCAL | RESOURCE_LOCAL |
容器托管的 EntityManager | JTA | 不支持 | 不支持 |
常用的3种组件:
1). 实体:增加了orm.xml映射文件或者Annotation的POJO.
2). EntityManager:类似于Hibernate框架的Session,使用其对实体进行操作时,JPA规范才可以将这种操作转换为对底层数据库的操作。
3). JPQL查询:类似于Hibernate提供的HQL查询语言。
#1. TopLink JPA实现(Net Beans创建Java Project, 项目名称:JpaQsTopLink)
实体News.java
package org.crazyit.model; import javax.persistence.*; @Entity @Table(name = "news_table") public class News { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "NEWS_TITLE", length = 50) private String title; @Column(nullable = true) private String content; //构造器 public News() { } //标识属性的setter和getter方法 public void setId(int id) { this.id = id; } public int getId() { return (this.id); } //消息标题的setter方法和getter方法 public void setTitle(String title) { this.title = title; } public String getTitle() { return (this.title); } //消息内容的setter方法和getter方法 public void setContent(String content) { this.content = content; } public String getContent() { return (this.content); } }
META-INF/persistence.xml(mysql)
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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"> <persistence-unit name="qs" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.crazyit.model.News</class> <properties> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/javaee"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="******"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/> <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>
META-INF/persistence.xml(sqlserver)
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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"> <persistence-unit name="qs" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.crazyit.model.News</class> <properties> <property name="hibernate.connection.driver_class" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="hibernate.connection.url" value="jdbc:sqlserver://127.0.0.1:1433;database=javaee"/> <property name="hibernate.connection.username" value="javaweb"/> <property name="hibernate.connection.password" value="******"/> <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/> <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>
JpaQs.java
package lee; import java.util.List; import javax.persistence.*; import org.crazyit.model.*; public class JpaQs { //一个持久单元对应一个EntityManagerFactory private static final EntityManagerFactory emfactory = Persistence.createEntityManagerFactory("qs"); public static void main(String[] args) { EntityManager em = emfactory.createEntityManager(); //创建一个News实体 News news = new News(); news.setTitle("Crazy Java Union Created!"); news.setContent("Crazy Java Union Created! Every question will be answered!"); try { System.out.println(news); //开启事务 em.getTransaction().begin(); //保存实体 news = em.merge(news); System.out.println(news); news.setTitle("aaaa"); //提交事务 em.getTransaction().commit(); } finally { em.close(); } } }
#2. Hibernate JPA实现(Net Beans创建Java Project, 项目名称:JpaQsHibernate)
News.java(参见#1)
META-INF/persistence.xml(mysql)
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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"> <persistence-unit name="qs" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.crazyit.model.News</class> <properties> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/javaee"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="******"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/> <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>
META-INF/persistence.xml(sqlserver)
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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"> <persistence-unit name="qs" transaction-type="RESOURCE_LOCAL"> <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider> <class>org.crazyit.model.News</class> <properties> <property name="toplink.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="toplink.jdbc.url" value="jdbc:sqlserver://127.0.0.1:1433;database=javaee"/> <property name="toplink.jdbc.user" value="javaweb"/> <property name="toplink.jdbc.password" value="******"/> <!-- 指定操作的目标数据库类型,可指定为auto,让JPA自动识别 该属性相当于指定数据库方言,该属性值默认就是Auto(区分大小写) --> <property name="toplink.target-database" value="Auto"/> <property name="toplink.ddl-generation" value="create-tables"/> <property name="toplink.jdbc.write-connections.max" value="10"/> <property name="toplink.jdbc.write-connections.min" value="5"/> <property name="toplink.jdbc.read-connections.max" value="2"/> <property name="toplink.jdbc.read-connections.min" value="2"/> <property name="toplink.jdbc.read-connections.shared" value="false"/> </properties> </persistence-unit> </persistence>
JpaQs.java
package lee; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; //import javax.persistence.*; import org.crazyit.model.*; public class JpaQs { //一个持久单元对应一个EntityManagerFactory private static final EntityManagerFactory emfactory = Persistence.createEntityManagerFactory("qs"); public static void main(String[] args) { final EntityManager em = emfactory.createEntityManager(); News news = new News(); news.setTitle("Crazy Java Union Created!"); news.setContent("Crazy Java Union Created! Every question will be answered!"); try { //开启事务 em.getTransaction().begin(); //保存实体 em.persist(news); //提交事务 em.getTransaction().commit(); } finally { em.close(); } } }
#3. Hibernate XML JPA实现(Net Beans创建Java Project, 项目名称:JpaQsHibernateXml)
News.java
package org.crazyit.model; import javax.persistence.*; public class News { private int id; private String title; private String content; public News() { } public void setId(int id) { this.id = id; } public int getId() { return (this.id); } public void setTitle(String title) { this.title = title; } public String getTitle() { return (this.title); } public void setContent(String content) { this.content = content; } public String getContent() { return (this.content); } }
News.orm.xml
<?xml version="1.0" encoding="GBK"?> <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0"> <persistence-unit-metadata> <persistence-unit-defaults> <access>PROPERTY</access> </persistence-unit-defaults> </persistence-unit-metadata> <package>org.crazyit.model</package> <entity class="News"> <table name="news_table"/> <attributes> <id name="id"> <generated-value strategy="IDENTITY"/> </id> <basic name="title"> <column name="news_title" length="50"/> </basic> <basic name="content"/> </attributes> </entity> </entity-mappings>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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"> <persistence-unit name="qs" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <mapping-file>org/crazyit/model/News.orm.xml</mapping-file> <properties> <property name="hibernate.connection.driver_class" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="hibernate.connection.url" value="jdbc:sqlserver://127.0.0.1:1433;database=javaee"/> <property name="hibernate.connection.username" value="javaweb"/> <property name="hibernate.connection.password" value="P@66word"/> <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/> <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>
JpaQs.java
package lee; import java.util.List; import javax.persistence.*; import org.crazyit.model.*; public class JpaQs { private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("qs"); public static void main(String[] args) { EntityManager em = emf.createEntityManager(); try { em.getTransaction().begin(); News news = em.find(News.class, 1); news.setContent("疯狂Java联盟的网址:crazyit.org!!"); em.getTransaction().commit(); } finally { em.close(); } } }
2. 实体类的要求和状态迁移