Hibernate知识总结

  

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 AnnotaitionConfiguratio­n().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” //引用
      table=”GENERATOR_TABLE”,//中间表的表面

       pkColumnName=”pk_key”,//一个列,默认是key,需要修改,key是关键字

       valueColumnName=”pk_value”,// 另外一个列
    pkColumnValue=”Teacher”, //(暂时不太明白什么意思)

       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>
<property name=”cache.provider_class”>org.hibernate.cache.EhCachePro
vider</property>

还要ehcache的jar包和配置相应的文件ehcache.xml
在ehcache.xml中可以了解的

<defaultCache

maxElementsMemory=”10000”

eternal=”false”

timeToIdleSeconds=”120”

timeToLiveSeconds=”120”

overflowDisk=”True” //需要指定溢出时候的路径

/>
<diskStore path=”java.io.tmpdir”>

 对于缓存算法: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 表示层技术的最大优势是其采用的组件模型,事件驱动!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值