Hibernate SQL方言 (hibernate.dialect)
RDBMS | 方言 |
DB2 | org.hibernate.dialect.DB2Dialect |
DB2 AS/400 | org.hibernate.dialect.DB2400Dialect |
DB2 OS390 | org.hibernate.dialect.DB2390Dialect |
PostgreSQL | org.hibernate.dialect.PostgreSQLDialect |
MySQL | org.hibernate.dialect.MySQLDialect |
MySQL with InnoDB | org.hibernate.dialect.MySQLInnoDBDialect |
MySQL with MyISAM | org.hibernate.dialect.MySQLMyISAMDialect |
Oracle (any version) | org.hibernate.dialect.OracleDialect |
Oracle 9i/10g | org.hibernate.dialect.Oracle9Dialect |
Sybase | org.hibernate.dialect.SybaseDialect |
Sybase Anywhere | org.hibernate.dialect.SybaseAnywhereDialect |
Microsoft SQL Server | org.hibernate.dialect.SQLServerDialect |
SAP DB | org.hibernate.dialect.SAPDBDialect |
Informix | org.hibernate.dialect.InformixDialect |
HypersonicSQL | org.hibernate.dialect.HSQLDialect |
Ingres | org.hibernate.dialect.IngresDialect |
Progress | org.hibernate.dialect.ProgressDialect |
Mckoi SQL | org.hibernate.dialect.MckoiDialect |
Interbase | org.hibernate.dialect.InterbaseDialect |
Pointbase | org.hibernate.dialect.PointbaseDialect |
FrontBase | org.hibernate.dialect.FrontbaseDialect |
Firebird | org.hibernate.dialect.FirebirdDialect |
ID生成策略<generator>
1.XML方式配置
可选的<generator>子元素是一个Java类的名字, 用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数, 用<param>元素来传递。
<id name="id" type="long" column="cat_id">
<generator class="org.hibernate.id.TableHiLoGenerator">
<param name="table">uid_table</param>
<param name="column">next_hi_value_column</param>
</generator>
</id>
所有的生成器都实现org.hibernate.id.IdentifierGenerator接口。 这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然, Hibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字:
l increment 用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。
l identity 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。
l sequence 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者int类型的。
l hilo 使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
l seqhilo 使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
l uuid 用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
l guid 在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
l native 根据底层数据库的能力选择identity, sequence 或者hilo中的一个。在mysql中默认的是auto_increment,SQLSERVER中是identity.
l assigned 让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。
l select 通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
l foreign 使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。
l sequence-identity 一种特别的序列生成策略,使用数据库序列来生成实际值,但将它和JDBC3的getGeneratedKeys结合在一起,使得在插入语句执行的时候就返回生成的值。目前为止只有面向JDK 1.4的Oracle 10g驱动支持这一策略。注意,因为Oracle驱动程序的一个bug,这些插入语句的注释被关闭了。(原文:Note comments on these insert statements are disabled due to a bug in the Oracle drivers.)
2 annotation中配置id生成策略
使用@Id注解可以将实体bean中的某个属性定义为标识符(identifier). 该属性的值可以通过应用自身进行设置, 也可以通过Hiberante生成(推荐).
使用 @GeneratedValue注解可以定义该标识符的生成策略: 有四种策略
l AUTO -默认值.可以是identity column类型,或者sequence类型或者table类型,取决于不同的底层数据库..对于MYSQL,是auto_increment,对于Oracle是hibernate-sequence.
l TABLE - 使用表保存id值 (了解)
l IDENTITY - identity column
l SEQUENCE - @SequenceGenerator
@GeneratedValue(strategy=GenerationType.XXXX)
XXXX取值为Type.SEQUENCE|TABLE|AUTO|IDENTITY不同的数据库对应着不同的生成策略.
例1
实体类注解
@Entity
主键进行注解
@Id
@GeneratedValue
默认值是@GeneratedValue(strategy=GenerationType.AUTO)
例2
使用SequenceGenerator
@Entity
@SequenceGenerator(
name="teacher_SEQUENCE",sequenceName="teacher_SEQUENCE_DB")
name是用户自定义的generator生成器的名字, sequenceName是生成到数据库后sequence对象的名字.
在实体中注解好后,就可以在id注解上写上对应的
@Id
@GeneratedValue(
strategy=GenerationType.IDENTITY,generator="teacher_SEQUENCE")
例3
表生成器(了解),这种方式会另外生成一个表.
实体类注解
@Entity
@javax.persistence.TableGenerator(//了解,更适合用于跨平台跨数据库.
name="TEACHER_GEN", //生成器generator的名字
table="GENERATOR_TABLE",//生成的表名
pkColumnName = "pk_key",//生成的表的字段名
valueColumnName = "pk_value",//生成的表的字段的值
pkColumnValue="teacher",// pk_key字段的值
allocationSize=1//自增变量
)
主键注解
@Id
@GeneratedValue(strategy=GenerationType.TABLE,generator="TEACHER_GEN")
l 联合主键生成策略
一般采用这种方式,比如有一个类Student(id,name,age),为了产生联合主键,把id和name分离出来.
Student(pk,age) StudentPk(id,name)
StudentPk类必需实现序列化接口implements java.io.Serializable.
StudentPk类必需重写boolean equals() ,int hasCode()方法
@Override
public boolean equals(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配置方法
<composite-id name="pk" class="com.hibernate.StudentPk">
<key-property name="id"></key-property>
<key-property name="name"></key-property>
</composite-id>
联合主键生成策略annotation配置方法
定义组合主键的三种方式:
l (少用)将组件类注解为@Embeddable,并将组件的属性注解为@Id.
实体模型Teacher(teacherPK,age) TeacherPk(id,name)
在TeacherPk(id,name)中把类注解@Embeddable
在Teacher(teacherPK,age)中把组件属性teacherPK注解@Id
l 将组件的属性注解为@EmbeddedId.
实体模型Teacher(teacherPK,age) TeacherPk(id,name)
只需要在Teacher(teacherPK,age)中把组件属性teacherPK注解@EmbeddedId
l (推荐使用)将类注解为@IdClass,并将该实体中所有属于主键的属性都注解为@Id.
实体模型Teacher(id,name,age) TeacherPk(id,name)
在Teacher(id,name,age)中把类注解@IdClass(value=”TeacherPk.Class”),在主键属性id,name上注解@Id即可.当IdClass()中只有一个属性默认写成IdClass(TeacherPk.Class).也就是说Teacher里面的组件属性id,name,合起来刚好是类TeacherPk.
对象的三种状态
三种状态的区别在于:
有没有ID,ID在数据库中有没有,在内存中有没有(session缓存)
三种状态
Transient:内存中的一个对象,没有ID,缓存中也没有
Persistent:内存中有,缓存中有,数据库中有ID
Detached:内存中有,缓存中没有,数据库有ID
核心接口开发介绍
Configuration
1 AnnotationConfiguration
2 进行配置信息的管理
3 用来产生SessionFactory:buildSessionFactory()
4 可以在configure()方法中指定hibernate配置文件
SchemaExport
可以在程序中控制生成建表语名.
位于包import org.hibernate.tool.hbm2ddl.SchemaExport;
create(boolean script,boolean export)
script - print the DDL to the console
export - export the script to the database
Configuration cfg=new AnnotationConfiguration().configure();
SchemaExport export=new SchemaExport(cfg);
export.create(true, true);
或者
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
SessionFactory
1 用来产生和管理sesssion
2 通常情况下,每个应用只需要一个SessionFactory,除非要访问多个数据库的情况
3 openSession()与openSession()
l openSession()总是创建新的session,需要手动close().
l getCurrentSession()事务自动提交并且自动关闭.从上下文环境中获得session,如果当时环境中不存就创建新的.如果环境中存在就使用环境中的,而且每次得到的都是同一个session(在session提交之前,提交之后就是新的了).用途:界定事务边界.
l 所谓的上下文参见配置文件
<property name="current_session_context_classs">thread</property>
取值范围 jta | thread | managed | custom.Class
JTA简介
Session
管理一个数据库的任务单元,即管理数据库中的增删改查操作,提交事务.
方法CRUD:save(),delete(),update(),saveOrUpdate(),load(),get(),clear().
session.beginTransaction();
session.save(Object obj);
session.getTransaction().commit();
session.close();
get()与load()的区别
l 查找时,都会优先从session的缓存中查找.
l 查找不存在对应记录时,表现不一样.load方法查找不到时不会报错,get查找不到时会报错.
l Load返回的是代理对象,等到真正要用到对象的内容时才发起SQL语句.get直接发起SQL语句从数据库中取出,不会延迟.
Update()方法
1 用来更新detached对象,更新完成之后成为persistent.
2 更新transient对象会报错. 更新自己设定id(前提是id在数据库中存在)的transient对象可以.
3 持久化的对象只要设定不同字段就会发生更新
4 更新部分更改的字段(三种方法)
l XML设定property标签的update=true|false属性,
annotation设定@Column(updatable=false)属性,这种方式少用,不灵活.
l XML设定class标签的dynamic-update=”true”属性,
同一个session中可以,跨session不行.跨session时的实现方法不过可以用session的merge().merge方法会先从数据库load,将得到的和数据库中的进行对比,再update更改过的字段.
JPA1.0 Annotation没有对应的属性,Hibernate
l 使用HQL(EJBQL)(建议使用)
clear()方法:
清除session中的缓存.调用clear()方法会强制清除session缓存.不会与数据库打交道.
flush()方法:
当session的事务提交后,会强制进行从内存(session缓存)到数据库的同步.默认情况下是session的事务提交时才同步.不常用.