mySql数据库的隔离级别
Mysql:
查询隔离级别: select @@tx_isolation; REPEATABLE-READ (可重复读)
更改隔离级别: set transaction isolation level read uncommitted;(未提交读, 没commit也能读到)
cascade="all" 级联操作
inverse="true" 控制反转
◆继承映射
1)父、子类在一个表中:
<class name="Animal" package="extendsMapping" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<!--鉴别器要紧挨着放到id下面这个string是hibernate类型,也可以-->
<discriminator column="type" type="string"/>用java类型
<property name="name"/>
<property name="sex"/>
<subclass name="Pig" discriminator-value="P">
<property name="weight"/>
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height">
</subclass>
</class>
2)每个父、子类在一个表中:
<class name="Animal" package="extendsMapping" table="t_animal">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="sex"/>
<joined-subclass name="Pig">
<key column="pid"/>
<property name ="weight"/>
</joined-subclass>
<joined-subclass name="Bird">
<key column="bid"/>
<property name="height"/>
</joined-subclass>
</class>
3)父类无表(有,设成抽象也不导出的),每个子类都对应一张表:(子类间id不能从)
<class name="Animal" package="extendsMapping" table="t_animal" abstract="true">
<id name="id">
<generator class="assigned "/><!--主键不能重复需要手动分配-->
</id>
<property name="name"/>
<property name="sex"/>
<union-subclass name="Pig" tabble="t_pig">
<property name="weight"/>
</union-subclass>
<union-subclass name="Bird" tabble="t_birg">
<property name="height"/>
</union-subclass>
</class>
◆component 映射 :
在hibernate中,component是实体对象的逻辑组成部分,component与实体对象的本质区别是它没有oid,
component的好处,它实现了对象的层次细粒度划分,层次分明,利于复用
<hibernate-mapping>
<class name="mapping.User">
<id name="id">
<generator class="native"/>
</id>
<property name="name">
<component name="contact">
<property name="contactTel"/>
<property name="email"/>
<property name="zipCode"/>
<property name="address"/>
</component>
</hibernate-mapping>
◆复合主键(联合主键)映射
通常将复合主键相关的属性,放到单独的实体类中
该实体类
● 必须实现序列化接口 implements Serializable
● 必须重写equals和hashcode方法
<hibernate-mapping>
<class name="ormapping.FiscalYearPeriod" table="t_fiscal_year_period">
<composite-id name="fiscalYearPeriodPK">
<key-property name="fiscalYear"/>
<key-property name="fiscalPeriod"/>
</composite-id>
<property name="beginDate"/>
<property name="endDate"/>
<property name="periodSts"/>
</class>
</hiberante-mapping>
◆集合映射映射
●set
●list
●array
●map
<hibernate-mapping>
<class name="ormapping.CollectionMapping">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="setValues" table="t_setvalues">
<key column="setid"/>
<element type="string" column="value"></element>
</set>
<list name="listValues" table="t_listvalues">
<key cloumn="lid"/>
<list-index column="list_index"/><!--维护list的顺序-->
<element type="string" column="value"/>
</list>
<array name="arrayValues" table="t_arrayvalues">
<key column="arrayid"/>
<list-index column="array_index"/>
<element type="string" column="value"/>
<!--如果不是普通属性用<composite-element>-->
</array>
<map name="mapValues" table="t_mapvalues">
<key column="mapid">
<map-key type="string" column="key"/>
<element type="string" column="value"/>
</map>
</class>
</hibernate-mapping>
◆树的映射,
节点-父节点 many-to-one, 节点-子节点 one-to-many
<hibernate-mapping>
<class name="ormapping.Node" table="t_node">
<id name="id">
<generator class="native"/>
</id>
<porperty name="name"/>
<property name="levle"/>
<property name="leaf"/>
<!--<many-to--one>在多的一段加个外键指向一的一端,这个例子中就一个表,加的外键指向本表,即自关联-->
<many-to-one name="parent" column="pid"/>
<set name="children" lazy="extra" inverse ="true">
<key column="pid"/>
<one-to-many class="ORMapping.Node" >
</set>
</class>
</hibernate-mapping>
◆ hibernate中的锁
悲观锁:其实现一般依赖于数据库提供的机制,在整个处理过程中数据将处于锁定状态
例如: select * from user for update
select * from user for update nowait(oracle用)
hibernate中用 load(Class theClass,Serializable id,LockMode lockMode),
lockMode: UPGRADE(ORACLE用 UPGRADE_NOWAIT)
乐观锁:大多数是基于数据版本记录机制实现(version),一般在数据库中加一个version字段
读取数据时连同版本号一同读出,之后更新是版本号加一,如果提交数据小于当前版本
号则认为数据是过期的否则才能更新。(也有用时间戳实现的。)
<hibernate-mapping>
<class name="ormapping.user" optimistic-lock="version" ><!--不写也可以默认就是version-->
<id name="id">
<generator class="uuid"/>
</id>
<version name="version"/>
<property name="name"/>
...
</class>
</hibernate-mappin>
hibernate的 lazy(延迟加载):
lazy的策略可以用在:
● <class>标签上,可以去值:true/false
● <property>标签上,可以取:true/false,这个属性需要类增强工具
● <set><list>等集合上,可以去值:true/false/extra
● <one-to-one>和<many-to-one>(单端关联)等标签上,可以取:false/proxy/noproxy
概念:
● lazy是只有需要的时候才发出sql语句
● hibernate支持lazy策略,只有session打开状态才有效可以用 ThreadLocale和Filter->OpenSessionInView来解 决。
hibernate在class级别的lazy可以控制什么时候加载这些普通属性(property),但不能控制many-to-one one-to-many等。
hibernate在集合上的lazy策略,可以取值ture/false/extra (智能推荐)
hibernate在单端关联的lazy策略<one-to-one>和<many-to-one>,可以取值: false/proxy/noproxy(noproxy需要类增强工具)
◆ HQL查询
1 简单属性查询
●单个属性查询,返回结果集为单个属性的集合。
List students= session.createQuery("select name from Student").list();
//students 为name对应的类型String集合List<String>
for(Iterator iter=students.iterator();iter.hasNext()){
String name =(String)iter.next();
}
●多个属性查询,返回结果为对象数组的集合,对象数组的长度取决于查询属性的个数,类型取决于属性类型
List students = session.createQuery("select id,name from Student").list();
for(Iterator iter=students.iterator();iter.hasNext()){
Object[] objs=(Object[])iter.next();
}
●多个属性查询,用hql动态实例化对象返回
List students = session.createQuery("select new Strudent (id,name) from Student").list();
for(Iterator iter=students.iterator();iter.hasNext()){
Student student = iter.next();
}
●别名
List students = session.createQuery("select s.id, s.name from Student s").list();
或
List students = session.createQuery("select s.id, s.name from Student as s").list();
2 查询实体对象
●查询实体对象 可以忽略select,但如果用select了必须使用别名,hql不支持*,支持count(*)
List students = session.createQuery("from Student").list();
//List students = session.createQuery("select s from Student as s").list();
for(Iterator iter=students.iterator();iter.hasNext()){
Student student = iter.next();
}
●)n+1问题,在默认情况下使用query .iterate()查询,可能会引发n+1问题,所为n+1是指在查询
对象的时候发出了n+1条查询语句
1:首先发出查询实体对象id列表的sql
n:根据id在缓存中查询,如果缓存中有与之匹配的数据,那么就区缓存中的数据,否则依次根据id发出查询语句。
●)query.list()默认只往缓存中放不从缓存中读。
发出 select student0_.id as id1_,student0_.name as name1,.... from t_student as student0_
query.iterate(),会利用缓存读取查询,第一次查询 会发出n+1条select语句,1为先查id的sql语句,然后根据id 查
n为记录的总数,如果第2回就不会了....
select student0_.id as col_0_0_ from t_student as student0_
select student0_.id as col_0_0_,student0_.name as name1,.... from t_student as student0_ where student0_.id = ?
3 条件查询
可以拼HQL串,
List students = session.createQuery("select s.id ,s.name from Student s where s.name like '%1%'").list();
方法链编程,传递参数不需要''号
●采用?传递参数
List students = session.createQuery("select s.id ,s.name from Student s where s.name like ? ").setParameter(0,"%1% ").list();
●采用 :参数名传递
List students = session.createQuery("select s.id ,s.name from Student s where s.name like : myname
").setParameter("myname","%1%").list();
● 条件查询支持in ,通常用setParameterList来赋值
List students = session.createQuery("select s.id ,s.name from Student s where s.id in (:myids) ")
.setParameterList("myname",new Objects[]{1,3,5}).list();
●between
List students = session.createQuery("select s.id ,s.name from Student s where s.createTime
between ? and ? order by s.id ").setParameterList(0,mydateformat.parse("2008/08/01")).setParameterList(1,dateformat.parse("2008/08/25")).list();
●调用数据库的函数
List students = session.createQuery("select s.id ,s.name from Student s where date_format(s.createTime,'%Y-%m')=? order by s.id ")。setParameterList(1,"2008/08/25").list();
4 外置命名查询
● 在映射文件中采用<query>类定义hql
<hibernate-mapping>
<class name=...>
...
</class>
<query><![CDTA[
select s from Student s where s.di <?
]]>
</query>
</hibernate-mapping>
●在程序中使用session.getNamedQuery()方法来得到查询(query对象)
5 查询过滤器
●定义过滤器参数
●在类映射文件中使用过滤参数
●在程序中启用过滤器
<hibernate-mapping>
<class name=...>
...
<!--在类映射文件中使用过滤参数-->
<filter name="filtertest" condition="id < :myid " />
</class>
<!--定义过滤器参数-->
<filter-def name="filtertest">
<filter-param name="myid" type="integer">
</filter-def>
<hiberante-mappingapping>
//在程序中启用过滤器,并设置参数
session.enableFileter("filtertest").setParameter("myid",10);
6.hibernate3开始支持原生sql查询
//返回结果是对象数组的集合,顺序同数据库中表的顺序
session.createSqlQuery("select * from t_student").list();
for(Iterator iter=students.iterator();iter.hasNext()){
Object[] objs=(Object[])iter.next();
}
7分页查询
session.createQuery("from student").setFirstResult(0).setMaxResults(2).list();
8 对象导航查询 在hql中,使用.进行导航
session.createQuery("select s from student s where s.classes.id <5")
9 连接查询
●内连接
session.createQuery("select c.name, s.name from Student s join s.classes c").list();
●外连接(左连接/右连接)
左连接 把所有班级都显示出来
session.createQuery("select c.name, s.name from Classes c left join c.students s").list();
右连接 把所有学生都显示出来
session.createQuery("select c.name, s.name from Classes c right join c.students s").list();
10.统计查询
List students=session.createQuery("select count(*) from Student").list();
Long count = (Long)students.get(0);
Long count=session.createQuery("select count(*) from Student").uniqueResult();
session.createQuery("select c.name,count(s) from Student s join s.class c
group by c.name order by c.id").uniqueResult();
hibernate的一级缓存
一级缓存的生命周期和session一致,随着session的关闭而销亡。
●get/load/iterate(查询实体对象)使用一级缓存
一级缓存缓存的是实体对象。
如何管理一级缓存
●session.clear/session.evict
如何避免一次性大批量的实体数据插入
●先flush,在clear清除缓存
hibernate的二级缓存
二级缓存也是缓存实体类
二级缓存也称进程级缓存或叫SessionFactory级缓存,它可以被所有session共享
二级缓存的生命周期伴随SessionFactory的生命周期存在和销往
SessionFactory可以管理二级缓存
二级缓存的配置和使用:
●将ehcache.xml文件拷贝到src下
●在hibernate.cfg.xml中配置启用二级缓存,默认就是开启
<hibernate-configuration>
<session-factory>
...
<!--是否启用二级缓存-->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--指定使用的二级缓存产品-->
<property name="hibernate.cache.EhCacheProvider_class"
</session-factory>
</hibernate-configuration>
●指定哪些实体类使用二级缓存
1)可以在hibernate.xml配置文件中定义
<class-cache class="xxx" usage="read-only"/>
2)可以在映射文件中配置缓存策略
<hibernate-mapping>
<class name="xxx">
<cache usage="read-only"/>
</class>
</hibernate-mapping>
●一二级缓存的交互,通过setCacheMode(Cache.Mode.GET)(PUT)默认读写
hibernate的查询缓存
查询缓存是针对普通属结果集的缓存
对实体对象的结果集只缓存主键id.
查询缓存的生命周期,当查询关联的表发生修改,那么查询缓存的生命周期结束。
查询缓存的配置和使用:()
在hibernate.cfg.xml文件中加入
<property name="hibernate.cache.use_query_cache">true</property>
在程序中显式开启查询缓存
query.setCacheable(true);
说明:转义字符应以“&”开头,以“;”结尾。
HTML常用转义字符:
字符 | 转义字符 | 描述 |
& | & | 和 |
< | < | 小于号 |
> | > | 大于号 |
" | " | 双引号 |
| | 空格 |
© | © | 版权符 |
® | ® | 注册符 |
XML常用转义字符:
字符 | 转义字符 | 描述 |
& | & | 和 |
< | < | 小于号 |
> | > | 大于号 |
" | " | 双引号 |
' | ' | 单引号 |