1.什么是动态代?
{:动态代理可以提供对另一个对象的讉KQ同旉藏实际对象的具体事实。代理一般会实现 它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现pȝ的实际功能,代理对象对客户隐藏了实际对象。客户不 知道它是与代理打交道q是与实际对象打交道?br /> 2.Z么用动态代?
{:因ؓ动态代理可以对hq行M处理
3.使用它有哪些好处?
{:因ؓ动态代理可以对hq行M处理
4.哪些地方需要动态代?
{:不允许直接访问某些类Q对讉K要做Ҏ处理{?/span>
目前Java开发包中包含了对动态代理的支持Q但是其实现只支持对接口的的实现?其实C要通过java.lang.reflect.Proxycdjava.lang.reflect.InvocationHandler接口?nbsp;
ProxycM要用来获取动态代理对象,InvocationHandler接口用来U束调用者实?/p>
以下为模拟案例,通过动态代理实现在Ҏ调用前后向控制台输出两句字符?/p>
目录l构
<br/>
定义一个HelloWorld接口
1 package com.ljq.test;
2
3 /**
4 * 定义一个HelloWorld接口
5 *
6 * @author jiqinlin
7 *
8 */
9 public interface HelloWorld {
10 public void sayHelloWorld();
11 }
<br/>
cHelloWorldImpl是HelloWorld接口的实?/p>
1 package com.ljq.test;
2
3 /**
4 * cHelloWorldImpl是HelloWorld接口的实?br /> 5 *
6 * @author jiqinlin
7 *
8 */
9 public class HelloWorldImpl implements HelloWorld{
10
11 public void sayHelloWorld() {
12 System.out.println("HelloWorld!");
13 }
14
15 }
HelloWorldHandler?InvocationHandler接口实现
1 package com.ljq.test;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 /**
7 * 实现在方法调用前后向控制台输Z句字W串
8 *
9 * @author jiqinlin
10 *
11 */
12 public class HelloWorldHandler implements InvocationHandler{
13 //要代理的原始对象
14 private Object obj;
15
16 public HelloWorldHandler(Object obj) {
17 super();
18 this.obj = obj;
19 }
20
21 /**
22 * 在代理实例上处理Ҏ调用q返回结?br />
23 *
24 * @param proxy 代理c?br />
25 * @param method 被代理的Ҏ
26 * @param args 该方法的参数数组
27 */
28 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
29 Object result = null;
30 //调用之前
31 doBefore();
32 //调用原始对象的方?/span>
33 result=method.invoke(obj, args);
34 //调用之后
35 doAfter();
36 return result;
37 }
38
39 private void doBefore(){
40 System.out.println("before method invoke");
41 }
42
43 private void doAfter(){
44 System.out.println("after method invoke");
45 }
46
47 }
试c?/p>
package com.ljq.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class HelloWorldTest {
public static void main(String[] args) {
HelloWorld helloWorld=new HelloWorldImpl();
InvocationHandler handler=new HelloWorldHandler(helloWorld);
//创徏动态代理对?/span>
HelloWorld proxy=(HelloWorld)Proxy.newProxyInstance(
helloWorld.getClass().getClassLoader(),
helloWorld.getClass().getInterfaces(),
handler);
proxy.sayHelloWorld();
}
}
q行l果为:
4 Strategy Pattern
上榜理由Q策略模式,易于变化的部分装为接口,通常Strategy 装一些运法则,使之能互换。Bruce Zhang在他的博客中提到{略模式其实是一U?#8220;面向接口”的编E方法,真是恰如其分?nbsp;
5 Iterator Pattern
上榜理由Q相信Q何的pȝ中,都会用到数组、集合、链表、队列这Lcd吧,那么你就不得不关心P代模式的来龙去脉。在遍历法中,q代模式提供了遍历的序讉K容器QGOFl出的定义ؓQ提供一U方法访问一个容器(containerQ对象中各个元素Q而又不需暴露该对象的内部l节?NET中就是用了q代器来创徏用于foreach的集合?nbsp;
6 Adapter Pattern
上榜理由Q在原类型不做Q何改变的情况下,扩展了新的接口,灉|且多L适配一切旧俗。这U打破旧框框Q适配新格局的思想Q是面向对象的精髓。以l承方式实现的类的Adapter模式和以聚合方式实现的对象的Adapter模式Q各有千U,各取所ѝ看来,把它叫做包装器一点也不ؓq,
7 Observer Pattern
上榜理由Q定义对象间的一U一对多的依赖关p?当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知q被自动更新。观察者和被观察者的分开Qؓ模块划分提供了清晰的界限。在.NET中用委托和事g可以更好的实现观察者模式,事g的注册和撤销不就对应着观察者对其对象的观察吗?
8 Bridge Pattern
上榜理由Q把实现和逻辑分开Q对于我们深ȝ解面向对象的聚合复用的思想甚有助益?
9 Singleton Pattern
上榜理由Q改善全局变量和命名空间的冲突Q可以说是一U改良了的全局变量。这U一个类只有一个实例,且提供一个访问全局点的方式Q更加灵zȝ保证了实例的创徏和访问约束?NET Frameeork已经装了Singletonc,我们拿来卛_?
ȝ
仁者见仁。以上只是笔者一家之aQ更重要的真知灼见皆来源于实践,设计思想和模式的应用也来源于不断的学习和反复Q我也将一如既往。此文只是开端,未来才是不断的探索?/p>
3. 基本注解
@EntityQ将领域模型标注Z个实体,默认情况下类名,可以通过name属性重新指定?br /> @IdQ属性对应表的主键?/p>
@ColumnQ属性对应表的字Dc?/p>
@GenaratedValueQ主键生成策略,通过startage属性指定。在4.0会解释主键生成策略?/p>
4. 主键生成{略
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface GeneratedValue {
GenerationType strategy() default AUTO;
String generator() default "";
}
IDENTITYQ主键由数据库自动生成?/p>
AUTOQJPA自动选择合适的主键生成{略Q默认选线?/p>
SEQUENCEQ通过序列产生主键Q条件是数据库必L持序列?/p>
TABLEQ通过表生主键,使用该策略更易于数据库的Ud{?/p>
5. 实体关系
实体之间的关pL一对一Q一对多Q多对一Q多多对。关pL多态的?/p>
多对一
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
}
一对一
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
String mappedBy() default "";
}
6. 双向兌Ҏ?/p>
双向关系的的反向端必通过OnToOneQOnToMany或者ManyToMany注解的MappedBy元素必须指向它的持久端。MappendBy表述L端的属性或字段?/p>
一对多Q多对一双向关系中的多端必须是持久端Q因此不能再ManyToOne中用MappedBy属性?/span>
对于一对一双向兌关系Q包括对应的外键Qforeign keyQ那一D|持久化?/span>
对于多对多双向关联关p都是持久端?/span>
7. 延迟加蝲
FetchType.EAGERQ代表立卛_载?/span>
FetchType.LAYZQ代表gq加载策略?/span>
8. 多U联
REFRESH指定当你在访问期_如果数据库数据发生改变时Q你的数据是否更 新?/p>
PERSIST指定在保?数据的时是否会同时保存联的n数据?/p>
MERGE指定?处于游离状态被修改了,n的数据也会被修改?/p>
REMOVE指定在删?的同时是否删除与之联的n数据?/p>
ALL指定包含所有的U联的N斏V?/p>
9. Java Persistence Query language
Z首次在EJB2.0引用的EJB查询语言Qjava持久化查询语a是一U可UL的查询语a。旨在以面向对象表达式语a的表辑ּ,SQL语法和简单查询语义绑定在一?使用q种语言~写的查询是可移植的,可以被编译成所有主数据库服务器上的SQL.
10JPA2.0与JPA1.0
JPA2.0也跟Hibernate一P也分ZU缓存,二~存Q而JPA1.0不支持二U缓存,二~存是跨事物场景的。当二~存有效Ӟ你就不能通过事物来保护ƈ发数据,而只能依靠锁的策略?/span>
11 事物与EntityManager
EntityManager对象事物理分ؓ二种Q由JTA和RESOURCE_LOCAL来控制?/span>
JTA EntityManager一般在容器里面使用Q而RESOURCE_LOCALQ应用托的EntityManagerQ数据库本地化事物,一般在J2SE环境下用?/p>
通过容器来传递PersistenceContext而不是通过E序来自׃递EntityManagerQ它的生命周期由容器q行理?/p>
在J2SE环境下,RESOURCE_LOCALq序来创徏EntityManagerFactoryQƈ由EntityManagerFactory来创建EntityMangerQ这U方式就是RESOURCE_LOCAL的基本用方式?/p>
12 监听实体调用
监听实体主要有PostLoad , PostPersist , PostRemove , PostUpdate, pre-persist , pre-remove {。调用如下:
public class UserListeners {
@PostRemove
public void dothing(User user) {
System.out.println("加蝲..........." + user.getUserName());
}
} @Entity
@org.hibernate.annotations.Entity(dynamicInsert = true)
@EntityListeners(UserListeners.class)
public class User implements Serializable{
………………..
}
13 乐观锁定
乐观锁定它可以确保在实体的状态从数据库读取出来,在没有中间插入的其它事物更改了与q个实体对应数据库记录的情况下,才把更新后实体的状态更新到数据库。它保Ҏ据的更新和删除与数据库的当前状态保持一_q且不会丢失中间的修攏V如果应用程序想启用实体的乐观锁Q就必须为实体指定version属性。如果没有将乐观锁作为实体状态的一部分q行定义Q应用程序就要自己去l护数据的完整性?nbsp;
直接映射
实体的生命周?/p>
EntityManager用于理实体实例的生命周期,一个实体实例可以分为newQmanagedQdetachedQ或remove
一个新创立的实体实例没有持久化标识Qƈ且还没有跟持久化上下相关联?br />
一个受的实体实例有一个正与持久化上下文相兌的持久化标识?br />
一个脱的实体实例有持久化标识Q但是这个标识没有跟持久化上下文相关联?br />
被删除的实体实例有持久化标示Qƈ且与持久化上下文相关联,但是已经计划从数据库中删除?/p>
@Enumerated
@Temporal
@Lob
@Transient
关系映射
@OneToOne
@ManyToOne
@OneToMany
@ManyToMany
@MapKey
@OrderBy
l承
@DiscriminatorColumn
@DiscriminatorValue
@MappedSuperclass
@AssociationOverride
@AssociationOverrides
@AttributeOverride
@AttributeOverrides
锁定
@PostPersist
@PreRemove
@PostRemove
@PreUpdate
@PostUpdate
@PostLoad
@EntityListeners
@ExcludeDefaultListeners
@ExcludeSuperclassListeners
查询
@NamedQueries
@NamedNativeQuery
@NamedNativeQueries
@QueryHint
@ColumnResult
@EntityResult
@FieldResult
@SqlResultSetMapping
@SqlResultSetMappings
l合上面调研的内容,上传一个基??的例子。该例子主要描述了JPA双向一对一Q双向一对多Q双向多对多Q单向一对一Q单向一对多Q单向多对一与单向多对多Q测试代码中使用了联、gq加载策略,单表查询、多表查询JPQL。JPA版本采用Hibernate3.2