hibernate API笔记 仅供查找!

为了通过反射机制来实例化对象,需要提供一个无参的构造函数

使用static实现全局的初始化操作,
private static final.... 在static进行new初始化...然后在使用一个get方法来获取实例
这样使用与用一个Util辅助类的形式来创建单例

<property name="hbm2ddl.auto">create</property> 用于自动创建数据库,第一次使用后可以注释掉,否则表示删除继续重建

inverse用于设置在多方

POJO:Plain Old Java Object

为了使用延迟关联加载代理.不要在非Final类中声明public final方法

cascade表示级联 all为全部 默认为none,通常使用在one-to-one 和one-to-many关系中,
如果子对象的寿命限定在父对象的寿命之内,可以通过cascade="all,delete-orphan" 变成自动生命周期管理的对象

可以在set里面添加order-by来增加排序语句

get方法不抛出异常,load方法会抛出异常
使用的都是session.get(Cat.class,主键值);
进行加载 其中get无的情况下,会得到null对象

查询
HQL QBE QBC SQL

HQL中可以使用复杂的对象或者简单的类型来生成查询条件
比如
List cats=session.createQuery("from Cat as cat where cat.birthdate < ?") . setDate(0,date).list();
同样可以使用setEntity(0,对象实例) 来直接加入对象进行条件映射
.setString设置简单的字符串

如果返回的结果只有一个,可以使用.setEntity()等条件后.uniqueResult(),这样返回一个Object,然后进行类型的强制转换

也可以使用 Set uniqueMothers = new HashSet(query.list())来过滤重复的查询结果

使用迭代式的获取结果Iterating
某些情况下使用iterate方法得到更好的性能,不过是在缓存或者session已存在的情况,不然更慢

有的时候根据语句会生成Object[]形式的结果,按照例子都是用.list().iterator()的方法执行查询,然后进行遍历,通常只有一个结果
其中第一个就是Object[]

标量查询...就是统计函数等,count min等SQL函数,同样使用上面的方法进行遍历结果
while(results.hasNext())
{
Object[] row = (Object[]) result.next();
Color type=(Color)row[0]
Date oldest = (Date) row[1].... 使用对象类型进行接受(值类型使用对应的包装类型)
}


绑定参数  主要形式有? 和:参数名 两种方法

:参数名 形式
Query q=session.createQuery("from xx where c=:name");
q.setString("name","XXXX")

?形式 使用0开始的下标索引

还有一种批量的设置单个元素为多条件的方法 比如使用在sql的 in方法之上时
Query q = session.createQuery("from Deon cat where cat.name in (:nameList)");
q.setParameterList("nameList",names);
List cats = q.list();

分页
Query q = session.createQuery("from Domec cat");
q.setFirstResult(20);
q.setMaxResults(10);
List cats = q.list();

集合过滤器是一种用于一个持久化集合或者数据的特殊查询,

Collection blackKittens = session.createFilter(pk.getKittens(),"where this.color = ?").setParmeter(Color.Black,
Hibernate.custom(ColorUserType.class)).list()
可以不使用from,同时也可以设置返回结果

使用原生的SQL的查询
可以使用session.Connection()来获取JDBC Connection对象
也可以使用
List cats = session.createSQLQuery("SELECT {cat.*} FORM CAT {car} WHERE ROWNUM<10","cat",Cat.class).list();
进行直接的SQL语句调用,比如把sql别名用{}大括号包围起来

可以使用session.flush() 把当前session中的数据进行刷新

如果使用native方式生成的ID(主键) 他们一执行save就会被插入


拦截器--功能更类似与触发器,用于在Hibernate触发操作的时候自动调用
分为两个级别 session和sessionfactory

通过继承EmptyInterceptor类来实现. 加载到Session的方法,在openSession的方法中传入new 接口实现类() 进行注册
也可以使用在new Configuration().setInterceptor(new AuditInterceptor()) 来注册SessionFactory级别的拦截器

同样也可是用事件系统来代替拦截器,或者作为拦截器的补充

可以用编程的方式和xml来注册事件
其中编程的方法可以共享一个实例

比如loadEvent需要实现LoadEventListener

Configuration cfg = new Configuration();
LoadEventListener[] stack = {new MyloadListener(),new DefaultLoadEventListener()};
cfg.EventListeners().setLoadEventListeners(stack);
其中第一个为接口实现类,第二个为接口

