JPA(Hibernate)

JPA

1,JPA:Java Persistence API.JPA通过JDK 5.0注解-关系表的映射关系,并将运行期的实体对象持久化到数据库中。JPA是JavaEE中的标准。JPA标准只提供了一套规范,需要有JPA的具体实现,Hibernate实现了JPA2.0标准,所以我们在用JPA的时候,其实用的是Hibernate提供了JPA2.0规范的实现;JPA还有其他实现,比如OpenJPA,各个JPA的实现在使用细节上有一些不同,使用时需要注意;
2,JPA和Hibernate对比:
  1),JPA只是Hibernate的一个子集(支持JPA只是Hibernate中的一个功能),
  2),Hibernate在对象状态,对象映射,对象关系,查询语句上和JPA80%以上都雷同;
  3),Hibernate本身更依赖XML配置,而JPA完全使用Annotation实现;
  4),Hibernate的API和JPA的API有一些区别(关键对象,对象方法);

JPA环境搭建:
1,JPA配置:
persistence.xml文件,放于classpath下META-INF/persistence.xml;
<properties>
hibernate.dialect:方言;
hibernate.show_sql:
hibernate.hbm2ddl.auto:
数据连接配置不能使用hibernate的哈;
  javax.persistence.jdbc.driver:JPA规范的数据库驱动;
  javax.persistence.jdbc.url:JPA规范的URL;
  javax.persistence.jdbc.user:JPA规范的用户名;
  javax.persistence.jdbc.password:JPA规范的密码;
  javax.persistence.validation.mode:设置为auto,避免domain的检查;
2,创建Employee对象,并添加注解
  1),@Entity:标在类上,标明当前实体类是需要JPA管理的一个实体对象,类似<class>
  2),@Table:标在类上,标明当前实体类在数据库中对应的表,类似<class>元素的table属性 ;
3,配置属性,(默认情况下,JPA会管理所有的属性;要规范属性,可以在字段上,也可以在getter方法)
  1),@Id:标明当前属性是OID,类似<id>
  2),@GeneratedValue:标明当前OID使用的主键生成方式,类似<generator>
  3),@Column:标明当前属性对应的列,类似<property>的column属性;
  4),@Temporal:标明当前属性的日期类型;

API使用
一,JPA框架的启动:
创建EntityManagerUtil;
  1),使用Persistence.createEntityManagerFactory("com._520it.jpa")创建EntityManagerFactory;
  (按照persistence.xml中的persistence-unit的name属性加载的)
  2),EntityManagerFactory类似SessionFactory,通过createEntityManager方法创建EntityManager;
  3),EntityManager类似Session,实体类的持久化方法由EntityManager提供
2,完成CRUD;
  1,getTransaction:得到事务对象,并调用begin方法开启事务;

  2,persist:持久化对象;

  3,find:得到对象,相当于get方法;

  4,merge:修改对象,相当于update方法;

  5,createQuery:创建一个Query对象;

  6,调用Query对象的getResultList方法执行查询;

  7,remove:删除一个对象,相当于delete方法;(注意,JPA中只能把持久化对象变为删除状态)

1,配置文件:

  1),JPA的配置文件默认从META-INF/persistence.xml加载;
  hibernate(classpath:hibernate.cfg.xml)
  2),JPA配置文件中,可以配置hibernate的相关配置项(只针对HIBERNATE的JPA实现);

  注意,有些配置只能使用javax.xxx
  3),JPA配置文件中,默认查询classpath下所有实体类,如果需要引入外部的类,才需要配置;

hibernate:要让hibernate管理的实体类,必须把映射文件配置在hibernate.cfg.xml的mapping中;
2,实体对象:

  1),JPA也是ORM框架,不同的是使用注解来完成映射;
  2),JPA中,O直接体现在对象中,所以一般情况下,在注解中一般不写配置或者只配置R部分;
  3),JPA中,最大的好处是不需要给所有属性配置,按需配置;
