关键概念
SessionFactory:单个数据库映射关系经过编译后的内存镜像
Session:应用程序与持久存储层之间交互操作的单线程对象,底层封装了JDBC连接
Transaction:对底层具体的JDBC,JTA及CORBA事务的抽象,具有数据库事务的概念配置文件:每一个配置文件对应一个Configuration对象,作用是创建SessionFactory对象
Hibernate配置文件
1.hibernate.properties:在project/etc下有示例
弊端:需要在代码中手动添加映射文件:Configuration cfg=new Configuration().addResource("News.hbm.xml")
2.hibernate.cfg.xml
Configuration cfg=new Configuration().configure() //configure方法会负责加载hibernate.cfg.xml文件
3.不用任何配置文件
使用addClass方法添加持久化类,使用setProperty设置单独属性,使用setProperties设置一系列属性(通过传入Properties实例)
配置文件常用属性
1.JDBC连接属性
<property name="connection.driver_class">com.mysql.jdbc.Driver</property> <propertyname="connection.url">jdbc:mysql://localhost:3306/javaweb</property> <property name="connection.username">root</property> <property name="connection.password">123456</property>
2.c3p0连接池属性
<!-- C3P0连接池最大连接数 --> <property name="hibernate.c3p0.max_size">2 </property> <!-- C3P0连接池最小连接数 --> <property name="hibernate.c3p0.min_size">2 </property> <!-- C3P0连接池超时时长 --> <property name="hibernate.c3p0.timeout">5000 </property> <!-- C3P0连接池缓存Statement的数量 --> <property name="hibernate.c3p0.max_statements">100 </property> <!-- C3P0连接池空闲连接检查时长 --> <property name="hibernate.c3p0.idle_test_period">3000 </property> <property name="hibernate.c3p0.acquire_increment">2 </property> <property name="hibernate.c3p0.validate">false</property>
3.数据库方言
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
4.JNDI数据源连接属性
<!--JNDI数据源,必填--> <property name="connection.datasource">java:comp/env/jdbc/manage</property> <!--JNDI提供者的URL,选填--> <property name="jndi.url">file:/</property> <!--JNDI InitialContextFactory实现类,选填--> <property name="jndi.class">xxx</property>
5.事务属性
<!--事务工厂的类型,必须是TransitionFactory的子类--> <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> <!--一个JNDI名--> <property name="jta.UserTransaction">jta/usertransaction</property> <!--事务完成后是否刷新数据到数据库--> <property name="hibernate.transaction.flush_before_completion">true</property> <!--事务结束后是否关闭Session--> <property name="hibernate.transaction.auto_close_session">true</property>
6.二级缓存相关属性
<!--设置二级缓存CacheProvider的类名--> <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property> <!--以频繁的读操作实现最小化写操作,对集群缓存有用--> <propertyname="hibernate.cache.use_minimal_puts">true</property> <!--是否启用二级缓存--> <property name="hibernate.cache.use_second_level_cache">true</property> <!--是否允许查询缓存--> <property name="hibernate.cache.use_query_cache">true</property> <!--设置查询缓存工厂的类名--> <property name="hibernate.cache.query_cache_factory">xxx</property> <!--设置二级缓存区名字的前缀--> <property name="hibernate.cache.region_prefix">hibernate.test</property> <!--是否强制以可读性更好的格式将数据存入二级缓存--> <property name="hibernate.cache.use_structured_entries">true</property>
7.其他属性
<!--是否在控制台输出Hibernate生成的SQL语句--> <property name="hibernate.show_sql">true</property> <!--是否将SQL语句转化为格式良好的SQL--> <property name="hibernate.format_sql">true</property> <!--是否在Hibernate生成的SQL语句中添加有助于调试的注释--> <property name="hibernate.use_sql_comments">true</property> <!--JDBC抓取数量的大小-> <property name="hibernate.jdbc.fetch_size">10</property> <!--使用JDBC2的批量更新的大小--> <property name="hibernate.jdbc.batch_size">10</property> <!--是否根据映射文件自动建立数据库表--> <property name="hibernate.hbm2ddl.auto">update</property>
对象的种类
持久化对象:POJO实例,与特定的Session相关联,并对应数据表的指定记录
瞬态对象:通过new关键字创建的JAVA实例,在没有与Session相关联时,处于瞬态
托管对象:一个曾经持久化的实例,因为Session的关闭处于托管态
持久化对象的方法
save(Object obj),persist(Object obj)
区别:save方法立即将持久化对象的数据插入数据库,并返回对象的标识属性值; persist方法保证当它在一个事务外部被调用时,并不立即转化为insert语句
装载持久化实例的方法
load,save
区别:使用load方法不会立即访问数据库,如果指定延迟加载而又找不到记录,则返回未初始化的代理对象
保存托管对象修改的方法
update,merge,updateOrSave
区别:如果不清楚对象是否持久化过,则使用updateOrSave; merge不会持久化给定对象,仅仅将托管态对象的修改内容保存到数据库
hibernate映射文件
1.根元素:hibernate-mapping
支持的属性:schema,catalog,default-cascade(默认级联风格),default-access(默认访问策略),default-lazy(默认延迟加载策略),package(包前缀),auto-import(是否使用非全限定名)
2.子元素:class
支持的属性:table,discriminator-value,mutable,proxy,dynamic-update,dynamic-insert,select-before-update,where,batch-size,optimistic-lock,check
3.映射主键:id
支持的属性:name(标识属性名),type(数据类型),column(映射的数据列名),access(访问策略)
主键生成策略: increment,identify,sequence,hilo,seqhilo,uuid,guid,native,assigned
4.映射普通属性:property
支持的属性:column,type,formula,access,lazy,unique,not-null,optimistic-lock,generated,index,unique_key,length,scale
<?xml version="1.0" encoding="gb2312"?> <!-- 指定Hiberante3映射文件的DTD信息 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- hibernate-mapping是映射文件的根元素 --> <hibernate-mapping package="org.crazyit.app.domain"> <!-- 每个class元素对应一个持久化对象 --> <class name="News" table="news_table"> <!-- id元素定义持久化类的标识属性 --> <id name="id"> <generator class="identity"/> </id> <!-- property元素定义常规属性 --> <property name="title" not-null="true"/> <property name="content"/> <!-- 通过formula指定该属性值没有对应的实际数据列 该属性值将由系统根据表达式来生成--> <property name="fullContent" formula="(select concat(nt.title,nt.content) from news_table nt where nt.id= id)"/> </class> </hibernate-mapping>
5.映射集合属性:list,set,map,array,primitive-array,bag
支持的属性:name,table,schema,lazy,inverse(在双向关联关系中不控制关联关系),cascade(持久化操作是否会级联到关联的子实体) 使用key元素来保存外键列 column,on-delete,property-ref,not-null,update,unique 使用<list-index>,<map-key>,<map-key-many-to-many>映射索引列
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.crazyit.app.domain"> <class name="Person" table="person_inf"> <!-- 映射标识属性 --> <id name="id" column="person_id"> <!-- 指定主键生成器策略 --> <generator class="identity"/> </id> <!-- 映射普通属性 --> <property name="name" type="string"/> <property name="age" type="int"/> <!-- 映射List集合属性 --> <list name="schools" table="school"> <!-- 映射集合属性数据表的外键列 --> <key column="person_id" not-null="true"/> <!-- 映射集合属性数据表的集合索引列 --> <list-index column="list_order"/> <!-- 映射保存集合元素的数据列 --> <element type="string" column="school_name"/> </list> </class> </hibernate-mapping>
6.映射组件属性:component
支持的属性:class,insert,update,access,lazy,optimistic-lock,unique
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.crazyit.app.domain"> <class name="Person" table="person_inf"> <!-- 映射标识属性 --> <id name="id" column="person_id"> <!-- 指定主键生成器策略 --> <generator class="identity"/> </id> <!-- 映射普通属性 --> <property name="age" type="int"/> <!-- 映射组件属性name,组件属性的类型为Name --> <component name="name" class="Name" unique="true"> <!-- 指定owner属性代表容器实体 --> <parent name="owner"/> <!-- 映射组件属性的first属性 --> <property name="first"/> <!-- 映射组件属性的last属性 --> <property name="last"/> </component> </class> </hibernate-mapping>
Hibernate的关联映射
关联关系有一对一,一对多,多对多之分,且有双向和单向之别
Hibernate的继承映射
1.采用subclass元素
这种情况下整个继承树的所有实例都保存在同一个表中,需要在表中增加一列,来区分该行元素是属于哪一个实例
2.采用joined-subclass元素
这种情况下父类和子类共有的属性保存在父类表中,子类增加的属性保存在子类表中。无需使用辨别者列,但需要为每一个子类使用key元素映射共有的主键
3.采用union-subclass元素
这种情况下父类实例的数据保存在父表中,子类实例保存在子表中,子类表的字段要比父类表的字段多
Hibernate的批量处理
1.批量插入
由于Session维持有一个必选的一级缓存,所以需要定时将Session缓存中的数据刷入数据库(session.flush,session.clear)
2.批量更新、删除:executeUpdate
HQL查询
1.获取Session对象
2.编写HQL语句
3.调用Session的createQuery方法创建查询对象
4.调用Query的set方法为参数赋值
5.调用Query对象的list或uniqueResult方法返回查询结果列表
from语句,连接语句,select语句,聚集函数,多态查询,where语句,表达式,order by子句,group by子句,自查询,命名查询
条件查询
1.获取Session对象
2.以Session对象创建Criteria对象
3.使用Restrictions的静态方法创建Criterion查询条件
4.向Criteria查询中添加Criterion查询条件
5.调用Criteria对象的list或uniqueResult方法返回查询结果集
聚合,投影:setProjection(Projection projection)
原生SQL查询 addEntity addScalar