批量插入(Batch inserts)
在循环添加的时候.使用session.flush()和session.clear()进行内存的释放,最好的和JDBC批量设置相同 如下
hibernate.jdbc.batch_size=20
也可以在批量处理时关闭二级缓存
hibernate.cache.use_second_level_cache false 当不是必须的,还有其他的方法

同样更新的时候也适合于清空内存

HQL查询

最简单的就是 form 实体类名  也可以使用as取别名, 不过可以省略
也可以使用,分开进行多表查询

关联的方式
inner join 内连接
left outer join 左外连接
right outer join 右外连接
full join 全连接 不常用

其中可以简写去掉outer

也可以使用with关键字 提供而外的join条件
from Cat as cat left join cat.kittens as kitten with kitten.bodyWeight>10

fetch连接允许使用一个选择语句相一组集合随着他们父对象的初始化而初始化,有效的代替了配置文件中的外连接和延迟声明
from Cat as cat inner join fetch cat.mate left join fetch cat.kittens
不过不可以和独立的with条件 以及setMaxResult等一起使用

join的语法包括显示和隐式的两种, 在HQL中直接写入的为显式,使用多个.个进行属性编写的为隐式,都会在生成的SQL中加入join

查询语句可以返回多个对象或属性,存放在Object[]队列中,也可以存放在一个list 或者一个对象中(自定义的构造函数) 下面描述例子

select new list(属性,属性...)
select new Family(属性,属性,属性);  这个尤其比较有用

也可以直接在HQL里面写上SQL的统计函数,并且封装成Map对象
select new map(max(属性) as max, min(bodyWeight) as min,count(*) as n) from Cat cat
其中会生成别名为key的键值对map


聚集函数---上面说到的SQL统计函数

受支持的聚集函数如下
avg(..) sum() min() max() count() count(distinct...) count(all...)

多态查询,当进行一个父类查询的时候,会返回子类的实例,或者实现了该接口的实例
from java.lang.Object o 将返回所有的对象

在HQl中的=运算符 可以直接用来比较对象

特殊属性的小写 id 可以作为对象的标识符(主键) 也可以使用在符合主键里面 id.子组件属性名

特殊属性的class用于在多态查询的时候 指定一个实例鉴别来保存对象
from Cat cat where cat.class = DomesticCat

表达式...非常多

常用的有in('','','') 和between 'a' and 'b'

特殊属性 size(属性) 用于测试一个集合的大小
from Cat cat where size(cat.kittens) > 0
或者from Cat cat where cat.kittens.size > 0

对于有序索引下的集合 可以使用minelement与maxelement函数来引用其中的一个最大值或最小值

在集合的查询中 可以使用更多的关键字,不过都只能使用where子句中
包括了any some all exists in  专用与集合的条件
或者结构变量 size,elements,indices,minindex,maxindex,minelements

也可以使用[]进行组合的操作 (查询结果的数组)

like子句用于实现模糊查询 可以使用upper(属性) 进行字母的大小化处理  like 'FRI%' %% %'都可以

也可以使用order by 对象.属性 asc,... 进行排序,可以进行多次排序 desc也可以

group by 进行分组

注意group by 和order by 子句不能包含算术运算符

子查询
通常和SQL聚集函数一起使用,需要用()括号包围起来

from Dome as cat where cat.name not in (select name.nickName form Name as name);
注意HQL子查询只能在where或者select子句中出现

也可以使用复杂的子查询
from Cat as cat where not (cat.name,cat.color) in (select cat.name,cat.color from DomesticCat cat);

统计查询结果 不用初始化集合
((Integer) session.iterate("select count(*) from ....").next()).intValue();

使用JavaBean的属性简化命名查询:name格式的Query生成
Query q = s.createQuery("from Foo as foo where foo.name=:name and foo.size =:size")
q.setProperties(fooBean); //foobean包含了方法getName()与getSize();
List foos=q.list()

使用集合与过滤器一起使用,集合是可以分页的....不太懂
Query q = s.createFilter( collection, "");
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();


条件查询 QBC
创建一个Criteria 实例

Criteria crit = session.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list()
使用Session创建一个Criteria接口的实例

限制结果集内容
Restrictions类定义了获取某些内置Criterion类型的工厂方法
Criteria crit = session.createCriteria(Cat.class)
.add(Restrictions.like("name","Friz%")) //模糊查询
.add(Restrictions.between("weight",minWeight,maxWeight))
.list();

