• JPA之hibernate4.2.4之简单测试


        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.Finaldocumentationquickstarten-UShtml_singleindex.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>

       目前hibernate 4.2.4只支持oracle10g  虽然我用的是oracle11g 但是这里写成10g 同样可以照常工作 如果改成11g的话 hibernate不识别 会报错


    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 (?, ?, ?, ?, ?, ?)

    通过控制台输出可以看到 hibernate底层使用了插入语句


     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=?

    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);
    		//删除
    		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的简单实现 记录学习的脚步 好晚了  睡觉了 

  • 相关阅读:
    JS实现延迟载入图片
    三星指纹识别新专利:手势打开不同应用
    与计算机之间的另一种沟通方式 ——“手势识别”
    手写数字识别系统之图像分割
    机器学习实战八大分类器识别树叶带源码
    构建CTC语音识别解码网络
    MFC CListCtrl 条目取消选中
    C++ 将输入的字符串中英文大写字母改成对应小写字母,并且过滤掉非英文字母字符
    C++遍历SQLite数据库下的所有表名 .
    MFC 操作注册表 Open QueryValue等
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275595.html
Copyright © 2020-2023  润新知