3,API代码:

  1),JPA的启动方式几乎和Hibernate相同,包括类结构基本一致;
  Persistence --- Configuration;
  EntityManagerFactory --- SessionFactory;
  EntityManager ---- Session

  2),EntityManager上的API和Session基本一致;
  使用entityManager.getDelegate()查看EntityManager的真实实现SessionImpl;
  EntityManager的的委托类其实就是SessionImpl,所以,Hibernate其实就是使用Session来实现了JPA的EntityManager;

单对象映射细节:
persistence.xml:
  1,class:引入需要扫描的类,
  2,exclude-unlisted-classes:是否只扫描配置的类;
  3,jar-file:引入需要扫描的jar包;

		<!-- 手动告诉JPA需要管理那些类 -->
		<class>com.rk1632._12_second_level_cache.Employee</class>
		<!-- exclude-unlisted-classes设置为false,JPA便只会管理class标签引入的实体类 -->
		<exclude-unlisted-classes>false</exclude-unlisted-classes>

对象:
  4,@Entity和@Table;entity的name属性可以为对象起别名;table的name为对象指定表名;
  5,默认情况下,根据@Id标签的位置确定access的方式;可以通过@Access来改变access方式(field);
  6,@Column标签;name属性;
  7,@Temporal标签;设置日期格式;
  8,@Transient标签;设置一个字段不需要持久化;
  9,@Lob标签:设置text类型;相当于hibernate <property type="text">

主键映射细节:

使用JPA内置的主键生成策略:

  1,@GeneratedValue(strategy=GenerationType.AUTO);---- native
  2,@GeneratedValue(strategy=GenerationType.IDENTITY); ------identity
  3,@GeneratedValue(strategy=GenerationType.SEQUENCE); ------sequence
  4,@GeneratedValue(strategy=GenerationType.TABLE);---- TableGenerator
  5,   @Id --- assigned

JPA--HIBERNATE

核心对象对比
  1,EntityManagerFactory: 类似SessionFactory,线程安全,主要用于产生EntityManager,对于一个应用+数据库,一个实例就够了
  2,EntityManager:类似Session,在Hibernate中就是Session的包装类,使用方式和Session相同;线程不安全;
  3,Query/TypedQuery:类似Query对象,部分API有区别;
  4,EntityTransaction:类似Tansaction对象,API相同;

EntityManager方法对比:

session ---> jpa

save; ---> persist:persist方法必须运行在事务中;

update; ---> merge:merge方法必须运行在事务中;

saveOrUpdate ---> erge方法可以把临时对象或者游离对象都变成持久化对象;

delete ---> remove:remove方法必须运行在事务中;

get ---> find:find返回对象类型不是Object;

load ---> getReference:使用延迟加载;

getTransaction; ---> getTranscation:得到的对象是EntityTransaction;

createQuery; ---> createQuery:javax.xxx.Query;TypedQuery

clear ---> clear;

evict ---> detach:把一个指定的持久化对象变成游离对象;

close ---> close;

单向的many2one:

	//<many2one name="dept" column="dept_id">
	//EAGER:迫切的	LAZY:懒,此处fetch设置延迟加载或者不延迟加载
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="DEPT_ID")
	private Department dept;

1,Employee
2,@JoinColumn相当于在many-to-one元素中的column;
3,默认情况下,得many方,JPA会直接使用LEFT JOIN 把one方查询出来;相当于没有延迟加载;
4,@ManyToOne(fetch=FetchType.LAZY)
   @Fetch(FetchMode.SELECT)
  1),manytoone标签上的fetch属性代表是否延迟加载,默认是FetchType.EAGER;如果使用延迟加载,FetchType.LAZY;
  2),fetch标签代表怎么去拿关联的对象,默认情况使用left join直接把many方对应的one方拿到,也可以设置为select,使用两条SQL分别加载many和one;

单向的one2many:
1,JPA中,one2many是使用三张表完成的;
2,从one方拿many,使用延迟加载,仍然使用的PersistenceSet,所以,还是只能使用接口;
3,只能使用集合的size方法来判断是否有many方和one方关联;
4,在关闭EntityManager之前实例化集合;