约束可以按逻辑分组
List cats = sess.createCriteria(Cat.class)
   .add(Restricrions.like("name","Fir%"))
   .add(Restrictions.or(
        Restrications.eq("age",new Integer(0)),
Restrictions.isNull("age")
)).list();

也可以直接使用SQL

List cats = sess.createCriteria(Cat.class)
   .add(Restrictions.sqlRestriction("lower({alias}.name) like lower(?),"Frix%",Hibernate.STRING"))
    .list();

Property实例是获取一个条件的另外一种途径
Property age = Property.forName("age");
List cats = sess.createCriteria(Cat.calss)
.add(Restrications.disJunction()
.add(age.isNull())
.add(age.eq(new Integer(0) ) )
)).add(Property.forName("name").in(new String[]{"fize","Izi"}))
.list();

结果集排序
使用Order类或者接口

List cats = session.createCriteria(Cat.class)
.add(Restrictions.like("name","F%"))
.addOrder( Order.asc("name"))
.addOrder( Order.desc("age"))
.setMaxResults(50)
.list();

同样也是用
addOrder(Property.forName("name").asc()) 来代替

关联 多个实体 用于建立约束
List cats = session.createCriteria(Cat.class)
.add(Restrictions.like("name","f%"))
.createCriteria("kittens")
   .add(Restrictions.like("name","F%"))
.list();

.ResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP) 增加结果的条件预过滤

动态关联抓取 使用setFetchMode()在运行时定义动态关联抓取
List cats = session.createCriteria(Cat.class)
.add(Restrictions.like("name","Fri%"))
.setFetchMode("mate",FetchMode.EAGER)
.setFetchMode("kittens",FetchMode.EAGER)
.list();
这个例子是通过外连接来抓取两个属性

使用Example类,允许通过一个给定实例构建一个条件查询....就是findByExample()
Cat cat = new Cat();
cat.setSex('F');
List results = session.createCriteria(Cat.class)
.add(Example.create(cat))
.list();

可以自行调整Example使之更实用....通过对Example实例的操作
Example example=Exam.create(cat)
.excludeZeroes()
.excludeProperty("color")
.enableLise();
List results = session.createCriteria(Cat.class)
.add(example)
.list();

使用Projection进行SQL聚合函数的使用

List results = session.createCriteria(Cat.class)
.setProjection(Projections.rowCount())
.add( Restrictions.eq("color",Color...))
.list()
也可以同时添加多个Projections

List results = session.createCriteria(Cat.class)
.setProjection(Projections.projectionlist()
.add(Projections.rowCount())
.add(Projections.avg("weight"))
.add(Projections.max("weight"))
.add(Projections.grunpProperty("color"))
).list()

可以使用alias()和as()方法简便的将一个投影实例取个别名,宫其他实例引用
List results = session.createCriteria(Cat.class)
.setProjection(Projections.groupProperty("color").as("colr"))
.addOrder(Order.asc("colr"))
.list();

同样在添加到投影列表的时候
List results = session.createCriteria(Cat.class)
.setProjection(Projections.projectionList()
.add(Projections.rowCount(),"别名")
)
.addOrder(Order.desc("别名"))
.list();


DetachedCriteria类用于在一个session范围之外创建一个查询,并且可以使用任意的Session来执行

DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
.add(Property.forName("sex").eq('F'));
然后在session中
List results = query.getExectableCriteria(session).setMaxResulets(100).list()


原生的Native SQL 查询

对原生SQL查询执行的控制通过SQLQuery接口进行,通过执行Session.createSQLQuery()获取这个接口

最基本的SQL查询模式
session.createSQLQuery("SELECT * FROM CATS").list();
将返回一个Object数组(Object[])组成的List

也可以指定返回的类型,以及返回的数量
session.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID",Hibernate.LONG)
.addScalar("NAME",Hibernate.STRING)
.addScalar("BIRTHDATE",Hibernate.DATE);
这个语句仅仅会返回这三个字段

也可以使用addEntity()让原生查询返回实体对象
session.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
同样也可以在SELECT语句里面指定返回的属性,然后进行部分封装

均返回一个List
使用addJoin("对象.外键对象属性")
用于减少数据库开销


同样也可以使用在返回多个实体的情况下
session.createSQLQuery("SELECT {c.*},{m.*} FROM CATS c,CATS m WHERE c.MOTHER_ID = c.ID")
.addEntity("cat",Cat.class)
.addEntity("mother",Cat.class)
尤其注意加上{} 为了避免两个实体内相同的属性名

