jpa是sun官网提出的java持久层规范,但是它不是一个持久层产品,它的实现还需要持久层产品的支持,例如hibernate,toplink等orm产品.jpa与hibernate的关系,就例如jdbc与oracle的jdbc驱动实现一样,一个是接口、规范,一个是具体的实现.
现在利用jpa接口编程,利用hibernate作为底层实现,操作oracle 11g,实现简单的增删改查
1.新建一个java工程,名为JpaHibernateOracleTest,然后将需要的jar包拷贝到工程下,如下:
这个用到的jar包 在官网下载包里面都有 前面博客曾有介绍 http://blog.csdn.net/undergrowth/article/details/9963529 只是多了一个ojdbc6.jar 这个是连接oracle数据库需要用到的jar oracle官网也有http://www.oracle.com/technetwork/cn/database/enterprise-edition/jdbc-112010-094555-zhs.html
2.建立jpa的配置文件 因为jpa在加载时 默认会在类路径下的META-INF/ 目录下查找名为persistence.xml的配置文件进行加载
所以在src目录下新建META-INF文件夹 然后在建立persistence.xml的文件
修改配置文件 在下载hibernate的解压包里面 hibernate-release-4.2.4.Final\documentation\quickstart\en-US\html_single\index.html 里面就有关于jpa配置的模板 还有一些其他的配置属性 不清楚的 查看前面博客有介绍http://blog.csdn.net/undergrowth/article/details/9963529
将persistence.xml配置文件修改如下:
<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="under"> <properties> <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/> <property name="hibernate.connection.username" value="under_test" /> <property name="hibernate.connection.password" value="under_test" /> <property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:ganew" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> </properties> </persistence-unit> </persistence>
3.使用注解的方式编写实体类 具体如下:
Student.java
package com.undergrowth; import java.util.Date; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; //Entity表明Student类为一个实体类 Table的name属性用于指定生成的表名 @Entity @Table(name="studentInfo") public class Student { //Id用于指定id属性为实体类的主键 //GeneratedValue用于表示主键自动产生 //因为连接的是oracle数据库 所以使用序列方式产生主键 @Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Integer id; //Column的length指定name字段可以容纳多少个字符 nullable表示不可以为空 @Column(length=20,nullable=false) private String name; //以日期的格式建立该字段 @Temporal(TemporalType.DATE) @Column(nullable=false) private Date birthday; @Column(nullable=false) private Integer age; //EnumType.STRING表示存储的是枚举常量的字符串值 @Enumerated(EnumType.STRING) @Column(nullable=false,length=8) private Gender sex; //Lob表示大字符对象 lazy使用延迟加载 @Lob @Basic(fetch=FetchType.LAZY) private String describe; public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Gender getSex() { return sex; } public void setSex(Gender sex) { this.sex = sex; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } //用于给反射使用 public Student(){} public Student(String name, Date birthday, Integer age, Gender sex, String describe) { super(); this.name = name; this.birthday = birthday; this.age = age; this.sex = sex; this.describe = describe; } }
枚举类:
Gender.java
package com.undergrowth; public enum Gender { 男,女 }
4.建立junit测试代码
package com.junit; import static org.junit.Assert.*; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; public class JunitTest { @Test public void test() { //通过配置文件中的<persistence-unit name="under">持久单元名,获取实体管理器工厂 EntityManagerFactory factory=Persistence.createEntityManagerFactory("under"); //关闭实体管理器工厂 factory.close(); } }在test测试方法中加入以上两句话 就可测试环境是否已经成功搭建 并且建立表结构 也是在创建实体管理器工厂的时候
如果没有问题 在oracle数据库中 应该看到studentinfo的表结构 如下
产生主键的序列:
现在接着修改测试的test函数 实现增删改查
修改如下:
添加记录
package com.junit; import static org.junit.Assert.*; import java.text.ParseException; import java.text.SimpleDateFormat; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; import com.undergrowth.Gender; import com.undergrowth.Student; public class JunitTest { @Test public void test() { //通过配置文件中的<persistence-unit name="under">持久单元名,获取实体管理器工厂 EntityManagerFactory factory=Persistence.createEntityManagerFactory("under"); //获取管理器实体 EntityManager manager=factory.createEntityManager(); try { addStudent(manager); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } //关闭管理器实体 manager.close(); //关闭实体管理器工厂 factory.close(); } private void addStudent(EntityManager manager) throws ParseException { // TODO Auto-generated method stub //打开事务 manager.getTransaction().begin(); Student student=new Student("undergrowth", new SimpleDateFormat("yyyy-MM-dd").parse("1999-1-2"), 20, Gender.男, "读书"); manager.persist(student); //提交事务 manager.getTransaction().commit(); } }
Hibernate: select hibernate_sequence.nextval from dual Hibernate: insert into studentInfo (age, birthday, name, sex, id, describe) values (?, ?, ?, ?, ?, ?)
oracle 数据效果
剩下的删除、更新、查询如下:
package com.junit; import static org.junit.Assert.*; import java.text.ParseException; import java.text.SimpleDateFormat; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; import com.undergrowth.Gender; import com.undergrowth.Student; public class JunitTest { @Test public void test() { //通过配置文件中的<persistence-unit name="under">持久单元名,获取实体管理器工厂 EntityManagerFactory factory=Persistence.createEntityManagerFactory("under"); //获取管理器实体 EntityManager manager=factory.createEntityManager(); /*try { addStudent(manager); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ //调用更新 updateStudent(manager); //关闭管理器实体 manager.close(); //关闭实体管理器工厂 factory.close(); } private void addStudent(EntityManager manager) throws ParseException { // TODO Auto-generated method stub //打开事务 manager.getTransaction().begin(); Student student=new Student("undergrowth", new SimpleDateFormat("yyyy-MM-dd").parse("1999-1-2"), 20, Gender.男, "读书"); manager.persist(student); //提交事务 manager.getTransaction().commit(); } private Student selectStudent(EntityManager manager) { // TODO Auto-generated method stub //通过实体类的主键找到实体类 Student student=manager.find(Student.class, 270); return student; } private void updateStudent(EntityManager manager) { // TODO Auto-generated method stub //打开事务 manager.getTransaction().begin(); Student student=selectStudent(manager); student.setName("刘德华"); //处于事务管理关联并且实体类处于托管状态 才可以更新到数据库中 //提交事务 manager.getTransaction().commit(); } }
控制台输出:
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.birthday as birthday3_0_0_, student0_.describe as describe4_0_0_, student0_.name as name5_0_0_, student0_.sex as sex6_0_0_ from studentInfo student0_ where student0_.id=? Hibernate: update studentInfo set age=?, birthday=?, name=?, sex=?, describe=? where id=?
删除:
package com.junit; import static org.junit.Assert.*; import java.text.ParseException; import java.text.SimpleDateFormat; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; import com.undergrowth.Gender; import com.undergrowth.Student; public class JunitTest { @Test public void test() { //通过配置文件中的<persistence-unit name="under">持久单元名,获取实体管理器工厂 EntityManagerFactory factory=Persistence.createEntityManagerFactory("under"); //获取管理器实体 EntityManager manager=factory.createEntityManager(); /*try { addStudent(manager); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ //调用更新 //updateStudent(manager); //删除 deleteStudent(manager); //关闭管理器实体 manager.close(); //关闭实体管理器工厂 factory.close(); } private void addStudent(EntityManager manager) throws ParseException { // TODO Auto-generated method stub //打开事务 manager.getTransaction().begin(); Student student=new Student("undergrowth", new SimpleDateFormat("yyyy-MM-dd").parse("1999-1-2"), 20, Gender.男, "读书"); manager.persist(student); //提交事务 manager.getTransaction().commit(); } private Student selectStudent(EntityManager manager) { // TODO Auto-generated method stub //通过实体类的主键找到实体类 Student student=manager.find(Student.class, 270); return student; } private void updateStudent(EntityManager manager) { // TODO Auto-generated method stub //打开事务 manager.getTransaction().begin(); Student student=selectStudent(manager); student.setName("刘德华"); //处于事务管理关联并且实体类处于托管状态 才可以更新到数据库中 //提交事务 manager.getTransaction().commit(); } private void deleteStudent(EntityManager manager) { // TODO Auto-generated method stub //打开事务 manager.getTransaction().begin(); Student student=selectStudent(manager); manager.remove(student); //处于事务管理关联并且实体类处于托管状态 才可以更新到数据库中 //提交事务 manager.getTransaction().commit(); } }
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.birthday as birthday3_0_0_, student0_.describe as describe4_0_0_, student0_.name as name5_0_0_, student0_.sex as sex6_0_0_ from studentInfo student0_ where student0_.id=? Hibernate: delete from studentInfo where id=?
对于查询的话 除了find以外 还可使用getReference
对于更新与删除 能够与数据库同步的原因在于
第一:实体对象处于实体对象管理器之下,即实体对象处于托管状态
第二: 实体管理器与事务关联
二者缺一 实体对象都没有办法与数据库同步
以上即是jpa的简单实现 记录学习的脚步 好晚了 睡觉了