集合:
1,JPA能够自动根据集合的类型来完成集合的映射;
2,如果集合是Set相当于默认使用<set>来映射;
3,如果集合是List相当于默认使用<bag>来映射;
4,可以使用@OrderBy标签来排序(让JPA按照集合中的类型的某个属性排序)

双向的many2one和one2many;

	//1,one方放弃去维护和many方的关系;---->inverse=true
	//2,one方查询many方的表结构按照many方对应的属性配置查询(one方放弃中间表结构)
	@OneToMany(mappedBy="dept")
	private Set<Employee> es = new HashSet<>();

1,在many方直接使用@ManyToOne标签;
2,在one方,使用@OneToMany(mappedBy="")
  1),mappedBy代表one方放弃对many方关系的维护;
  2),one方放弃自己的中间表结构,使用many方对应的属性的表结构;
3,双向的many2one,one2many就和hibernate中的是一样的了;

JPA级联:

MERGE:
REMOVE:
all:额外的包含了DETACH和PERSIST
在hibernate中的delete-orphan变成了@OneToMany的一个属性:orphanRemoval=true;

DETACH:代表,在主对象上面调用detach方法(把持久化对象变成游离对象,相当于evict),级联的对所有子对象调用detach方法;
PERSIST:代表,在主对象上面调用persist方法,级联的对所有子对象调用persist方法;

many2many:

@Entity
public class Teacher {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	private String name;

	@ManyToMany
	private Set<Student> students = new HashSet<>();
        //省略get/set  ...
}

@Entity
public class Student {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	private String name;

	@ManyToMany(mappedBy="students")
	private Set<Teacher> teachers = new HashSet<>();
        //省略get/set  ...
}

自定义中间表

	@ManyToMany
	//类似于<set table="">
	//name表示中间表的名称
	//joinColumns代表在中间表里面对应自己主键的外键列
	//				name:中间列的外键列的名称
	//				referencedColumnName:参照自己的哪个列(主键列),可以不写
	//inverseJoinColumns代表在中间表里面对应对方主键的外键列
	//				name:中间列的外键列的名称
	//				referencedColumnName:参照对方的哪个列(主键列),可以不写
	@JoinTable(name="TEA_STU",
				[email protected](referencedColumnName="id",name="TEA_ID"),
				[email protected](referencedColumnName="id",name="STU_ID"))
	private Set<Student> students = new HashSet<>();

  

组件关系:

//组合对象
//可嵌入对象,代表这个对象不是一个实体对象,是一个需要嵌入到宿主对象中才有意义的对象
@Embeddable
public class Address {

	private String provice;
	private String city;
	private String street;
        //省略get/set
}

//宿主对象
@Entity
public class Company {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	private String name;

	private Address address;

	//多个相同类型的嵌入对象,需要重写属性列名
	@AttributeOverrides({
			@AttributeOverride(name="city",[email protected](name="REG_CITY")),
			@AttributeOverride(name="provice",[email protected](name="REG_PROVICE")),
			@AttributeOverride(name="street",[email protected](name="REG_STREET"))
	})
	private Address regAddress;
        //省略get/set
}

  

继承关系:
1,默认情况下,JPA使用ONE TABLE的方式来自动完成继承的映射
  1),只需要在整个继承体系的根对象上面添加@Entity和主键映射;
  2),其他所有的子类只需要加上@Entity标签就可以了;
  3),会创建一个鉴别器列,DTYPE,使用类名作为鉴别器的值;
  4),如果要自定义鉴别器列,在根类型上加上@DiscrimnatorColumn
  5),如果自定义了鉴别器列,根类型及所有子类必须添加@DiscriminatorValue

2,使用PER TABLE的方式:
  1),在父类(根类)上使用@Inheritance标签,使用TABLE_PER_CLASS的继承策略;
  2),id的生成策略不能是AUTO或者IDENTITY;
  3),子类只需要添加@Entity,如果要修改子类的表名,@Table;