返回非受管实体(Returning non-managed entities). 使用ResultTransformer
session.createSQLQuery("SELECT NAME,BIRTHDATE FROM CATS")
.serResultTransformer(Transformers.aliasToBean(CatDTO.class))
会查询出指定的值,并注入到对应的属性中

在原生的SQL查询中,可以使用query.setString 设置对应的参数 包括了?和:两种


存储过程的调用

对于存储过程的查询无法使用setFirstResult 或者setMaxResults()进行分页查询
其他没有详细的说明

抓取策略
可以在ORM映射的元数据中声明,也可以特定的HQL或者QBC语句中重载声明

hibernate.default_batch_fetch_size 用于设置批量抓取的优化

通常的情况下不对抓取策略进行定制,更多的是,保持其默认值,然后在特定的事务中,使用HQL的左外连接抓取(left join fetch)
对其进行重载, 在QBC中,应该调用setFetchMode(FetchMode.JOIN)语句,可以针对具体属性
例如

User user =(User)session.createCriteria(User.class)
.setFetchMode("permissions",FetchMode.JOIN)
.add(Restrictions.idEq(userId))
.uniqueResult();

Hibernate.initialized(Object) 会强制对代理初始化

初始化部分集合的方式
1:求大小
((Integer) s.createFilter(collection,"select count(*)").list().get(0)).intValue()

也可以使用createFilter()方法来有效的抓取集合的部分内容,无需实例化整个集合
s.createFilter(lazyCollection,"").setFirstResult(0).setMaxResults(10).list();

使用批量抓取
在<class name="Person" batch-size="10">...<> 定义在一方
这次每次在多方就会查询10个多方结果


二级缓存(The Second Level Cache)

通过在Hibernate.cache.provider_class属性指定org.Hibernate.cache.CacheProvider的某个实现的类名,
用于选择让HIbernate使用哪个缓存实现...比如EhCache
org.hibernate.cache.EhCacheProvider

缓存映射, 类或者集合中 使用<cache>元素
<cache usage="缓存的策略"
region="RegionName" 默认为类或者集合的名字,指定二级缓存的区域名
include="all || non-lazy" 默认为all
>

也可以在hibernate.cfg.xml中指定<clas-cache>和<collection-cache>元素 来指定缓存

使用session.evict(cat) 可以手动在一级缓存中移除该对象
session.contains()方法,判断某个实例是否处于当前session缓存中
session.clear()方法会清空所有缓存中的对象

对于二级缓存,需要使用Sessionfactory中的方法. 清空缓存中实例,整个类,集合实例,或者整个集合
evict 和evictCollection方法

CacheMode参数用于控制具体的Session如何与二级缓存进行交互
CacheMode  ..NORMAL GET PUT REFRESH等
通过hibernate.cache.use_minimal_puts的设置,强制二级缓存从数据库中读数据,刷新缓存内容

查看二级缓存区内容 使用Statistics 统计API
Map cacheEntries = sessionFactory.getStatistics().getSecondLevelCacheStatistics(regionName).getEntries()
此时.必须手动打开统计选项
hibernate.generate_statistics  true
hibernate.cache.use_structured_entries true

其中上面所说的RegionName为cache标签中的定义

查询缓存. 需要手打打开
hibernate.cache.use_query_cache true;
用于经常使用同样的参数进行查询时候,才会有作用
需要手动调用Query.setCacheable(true) 才可以调用到查询缓存,以及保存数据到缓存


集合的效率

Lists maps和sets 用于更新效率最高...而bag最低

设计良好的情况下 应该用的比较多的是set 在xml映射中, 而且在多方设置inverse="true" 来处理一对多关联

Bag和list是反向集合类中效率最高的,即双向的一对多关联中
Parent p = (Parent)sess.load(Parent.class,id)
Child c = new Child();
c.setParent(p);
p.getChildren().add(c);
sess.flush
不需要初始化包元素,也能进行添加新元素

一次性的删除并不适用于被映射为inverse="true"的集合


监控Hibernate资源使用情况
如果打开StatisticsService MBean选项, 那么Hibernate可以使用JMX技术,发布其数据记录
可以共享或者分别给SessionFactory分配一个MBean

单向的Many to one可能会导致性能问题(SQL语句过多),所以还是配置双向的好

你可能感兴趣的:(sql,C++,c,Hibernate,cache)