1. hibernate3.0需要的包
包的介绍:
http://hi.baidu.com/magicalboy/blog/item/394eb0196079f24f43a9ad87.html
补充: java日志,需要知道的几件事(commons-logging,log4j,slf4j,logback)
http://singleant.iteye.com/blog/934593
2. 配置文件:
<property name=”show_sql”>true</property> <property name=”hbm2ddl.auto”>update</property> <property name=”current_session_context_class”>thread</property> <property name=’format_sql>true</property>//sql显示好看些 |
对应hibernate.hbm2ddl.auto的值
create:表示启动的时候先drop,再create create-drop: 也表示创建,只不过再系统关闭前执行一下drop update: 这个操作启动的时候会去检查schema是否一致,如果不一致会做scheme更新(用的多) validate: 启动时验证现有schema与你配置的hibernate是否一致,如果不一致就抛出异常,并不做更新 |
除了使用<property name=”show_sql”>true</property>之外用
new SchemaExport (new AnnotaitionConfiguration().configure().create(false,true)//一个false,一个true,两个true就会重复打印
使用getCurrentSession需要制定session的上下文
<property name=”current_session_context_class”>thread</property>
3. 一些注解:
@GeneratedValue(stratery=GenerationType.IDENTITY) ID生成策略
// stratery:战略的意思 generator:生成
native:默认的,交给数据库管理.用的最多
increment:用的极少
identity:SQL Server常用
sequence:Oracle数据库常用
uuid:用的极少,需要设置ID的类型是String
ggid:在一个范围
TABLE:自己定义张表
@GeneratedValue(stratery=GenerationType.TABLE,generator=”Teacher_GEN”)
中间生成主键的表举例 |
@Entity @javax.persisstence.TableGenerator( name=” Teacher_GEN” //引用 pkColumnName=”pk_key”,//一个列,默认是key,需要修改,key是关键字 valueColumnName=”pk_value”,// 另外一个列 allocationSize=1 //增量 ) |
@BeforeClass
@BeforeClass public static void beforeClass(){sessionFactory = new AnnotationConfiguration.configure(“hibernate.xml”)//如果是”hibernate.cfg.xml”就可以不写参数 |
@AfterClass
public static void afterClass(){ sessionFactory.close();} |
sessionfactory就是产生session的:
①Session session = SessionFactory.getCurrentSession()//获取session,如果没有就创建.如果有就直接用,事务Commit之后就是不同的Session对象了,在hibernate.cfg.xml中需要定制session的上下文
②Session session = SessionFactory.openSession() //这个永远是创建新的.好像hibernate3.2之后就不太建议使用了,使用openSession()一定要关闭.
二者不能混用
4.Hibernate关联关系映射配置:
- 一对一单向外键关联和一对一双向外键关联:
@OneToOne:单向外键关联.假如是双向外键关联的话,需要@OneToOne(mapperBy=”wife”)
在xml中双向外键关联
<one-to-one name=”sutIdCard” property-ref=”student”></one-to-one> |
- 一对一单向主键关联, 一对一双向主键关联:不重要
@PrimaryKeyJoinColumn:主键关联时候用(不常用)
- 组件映射
注解的3种方式:
a)将组件类注解为@Embeddable(可被嵌入的),并将组件属性注解为@Id
b)将组件类的属性注解为@EmbeddedId 常用
c)将类注解为@IdClass(实体类.class),并将该实体中所有的属性主键都注解为@Id 常用
作为联合主键的类需要implements java.io.Serializable,然后重写equlas()和hashCode
@Override public boolean euqals (Object o){ if(o instanceof StudentPK){ StudentPK pk = (StudentPK)o; if(this.id==pk.getId() && this.name.equals(pk.getName()) return true; } } return false;} @Override public int hashCode(){ return this.name.hashCode(); }
|
xml方式
<component name="wife"> <property name="name" column="WIFENAME" /> <property name="age" column="AGE" precision="3" /> </component> |
- 多对一单向关联
@ManyToOne
//@JoinColumn(name=””)//可以指定外键名称
- 一对多单向关联
@OneToMany
@JoinColumn(name="HOUSE_ID")//不加会生成由一张中间表连接的共三张表
- 一对多、多对一双向关联
一方: @ManyToOne//如果需要指定外键字段使用 @JoinColumn(name="PERSON_ID") 另一方: @OneToMany(mappedBy="person")//参考了对方的属性名 - 多对多单向关联
@ManyToMany @JoinTable( name="H_T_S",//指明中间表的名字 joinColumns={@JoinColumn(name="TEACHER_ID", referencedColumnName="ID")}, //指明中间表参考当前类对应数据库表中的字段ID的外键名为TEACHER_ID inverseJoinColumns={@JoinColumn(name="STUDENT_ID",referencedColumnName="ID")} //指明中间表参考另外一张表中的字段ID的外键名为STUDENT_ID )
|
- 多对多双向关联
@ManyToMany(mappedBy="students") |
@ManyToMany @JoinTable( name="H_T_S",//指明中间表的名字 joinColumns={@JoinColumn(name="TEACHER_ID", referencedColumnName="ID")}, //指明中间表参考当前类对应数据库表中的字段ID的外键名为TEACHER_ID inverseJoinColumns={@JoinColumn(name="STUDENT_ID", referencedColumnName="ID")} //指明中间表参考另外一张表中的字段ID的外键名为STUDENT_ID )
|
在@OneToMany和@ManyToOne中:
caascade用的最多是(@ManyToOne(cascade={CascadeType.ALL})
fetch:@OneToMany默认是(fetch=FetchType.LAZY)
@ManyToOne默认是(fetch=FetchType.EAGER)
@OrderBy 默认按照主键排序
@MapKey(name=”id”) map类型时候,需要一个MapKey只有一个属性
Inheritance mapping:3种方式
(1)、每个具体类(非抽象类)对应一个表:此方式中关系数据模型完全不支持对象的继承关系。 (2)、基类(根类)对应一个表:此方式中对关系数据模型进行非常规设计,在数据库表中加入额外的区分子类的字段,从而使关系数据模型可以支持继承关系。 (3)、每个类对应一个表:此方式中在关系数据模型中用外键关系来表示继承关系。 |
HQL查询:不解释
Query接口: Query q = session.createQuery("from Category"); Query q = s.createSQLQuery("select * from user").addEntity(User.class);
5.三种状态:
6.session的方法:
load()是产生一个代理.需要时才发送sql语句,需要有session对象
get()马上发送sql语句
update()默认更新所有字段.使用update需要使用制定ID,所以不能是瞬时态,如果想更新制定字段
在xml中
<property name =”name update=”true/flase”></property> |
在注解中
@column(updatable=false public String getTitle(){ return title; } |
但是一般是使用dynamic-update=”ture”,这个就是只更新改变过的字段.但是它只是在一个session中起作用.想跨session需要用merge();
哈哈.但是还是没有必要这么麻烦直接用HQL语句就行了
“update Student s set s.name=’billy’ where s.id=”1”)//秒杀前面的所以 |
clear():直接清除缓存 flush():是缓存和数据库同步,涉及到一个session.setFlushMode(FlushMode.XXX) save();delete();saveOrUpdate();
1+N问题:
①设置fetch取值为lazy②@BatchSize(size=5)③加连接jion fetch
但是网上是这么讲的
1 )lazy=true, hibernate3开始已经默认是lazy=true了;lazy=true时不会立刻查询关联对象,只有当需要关联对象(访问其属性,非id字段)时才会发生查询动作。 2)使用二级缓存, 二级缓存的应用将不怕1+N 问题,因为即使第一次查询很慢(未命中),以后查询直接缓存命中也是很快的。刚好又利用了1+N 。 3) 当然你也可以设定fetch="join",一次关联表全查出来,但失去了懒加载的特性。 |
list和iterate不同之处:
l list取所有(内存开销大)
l iterate先取ID,等用到的时候在根据ID来取对象
l 在session中list第二次发出,仍会到数据库查询
l iterate第二次的时候,先找session级缓存
Hibernate的缓存:
l 一级缓存是session级别的缓存
l 二级缓存是SessionFactory级别的缓存,可以跨越session存在
l 三级缓存是查询缓存
l 如果要使用二级缓存
在hibernate.cfg.xml中
<property name=cache.user_second_level_cache”>true</property> |
还要ehcache的jar包和配置相应的文件ehcache.xml
在ehcache.xml中可以了解的
<defaultCache maxElementsMemory=”10000” eternal=”false” timeToIdleSeconds=”120” timeToLiveSeconds=”120” overflowDisk=”True” //需要指定溢出时候的路径 /> |
对于缓存算法:LRU,LFU,FIFO不解释
@Cache注解使用:不解释
l load()默认是用二级缓存,iterate默认使用二级缓存,list默认往二级缓存存入数据,但是查询的时候不使用
l 如果要query用二级缓存,需打开查询缓存
<property name=”cache.use_query_cache”>true</property> |
7.事务处理:
原子性,一致性,独立性,持久性
事务中会出现的常见问题:脏读,不可重复读,幻读
数据库的事务处理机制:read-uncommitted;read-committed;repeatable read;serializable;
但是综合效率一般呢.是用read-committed.但是还是有问题.所以我们结合hibernate的悲观锁和乐观锁配合完成
①悲观锁:用lockMode.UPGRADE_NOWAIT
String hqlStr ="from TUser as user where user.name='Erica'"; Query query = session.createQuery(hqlStr); query.setLockMode("user",LockMode.UPGRADE); // 加锁 List userList = query.list();// 执行查询,获取数据 |
hibernate的加锁模式:
LockMode.NONE: 无锁机制。
LockMode.WRITE: Hibernate 在 Insert 和 Update 记录的时候会自动获取。
LockMode.READ : Hibernate 在读取记录的时候会自动获取。
以上这三种锁机制一般由 Hibernate 内部使用,如 Hibernate 为了保证 Update过程中对象不会被外界修改,会在 save 方法实现中自动为目标对象加上 WRITE 锁。
LockMode.UPGRADE :利用数据库的 for update 子句加锁。
LockMode. UPGRADE_NOWAIT: Oracle 的特定实现,利用 Oracle 的 for update nowait 子句实现加锁。
②乐观锁:大多是基于数据版本( Version )记录机制实现
optimistic-lock="version"
8.小常识:
hibernate3.5支持jpa
ibatis不支持jpa
JIT: Compiler(Just-in-time Compiler) 即时编译
flex: flex只是一个写actionscript3.0脚本的软件,AS不解释
C3P0:是一个开源的JDBC连接池
JNDI:(Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API
jsf: JavaServer Faces(JSF) 是一种标准的 J2EE 表示层的技术,其 主旨是为了使 Java 开发人员能够快速的开发基于 Java 的 Web 应用程序。它不同于其它 Java 表示层技术的最大优势是其采用的组件模型,事件驱动!