查询:
1,TypedQuery和Query的区别;TypedQuery主要用于查询一个实体对象,不能使用投影查询;
2,分页:同样使用setFristResult和setMaxResult两个方法;
3,注意,如果使用JPA的查询,使用位置参数,参数的索引是从[1]开始的 (hibernate从[0]开始的)
4,查询总条数之类的只有一条结果的,可以使用getSingleResult方法;
5,如果要使用原生的SQL,直接使用createNativeQuery()

		//如果只查询一种实体对象,建议使用TyedQuery
		TypedQuery query = em.createQuery("select e from Employee e where name like ?", Employee.class);
		//分页的两个方法和Hibernate的query相同
		//List<Employee> list = query.setFirstResult(5).setMaxResults(5).getResultList();
		//System.out.println(list);

		//如果确定结果集只有一行,使用getSingleResult==Hibernate中的uniqueResult
		//query.getSingleResult();

		//JPA中,查询参数的顺序从1开始
		//List<Employee> list = query.setParameter(1, "%松鼠%").getResultList();

		List<Object[]> objs = em.createNativeQuery("select * from Employee", Employee.class).getResultList();
		System.out.println(objs);

  

JPA中的锁;

1,悲观锁;
select for update可以阻止:除了SELECT之外的其他SQL(FOR UPDATE,DML,LOCK IN SHARE MODE);
select lock in share mode可以阻止:DML和FOR UPDATE,LOCK IN SHARE MODE;

在JPA中使用悲观锁,
em.find(Class,id,LockModeType),
LockModeType一般有两种方式:
  1,PESSIMISTIC_READ:LOCK IN SHARE MODE:会通过造成死锁来阻止并发事务执行;
  2,PESSIMISTIC_WRITE:SELECT FOR UPDATE:会延迟另一个事务的执行;(一般使用这种)

在JPA中使用乐观锁.
在对象中添加一个version属性,在上面添加@Version标签就可以了

二级缓存的配置:
1,拷贝二级缓存的jar包;
2,拷贝二级缓存的hibernate的配置文件,

			<!-- 告诉hibernate使用哪个缓存框架作为二级缓存框架 -->
			<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
			<!-- 设置二级缓存前缀 -->
			<property name="hibernate.cache.region_prefix" value="hibernate"/>

3,拷贝ehcache的配置文件(classpath);
4,在需要二级缓存的对象上面加上标签;
  1),Cacheable标签是JPA提供的;
  2),Cache标签,是hibernate提供的,提供了更多的二级缓存控制相关的配置;

@Entity
//Cacheable标签表示需要二级缓存的实体类
@Cacheable
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE,region="hibernate.EMPLOYEE")
public class Employee {
      //省略
}

  

二级缓存的操作:
1,在JPA中,二级缓存是放在EntityManagerFactory上的;
2,entityManagerFactory.getCache()方法得到二级缓存对象;
3,evict(Class):清除指定类型所有数据;
   evict(Class,Object id):清除指定对象;
   evictALL:清除所有二级缓存对象

原文地址:https://www.cnblogs.com/Java0120/p/9906003.html

时间: 2024-10-14 08:42:50

JPA(Hibernate)的相关文章

SpringMVC+Apache Shiro+JPA(hibernate)整合配置

序: 关于标题: 说是教学,实在愧不敢当,但苦与本人文笔有限,实在找不到更合理,谦逊的词语表达,只能先这样定义了. 其实最真实的想法,只是希望这个关键词能让更多的人浏览到这篇文章,也算是对于自己写文章的一个肯定吧.^_^! 关于内容: 再写这系列文章之前,本人和许多人一样都是伸手党,并深深的了解咱伸手党且英文较差的朋友对于新知识的学习及获取中文资料少的痛苦.所以本着"取之于民,共享与民"的原则,记录下实际工作中对SpringMVC+Shiro整合应用的部分心得.本人技术水平有限,仅希望

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(二)基于SpringMVC+Shiro的用户登录权限验证

