Day4
4. EntityManager接口
find(Class<T> entityClass, Object primaryKey):<T> T //根据主键查找,没有符合条件记录,返回null
Hibernate:get();
getReference(Class<T> entityClass,Object primaryKey):<T>T //根据主键查找,没有符合条件记录,抛出异常
Hibernate:load(); //EntityNotFoundException
persist(Object entity):void //将实体变成受管态,并持久化它,将在数据库中增加一条记录
Hibernate:save();
merge(T entity):T //合并一个实体到持久化上下文中,将更新数据库记录,并返回持久化对象
Hibernate:merge();
remove(Object entity):void //删除一个实体,将删除数据库记录
clear():void //清除持久化上下文,将导致托管态对象变成游离态对象
contains(Object entity):boolean //检查一个实体对象是否包在持久化上下文中
close(); //关闭持久化上下文
flush(); //对象同步到数据库,有两种同步方式
FlushModeType.AUTO //事务提交和执行查询时同步
FlushModeType.COMMIT; //只有事务提交时同步
setFlushMode(FlushModeType flushMode) //设置同步方式
refresh(); //数据库同步到对象
getTransaction().begin(); //开启事务
getTransaction().commit(); //提交事务,事务结束
5. 持久化上下文和实体的生命周期
新建 -> 托管(受管) -> 脱管(游离) -> 删除
1) 新建new:new Instance persist(); 新建一个实体对象,还未持久化,没有持久化标志
2) 托管managed:数据库里和持久化上下文中都有 实体对象
3) 游离detached:持久化上下文中没有,但是又具有持久化标志(oid) 可调用merge(),不能调用persist();
4) 删除removed:hibernate没有(数据库中和持久化上下文中都有,但是通过remove()标志实体是被删除的)
总结:
1) 不调用persist, 而是调用merge持久保存entity对象
2) 在事务当中(ejb默认一个方法是一个事务)或者持久化上下文中,先查询entity, 再进行操作
3) 调用find方法, 不要调用getReference()
6. 持久化上下文类型
容器管理的上下文
@PersistenceContext(type=PersistenceContextType.TRANSACTION)
1)事务范围的(默认方式):
事务结束时(一个方法默认为一个事务),上下文被关闭
@PersistenceContext(type=PersistenceContextType.EXTENDED)
2)扩展范围的(多个事务):
上下文跨越多个事务(事务结束时,上下文并不关闭)
*只有*有状态会话Bean适用,SFSB销毁时,上下文关闭
应用程序管理的上下文,是扩展的上下文
EntityManagerFactory emf;
EntityManager em = emf.createEntityManager();
7. 实体回调
1)注解方法
@PrePersist //insert into SQL执行之前调用
@PostPersist //insert into SQL执行之后调用
@PreUpdate //update SQL执行之前调用
@PostUpdate //update SQL执行之后调用
@PreRemove //delete SQL执行之前调用
@PostRemove //delete SQL执行之后调用
@PostLoad //加载实体之后,select SQL执行之后调用 (只有这个没有之前执行的)
2)独立的回调类
@EntityListeners(Callback.class)
回调方法多一个Object 参数,如:
Callback.java 里写: entity.java里写:
@PreUpdate @PreUpdate
public void preUpdate (Object obj); public void preUpdate ();
8. JPA查询(JPQL)
1)javax.persistence.Query接口
Query query = em.createQuery("select 别名 from entity类 别名"); //也可写 "from entity类"
List<entity类> list = query.getResultList();
for(entity类 obj : list){System.out.println(obj.getOid() + " : " + obj.getName());}
2)本地查询
Query query = em.createNativeQuery("select * from 表名", entity类.class);
List<entity类> list = query.getResultList();
for(entity类 obj :list){System.out.println(obj.getOid() + " : " + obj.getName());}
3)命名查询
a)在Entity里添加标注
@NamedQuery(name="命名1", query="select h from entity类 h where h.age>?2 and h.name like ?1")
//上面 ?1 ?2 的数字决定参数下标。也可以只用 ? ,但代码得保证对应这语句的顺序。(h是 entity类 的别名)
//query 语句也可写成:"from entity类 where age>:age and name like :name"
//分号表示用名称代号代替之前的下标,来表示参数。这种方式更常用,不易出错
b)查询代码
Query query = em.createNamedQuery("命名1");
query.setParameter(1, "%始%"); //如果query 语句用分号的,则query.setParameter("name", str);
query.setParameter(2, 70);
List<entity类> list = (List) query.getResultList();
for (entity类 obj : list){
System.out.println(obj.getOid() + " : " + obj.getName());}
4)本地命名查询
a)在Entity里添加标注
@NamedNativeQuery(name="命名2", query="select * from 表名", resultClass=entity类.class)
b)查询代码
Query query = em.createNamedQuery("命名2");
List<entity类> list = (List)query.getResultList();
for (entity类 obj : list){System.out.println(obj.getOid() + " : " + obj.getName());}
JPA(Java Persistence API)简介
1)ORM(object relational mapping):
实现对象到关系数据库中的表的自动持久化(翻译),通过元数据描述对象于数据库间的映射。
2)JPA, Sun提出的又一套Java持久化规范标准
3)整合当前各种ORM框架和技术,为各种ORM框架提供统一编程接口
4)使用Annotation和XML描述对象和关系表的关系
5)只是一套接口,要求持久化提供商实现支持
6)EJB和普通Java程序都可使用
数据库库同步
flush();
FlushModeType.AUTO 和 FlushModeType.COMMIT;
refresh();
9. O/R mapping metadata
@Entity //用于类名前。表明他是pojo类
@Table(name="t_film") //用于类名。这个类对应的表名,可以不写
@Column(name="filmName") //用于属性。表中的字段名,不写则跟属性名一样(大小写也一样)
@Id //用于属性。表明他是id;要求一定要有ID
@GeneratedValue //用于id属性。指定需要框架自动产生主键
//主键生成策略
@GeneratedValue(strategy=GenerationType.AUTO, generator="generatorName")
GenerationType.AUTO //默认
GenerationType.IDENTITY //Mysql,Sql Server适用
GenerationType.SEQUENCE //Oracle
@SequenceGenerator(name="generatorName", sequenceName="")
//Oracle: create SEQUENCE SEQ_ID INCREMENT BY 1 START WITH 1)
GenerationType.TABLE //Mysql,Oracle 适用
@TableGenerator( name="generatorName", table="ID_GEN", pkColumnName="entityName",
valueColumnName="IdValue", allocationSize=1 )
//Annotation
@Basic(optional=false) //属性可选
@Transient //瞬态属性;不会持久化到数据库
@Lob //大字段类型属性
@Embedded //复合组件(属性) @Enumerated的手误???
复合主键和复合组件
@IDClass(复合主键)
@EmbeddedID(复合主键)
@Embeddable
@Embedded(复合组件)
-----------------------------------------------------------
Day5
10.继承映射策略
1)每个类对应一个表
@Inheritance(strategy=InheritanceType.JOINED) //用于父类,还需有@Entity
优点: 符号面向对象;支持多态;没有数据冗余
缺点: 表的数量过多,不方便维护;连接查询速度慢
2)每个具体类对应一个表
@MappedSuperclass //用于父类,子类继承父类的id,而父类没有表
@AttributeOverrides({
@AttributeOverride(name="prepertyName1", column=@Column(name="fieldName1")),
@AttributeOverride(name="prepertyName2", column=@Column(name="fieldName2")) })
优点:查询速度快
缺点:数据定义存在冗余
3)整个类层次结构对应一个表
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discriminatorField")
@DiscriminatorValue("discriminatorValue")
优点:容易理解和维护;最快的查询数度
缺点:最大的冗余
11.实体关联关系
//多对一与一对多
@ManyToOne //主动,只有他不能放弃维护关系。加上mappedBy就编译不通过
@JoinColumn(name="外键字段名") //指定外键;Many的一方不需另外建表,只需增加字段就可以维护关系
//被动。写mappedBy后就不再另外建表维护OneToMany的关系(默认建One_Many表)
@OneToMany(mappedBy = "", cascade={}, fetch=FetchTYPE.EAGER)
@JoinTable(name="One_Many关系表名" //反映 One_Many 关系的一个表。不写则不建
,joinColumns={@JoinColumn(name="One_id1")} //这个关系表的主键字段,可以用复合主键(One端)
,inverseJoinColumns={@JoinColumn(name="Many_id")}) //这个关系表的成员的字段(Many端)
//一对一
@OneToOne //主动
@JoinColumn(name="外键字段名")
@OneToOne(mappedBy="") //任意一方加上mappedBy后,变被动;他不可以再维护关系了
//多对多
@ManyToMany //主动
@JoinTable(name="innerTableName"
, joinColumns={@JoinColumn(name="foreign_key")}
, inverseJoinColumns={@JoinColumn(name="otherColumn")})
@ManyToMany(mappedBy="") //加上mappedBy后,变成 ManyToOne 的 One方
三大要点:
a.维护关系(没有mappedBy的默认都是维护关系(设置外键或者设置中间表记录))
加上mappedBy后,他就不可以再维护关系了
b.fetch //设置加载方式
(FetchType.EAGER时, 查询主表记录,并查询从表纪录,两条SQL语句;对 One 的一方)
对于基本属性,使用 fetch=FetchType.EAGER (通常配合二级缓存使用),会提高效率(默认 EAGER)
(FetchType.LAZY时, 只查询主表记录, 只有一条SQL语句;对 Many 的一方)
对于集合属性,一般设置为 fetch=FecthcType.LAZY 加载;为了提高效率
c.cascade
对一边执行操作时,是否要对另一端也行操作(只能用于 One端,用于Many端时编译不通过)
cascade={CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.RERSIST,
CascadeType.MERGE, CascadeType.ALL} //级联操作,小心使用
例如: persist()一个对象时(执行insert语句),是否同时persist关联对象
12. EJBQL (又称 JPQL)
类似HQL(Hibernate的SQL语句),这是EJB的SQL语句,又称JAVA的SQL语句
1)批量删除、更新(delete from Entity),需要 em.clear();
2)连接查询(关联对象之间使用 join fetch,只能给有关联的类使用)
left join/inner join (select u from User u inner join u.dept)
inner join/left join(select u from User u left join u.dept)
只能给有关联的表作级联操作。(功能不如SQL,SQL可以给所有表作级联操作)
inner join fetch/left join fetch (查出所有关联实体)
3)group by 和 having 语句
4)投影:(要求构造函数才可以根据投影返回对象)
如:select u.userName from User ;查询之后返回对象数组
select new User(u.userName) from User u ;返回实体对象(要求有对应的构造函数)
5)子查询:只能在where子句中出现(功能不如SQL,SQL可任意子查询)
13. 并发访问
乐观锁
悲观锁(只有数据库的锁才是悲观锁)
@Version //加在Entity类的版本属性里
The basic of JPA (II)
-----------------------------------------------------------
Day6 事务
1. 事务概念:
1)事务产生的动机
使用事务保证原子操作,避免应网络故障或机器故障,导致数据状态不一致,保证多用户并发访问数据库的问题
2)事务过程的参与者:
事务对象:包含事务的应用组件,如EJB组件
事务管理器:负责管理应用组件的事务操作,如J2EE应用服务器
资源:一个可供读写的永久性的存储库,如数据库
资源管理器:负责管理资源,如一个数据库管理系统
3)事务的ACID属性:
原子性(Atomicity)
事务中的数据库修改操作,要么全部成功,要么全部不成功。
一致性(Consistency)
事务执行之前,和事务结束之后,数据库都必须满足全部完整性要求。
隔离性(Isolation)
一个事务的处理不能影响另一个事务的处理。(有多个隔离级别)
持久性(Durability)
指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。以后其他操作或故障不对其有任何影响。
2. 分布式事务
1)事务的类型:JDBC事务 和 JTA事务
2)分布式事务和两阶段提交协议
分布式事务:事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的布式系统的不同(机器)节点之上
为了实现分布式事务需要使用两阶段提交协议。
两阶段提交协议(后台实现)
阶段一:开始向事务涉及到的全部资源发送提交前信息。各资源服务器进行“预提交”。
阶段二:只在阶段一没有异常结束的时候才会发生
数据源配置文件位置(固定): %jboss_home%/server/default/deploy/ 目录放
mysql-xa-ds.xml 以及 oracle-xa-ds.xml (为每个需要调用的数据库都配置)
驱动: %jboss_home%/server/default/lib/ 目录下放 mysql 和 Oracle 的驱动
3. EJB事务
1)Bean(EJB Object)管理事务(BMT)(编程性事务)
2)容器管理事务(CMT)(声明式事务)
3)客户端管理事务
4. Bean管理事务
1)由EJB实现类显示调用事务代码(编程式事务)
@TransactionManagement(TransactionManagementType.BEAN)
@Resource(mappedName = "UserTransaction")
UserTransaction userTx;
2)优点:支持细粒度事务控制
3)缺点:需要编写事务代码,业务逻辑代码和事务代码耦合在一起,不利于维护
5. 容器管理事务(默认)
1)由容器为我们管理事务(声明式事务)
@TransactionManagement(TransactionManagementType.CONTAINER)
2)类级别声明和方法级别声明
@TransactionAttribute(TransactionAttributeType.REQUIRED|TransactionAttributeType.REQUIRED)
3)六种事务属性
REQUIRED: 一定有事务(调用者有事务,加入;调用者没有事务,创建一个事务)
REQUIRES_NEW: 总是创建新事务
SUPPORTS:支持事务,和调用者一致
MANDATORY:调用者,必须有事务(客户端没事务就抛出异常)
NOT_SUPPORTED:挂起原事务(如果有), 运行本方法,恢复原事务
NERVER: 调用者不允许有事务
4)优点:解耦业务逻辑代码和事务代码
5)缺点:对事务控制的最小粒度受限制(方法级),不够灵活
6. 客户端管理事务
1)由客户端负责事务管理(编程式事务)
UserTransaction utx = (UserTransaction)ctx.lookup("UserTransaction");
2)EJB本身必须是CMT事务,否则客户端事务无法远程传递到EJB
3)优点:事务在客户端,对于网络等问题造成的问题能进行处理(其他事务在这种情况下不知道事务是否成功)
4)缺点:跨越网络的长事务将导致严重的性能问题
----------------------------------------------------------part5 消息技术和消息驱动Bean1. 什么是消息和消息技术 广义来讲是程序或者计算机之间,进行通信的数据,有消息两种:同步消息和异步消息。 消息中间件技术中的消息是狭义的消息,特指异步消息。 消息技术拓扑图和消息技术作用 1)异步通信(接收、存储、转发):非阻塞 2)不同应用系统集成:松耦合 3)可靠性:重发 4)多发送者同时发送和多接收者同时接收