标签:
什么是JPA:
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate、TopLink等ORM框架的基础上发展而来的,具有易于使用、伸缩性强等优点。从目前的开发社区的反应上看,JPA受到了极大的支持和赞扬,其中就包括了Spring与EJB3.0的开发团队。着眼未来几年的技术走向,JPA作为ORM领域标准化整合者的目标应该不难实现。
JPA的总体思想和现有Hibernate、TopLink等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:
ORM映射元数据
JPA支持XML和JDK 5.0注释(也可译作注解)两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
Java持久化API用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者可以从繁琐的JDBC和SQL代码中解脱出来。
查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
提示: JPA不是一种新的ORM框架,他的出现只是用于规范现有的ORM技术,他不能取代现有的Hibernate、TopLink等ORM框架。相反,在采用JPA开发时,我们仍将使用到这些ORM框架,只是此时开发出来的应用不再依赖于某个持久化提供商。应用可以在不修改代码的情况下在任何JPA环境下运行,真正做到低耦合,可扩展的程序设计。
JPA工程
所需JAR包
Hiberante核心包(8个文件)
hibernate-distribution-3.3.1.GA
---------------------------------------------
hibernate3.jar
lib\bytecode\cglib\hibernate-cglib-repack-2.1_3.jar
lib\required\*.jar
Hiberante注解包(3个文件):hibernate-annotations-3.4.0.GA
------------------------------------------------------------------------------------
hibernate-annotations.jar
lib\ejb3-persistence.jar、hibernate-commons-annotations.jar
Hibernate针对JPA的实现包(3个文件):hibernate-entitymanager-3.4.0.GA
------------------------------------------------------------------------------------------------------
hibernate-entitymanager.jar
lib\test\log4j.jar、slf4j-log4j12.jar
JPA配置文件
JPA规范要求在类路径的META-INF目录下放置persistence.xml,文件的名称是固定的,配置模版如下:
<?xml version="1.0"?>
<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">
<persistence-unit name="itcast" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/itcast?useUnicode=true&characterEncoding=UTF-8"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>JPA实体类:
/**在实体bean中用注解@Entity来指定实体以让jpa知道生成数据库中的表*/
@Entity
/**在实体类的前面用注解@Table(name="xx")指定生成表的名字*/
@Table(name = "t_person")
public class Person implements Serializable {
private Integer id;
private String name;
private Date birthday;
private Gender gender = Gender.MAN;// 设置默认值
private String info;
private byte[] file;
private String imagePath;
/**Table效率不高*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
/**在实体bean中用注解@Column(length,nullable,name)指定数据库中的表的字段的长度,是否为空即字段的名字*/
@Column(name = "person_name", nullable = true, length = 30)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**反射用,默认无参构造函数*/
public Person() {
super();
}
/**在实体类中用注解@Temporal(TemporalType.Date)指定生日的时间类型*/
@Column(name = "birthday", nullable = true)
@Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Column(length = 5, nullable = true)
@Enumerated(EnumType.ORDINAL)
/**@Enumerated(EmumType.STRING)注解指定枚举类型(保存到数据库中是字符串)
@Enumerated(EnumType.ORDINAL)注解指定枚举类型(保存到数据库中是索引,从0开始)
*/
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
/**@Lob声明属性对应的数据库字段为大文本类型,可以存放大的数据(文本和字节)*/
@Lob
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Lob
/**是否把数据装载到内存中延迟初始化,第一次访问的时候在加载数据,一般用在大数据存放*/
@Basic(fetch=FetchType.LAZY)
/**FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载*/
public byte[] getFile() {
return file;
}
public void setFile(byte[] file) {
this.file = file;
}
/**指定这个字段不跟数据库字段进行映射和关联*/
@Transient
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public Person(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
} 实体引用枚举
public enum Gender {
MAN, WOMEN
}
/**
* jpa四种状态
* 1.new 新建
* 2.托管
* 3.游离(脱管)
* 4.删除
*
*/
public class PersonTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void test() {
fail("Not yet implemented");
}
/**
* 增加数据
*/
@Test
public void save() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
/** 读取数据不要开启事务,只要有更改数据的动作才需要开启事务*/
em.getTransaction().begin();
//new 新建 new一个实例
Person p=new Person("张三");
//持久化
em.persist(p);////插入
em.getTransaction().commit();
em.close();
factory.close();
}
/**
* 删除数据
*/
@Test
public void remove() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Person p=em.find(Person.class, 1);
em.remove(p);//删除(注意有外键约束时,需要先解除外键约束才能删除)
em.getTransaction().commit();
em.close();
factory.close();
}
/**
* 更新数据:方法一
*/
@Test
public void updatePerson() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Person p=em.find(Person.class, 2);
p.setName("老张test");//(1).跟事务关联在一起了(2)对象处于托管状态,可以直接保存到数据库
em.getTransaction().commit();
em.refresh(p);//进行数据库刷新,拿出最新的数据
System.out.println(p);
em.close();
factory.close();
}
/**
* 更新数据:方法二
*/
@Test
public void updatePerson2() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Person p=em.find(Person.class, 2);
em.clear();////把事务管理器中的所有实体变成游离状态
p.setName("老张");//现在还是不可以,实体还是处于游离状态
em.merge(p);//把游离状态中的实体bean同步到数据库
em.getTransaction().commit();
em.close();
factory.close();
}
/**
* 查看数据:方法一
*/
@Test
public void getPerson() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
Person p=em.find(Person.class, 1);
System.out.println(p);//如果找不到,返回null值
em.close();
factory.close();
}
/**
* 查看数据:方法二
*/
@Test
public void getPerson2() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
Person p=em.getReference(Person.class, 0);//1.没有值不出现异常
System.out.println(p);//获取属性值时,如果找不到,出现异常 //2出现异常
em.close();
factory.close();
}
/**
* 查看数据:返回结果集
*/
@Test
public void queryAll() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Query query=em.createQuery("select o from Person o");
List<Person> list=query.getResultList();
for(Person p:list){
System.out.println(p);
}
em.close();
factory.close();
}
/**
* 查看数据:返回单条数据
*/
@Test
public void querySigle() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
Query query=em.createQuery("select o from Person o where o.id=?1");//必须有select o,id=等于后面不要直接写值以免sql注入
query.setParameter(1, 2);
/**
* (1)匿名查询用:id
(2)未参数查询?1即:where o.id=?1//指明?的值从索引1开始
*/
Person p=(Person) query.getSingleResult();//获取单条记录
System.out.println(p);
em.close();
factory.close();
}
/**
* 查询删除
*/
@Test
public void queryDelete() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Query query=em.createQuery("delete from Person o where o.id=?1");
query.setParameter(1, 2);//位置参数
int i=query.executeUpdate();
System.out.println("受影响的行数 :"+i);
em.close();
factory.close();
}
/**
* 查询更新
*/
@Test
public void queryUpdate() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Query query=em.createQuery("update Person o set o.name=:name where o.id=:id");
query.setParameter("name", "五五");//匿名参数
query.setParameter("id", 3);
int i=query.executeUpdate();
System.out.println("受影响的行数 :"+i);
em.close();
factory.close();
}
}
JPA总结
首先,JPA不是ORM框架,而是SUN官方提出的JAVA持久化规范。JPA整合了现有的Hibernate、TopLink等ORM框架,具有易于使用、伸缩性
强等优点。下面我们就来学习关于JPA的知识。
1. JPA规范要求在类路径的META-INF目录下放置persistence.xml,文件的名称是固定的,配置模版可见hibernate-entitymanager开发包
2. JPA ORM映射元素数据有XML和注解两种方式,这里我们学习基于注解的方式,那么我们来谈谈JPA有哪些常用的注解
1) 在实体bean中用注解@Entity来指定实体以让jpa知道生成数据库中的表
2) 在实体bean中用注解@Column(length,nullable,name)指定数据库中的表的字段的长度,是否为空即字段的名字
3) 在实体类的前面用注解@Table(name="xx")指定生成表的名字
4) 在实体类中用注解@Temporal(TemporalType.Date)指定生日的时间类型
5) @Enumerated(EmumType.STRING//保存到数据库中是索引还是字符串)注解指定枚举类型
6) @Lob声明属性对应的数据库字段为大文本类型,可以存放大的数据(文本和字节)
7) @Transient不成为持久化字段及不跟数据库中的字段形成映射
8) @Basic(fetch=FetchType.LAZY)//是否把数据装载到内存中延迟初始化,第一次访问的时候在加载数据,一般用在大数据存放
9) @Embeddable指定联合组键
3. JPA的增删改查:
1) 读取数据不要开启事务,只要有更改数据的动作才需要开启事务
2) 增加数据:em.persist(new Person("老黎"));//插入
3) 删除数据:em.remove(person); //删除(注意有外键约束时,需要先解除外键约束才能删除)
4) 更新数据:
方法一:Person person = em.find(Person.class,1);
person.setName("老黎");(1).跟事务关联在一起了(2)对象处于托管状态
方法二:Person person = em.find(Person.class,1);
em.clear();//把事务管理器中的所有实体变成游离状态
person.setName("老黎");//现在还是不可以,实体还是处于游离状态
em.merge(person);//把游离状态中的实体bean同步到数据库
标签:
原文地址:http://blog.csdn.net/hardworking0323/article/details/51105838