序: 在上一篇中,咱们已经对于项目已经做了基本的配置,这一篇文章开始学习Shiro如何对登录进行验证. 教学: 一.Shiro配置的简要说明. 有心人可能注意到了,在上一章的applicationContext.xml配置文件中,包含以下配置. <!-- 項目自定义的Realm --> <bean id="shiroDbRealm" class="org.shiro.demo.service.realm.ShiroDbRealm" ><

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(四)基于Shiro验证用户权限,且给用户授权

最新项目比较忙,写文章的精力就相对减少了,但看到邮箱里的几个催更,还是厚颜把剩下的文档补上. 一.修改ShiroDbRealm类,实现它的doGetAuthorizationInfo方法 package org.shiro.demo.service.realm; import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; import org.apache.commons.lang.St

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(三)给Shiro登录验证加上验证码

序: 给Shiro加入验证码,有多种方式,当然你也可以通过继承修改FormAuthenticationFilter类,通过Shiro去验证验证码.具体实现请百度: 应用Shiro到Web Application(验证码实现) 而今天我要说的,既然使用的SpringMVC,为什么不直接在Controller中就处理验证码验证,让事情变的更简单一点呢? 一.新建ValidateCode.java验证码工具类 package org.shiro.demo.util; import java.util.

将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置

配置web.xml,applicationContext.xml, spring-mvc.xml,applicationContext-shiro.xml,而且都有详细的说明. Web.xml是web项目最基本的配置文件,看这个配置,可以快速知道web项目使用什么框架,它就像一个面板,切入我们想用的插件. applicationContext.xml是spring的基本配置,主要配置数据源.JPA实体管理器工厂.事务 spring-mvc.xml是SpringMVC的配置, applicatio

JPA(三):JPA+Hibernate 基础学习

在该系列的第一篇文章中,我们已经提到JPA和Hibernate.下图是两者在系统架构中的作用: 由以上图片我们可以得出两个结论:首先JPA的主要作用就是持久化操作:其次JPA只是一种规范,它需要一种实现,正如上图显示的,Hibernate.oPenJPA等等.简单些,可以说JPA只是一套接口,本身不能完成任何事情. 而这篇博文的主要内容就是对JPA和Hibernate学习的一个总结.首先来看一个最简单的入门demo. 所需jar包: hibernate3.jar hibernate-cglib-

java框架整合例子(spring、spring mvc、spring data jpa、hibernate)

这是自己参考springside开源项目整合的框架,主要整合了spring.spring mvc.spring data jpa.hibernate这几个框架,对于这几个框架其中感觉比较舒服的还是spring data jpa这个框架,这个框架在写dao类的时候,只需要写一个接口声明,spring data jpa会自动的实现其实现类,使用起来比较方便,至于详细的使用方法还请自己百度吧,因为我也不清楚.个人感觉还有一个比较不错的地方就是能够打印sql语句,都知道hibernate打印的sql语句

java(样品集成框架spring、spring mvc、spring data jpa、hibernate)

这是你自己的参考springside集成框架的开源项目.主要的整合spring.spring mvc.spring data jpa.hibernate几个框架,对于这些框架中仍然感觉更舒适spring data jpa该框架,该框架编写dao上课时间,只需要编写一个接口声明,spring data jpa会自己主动的实现事实上现类,使用起来比較方便,至于具体的用法还请自己百度吧,由于我也不清楚. 个人感觉另一个比較不错的地方就是可以打印sql语句,都知道hibernate打印的sql语句并不会

java:LeakFilling(Hibernate)

1.关系型数据库: Oracle / Mysql 数据持久化的技术: IO JDBC XML  ... 主流的持久层框架: Hibernate mybatis---->apache产品 JPA(由EJB 3.0软件专家组开发,奢侈,豪华的解决方案)--->Oracle TopLink---->Oracle(DBA专业管理员) JSF(JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架) JDO(JDO(Java Data Object )是J