`
goto0917
  • 浏览: 46433 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论
  • take: 这是POI方式,不是JXLS方式. JXLS包路径都是net ...
    jxls

hibernate

阅读更多
一、缓存的分类
1.集群
2.应用级
3.事务级
二、什么时候用缓存
三、缓存的优缺
四、hibernate与ehcache如何实现二级缓存
五、list与iterator的区别
六、get与load主法的区别
七、executeUpate的特点,load,get,update,delete的特点?
八、hibernate如何用连接池
九、spring如何用连接池


一、事务的四大特点
1.原子性(atomic)
要么全成功,要么全失败
2.隔离性(isolate)
事务间不相互影响
3.持久性(persistent)
将数据写入到数据库中
4.一致性(coherence)
业务处理要适合业务逻辑,将相关的操作放到
同一个业务方法
二、没有锁的问题
1.脏读(dirty)
事务1先开始,但没有提交,事务2将在事务1数据的基础上更新了。
事务1:
update buy set amount=amount+1 where buyID=1;
sleep(1000);
rollback;
事务2:
update buy set amount=amount+1 where buyID=1;
commit;
2.覆盖更新(overwrite)
事务1:
update buy set amount=amount+1 where buyID=1;
sleep(1000);
commit;
事务2:
update buy set amount=amount+1 where buyID=1;
commit;
事务1,事务2同进读取数据,事务2的操作被事务1覆盖了。
3.不可重复读:同一个事务内,相同有select得到的结果不一样.
事务1:
update buy set amount=amount+1 where buyID=1;
commit;
事务2:
select * from buy;
sleep(1000);
select * from buy;
commit;
事务1,事务2同时进行
4.幻想读(fancy):第一次读有(没有),第二次读没有(有)
(insert,delete)
事务1:
insert into buy();
commit;
事务2:
select * from buy;
sleep(1000);
select * from buy;
commit;
三、锁的分类
1.读未提交:四大问题都无法处理。
2.读已提交:数据库默认的处理方式.
a.读了的数据都是已提交的,可防止脏读。
b.如果一行正在更新,加锁。
c.提交时会将当行对应的版本与数据库版本比较
  如果小于数据库版本回退,当将操作失败。(可以防止覆盖更新)
d.乐观锁(optimistic)与悲观锁(pessimistic)
pessimistic(铁公鸡):该事务下select了一批数据
,不管更新与否,别的事务都不可以更新
该行.如果它更新,肯定可以成功。
optimistic:该事务下select了一批数据
,如果不更新,别的事务都可以更新
该行,该事务更新时,如果比数据版本低
报错。
3.可重复读:将一个SQl的查询结果备份一份,第二次取时从
     备份的文件中取。
4.串行化(serializable):对整个表加锁,只一个事务可以操作当前表,
       其余事务只能等待。
四、hiberntate的优化
1.用延迟加载
many
大文本
2.用二级缓存
3.更多的选择optimistic而不是pessimistic
1、pessimistic
a.Query query1=session.createQuery("select * from Customer for update");
b.
Query query1=session.createQuery("select * from Customer");
query1.setLockMode("Customer",LockMode.UPGRADE);
2、optimistic:默认是乐观锁
<class optimistic-lock="version/none"/>

4.合理的规划session的生命周期
5.在hibernate.cfg.xml文件中
  设置fetch-size及batch-size参数
  batch-size:在更新或增加数据时,删除时执行多少个sql后
           再向数据库一次传送多个sql.
  fetch-size:从数库一次提取的行数.
  记录条数一般设置为30、50、100。
OracleJDBC驱动默认的Fetch Size=15,
设置Fetch Size为:
30、50性能会明显提升。
6.如有可能,选用uuid作为主键生成器
7.开发过程中,打开hibernate的SQl日志输出(hibernate.show_sql=true),通过观察hibernate生成的sql语句进一步了解其实现原理,
  从而指事实上更好的实现策略。
org.hibernate.Criteria对象,可以在不使用SQL甚至
HQL的情況下进行数据库查询
查询所有的Customer的记录
Criteria crit = session.createCriteria(Customer.class)
查询限定条件,org.hibernate.expression.Expression
Expression.eq("field",value)对应SQL的表达式:field=value
Expression.ge("field",value)对应SQL的表达式:field>=value
Expression.gt("field",value)对应SQL的表达式:field>value
Expression.lt("field",value)对应SQL的表达式:field<value
Expression.le("field",value)对应SQL的表达式:field<=value
Criteria crit = session.createCriteria(Customer.class);
        crit.add(Expression.ge("age", new Integer(20))); //Expression.ge的用法取出年龄>=20的customer的记录
如果要对结果进行排序,可以使用org.hibernate.expression.Order,列如: 
        Criteria crit = session.createCriteria(Customer.class);
crit.add(Expression.ge("age", new Integer(20)));       
        crit.addOrder(Order.asc("customerName"));
        crit.addOrder(Order.desc("age") ) ;
分页
crit.setFirstResult(1);
crit.setMaxResults(2) ;//指定返回条数为3条;
DetachedCriteria类可以脱离session独立存在
      Session session = sessionFactory.openSession();
      DetachedCriteria crit = DetachedCriteria.forClass(Customer.class);
      crit.add(Expression.ge("age", new Integer(20)));
      crit.getExecutableCriteria(session);//
Hibernate Query Language(HQL)查询 
实体查询
String sql="from Customer as customer where customer.age=20";
Query q= session.createQuery(sql);
单个属性查询
       String sql="select customer.customerName from Customer as customer ";
       Query q= session.createQuery(sql);
       q.list();//在这里list集合里的数据就不是一条条Customer实体对象,而是一个个String类型的customerName
       Object[] customerNames=q.list().toArray();//把他转化为对象数组 
       for(int i=0;i<customerNames.length;i++)
       {
     System.out.println(customerNames[i]);
       }
多个属性查询
      String sql="select customer.customerName ,customer.age from Customer as customer ";
      Query q= session.createQuery(sql);
      q.list();//现在我们的list集合元素是一个个对象数组
      Iterator iterator=q.iterate();
      while(iterator.hasNext())//把每个对象数组迭代取出
      {
         Object []obj=(Object[]) iterator.next();//用一个象数组接受 
System.out.println("customerName:"+obj[0]+"   "+"age:"+obj[1]);
      }
取出属性直接转化为一个对象
List<Customer> results=session.createQuery("select new Customer(sex,customerName) from Customer ").list();
for (Customer customer : results)
{
System.out.println(customer.getCustomerName()+"  "+customer.getSex());
}
分组与排序
order by 子句   
      String sql=" from Customer as customer order by customer.age";
      Query q= session.createQuery(sql);
group by ---对某个字段进行分组统计,查询实现同年龄的人的个数
String sql=" select count(customer.customerName),customer.age from Customer as customer group by customer.age";
Query q= session.createQuery(sql);
引用查询
Hibernate提供了HQL可配置化的内置功能,
<class>
.....
.....
</class>
<query name="myhql">
<![CDATA[from Customer as customer where customer.customerName=:customerName]]>
</query>
Customer f=new Customer();
f.setCustomerName("a");
Query q= session.getNamedQuery("myhql");
q.setProperties(f);//给HQL传一个Customer的对象作为参数设进去
联合查询
加fetch后,当Buy对象被加载时就立即填充Cutomer里的buies集合
String sql="from Customer as customer inner join fetch customer.buies";
Query q= session.createQuery(sql);
List list=q.list();
for(int i=0;i<list.size();i++)
{
Customer c=(Customer) list.get(i);
System.out.println(c.getCustomerName()+c.getbuies());
}
没有声明fetch,则得到的list集合里面每一个元素就是一个对象数组,其包括一个Customer对象和一个Customer相对应的Buy对象。
String sql="from Customer as customer inner join customer.buies order by customer.customerName";
Query q= session.createQuery(sql);
List list=q.list();
for(int i=0;i<list.size();i++)
{
Object []obj=(Object[]) list.get(i);
Customer c=(Customer) obj[0];
Buy b=(Buy) obj[1];
System.out.println("客户名 :"+c.getCustomerName()+" 购买物 : " +b.getProductName());
}
左连接:没有fetch
String sql = "from Customer as customer left join customer.buies order by customer.customerName";
Query q = session.createQuery(sql);
List list = q.list();
for (int i = 0; i < list.size(); i++)
{
Object[] obj = (Object[]) list.get(i);
Customer c = (Customer)obj[0];
if (obj[1] != null)
{
Buy b = (Buy) obj[1];
System.out.println("客户名 :" + c.getCustomerName() + " 购买物 : "+ b.getProductName());
}
else
{
System.out.println("客户名 :" + c.getCustomerName()+ " 购买物 : null ");
}
}
Connection con=session.getConnection();
右连接
String sql = "from Customer as customer right join customer.buies order by customer.customerName";
子查询
String sql=" from Customer as customer where (select count(*) from customer.buies)>1"; 
数据加载方式
即时加载
当实体被加载时,立即加载他的关联属性
预先加载:用一个sql语句取出多个对象的信息,用关联实现,只要一个SQL
延迟加载:至少要两个sql
批量加载:batch-size
继承映射:有三种策略
1、一个类一个表。
2、继承同一父类的子类通通映射到一张数据表里面,
   在数据表里加入一个标识字段,
   用于去识别某个字段具体是属于哪个子类或是父类的属性。
create table user2
(
userName varchar(20) primary key,
pwd varchar(20),
guessRemark varchar(20),
adminRemark varchar(20),
DISCRIMINATOR_USERTYPE varchar(30)
);
package hibernate;
public class Users2 implements java.io.Serializable
{

private String userid;

private String username;

private String pwd;
public Users2()
{
}
public String getPwd()
{
return pwd;
}
public void setPwd(String pwd)
{
this.pwd = pwd;
}
public String getUserid()
{
return userid;
}
public void setUserid(String userid)
{
this.userid = userid;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
子类:guest
public class guest extends Users2 {
private String guestRemark;
public String getGuestRemark() {
return guestRemark;
}
public void setGuestRemark(String guestRemark) {
this.guestRemark = guestRemark;
}
public guest() {
}
}
子类:admin类
public class admin extends Users2
{
private String adminRemark;

public String getAdminRemark() {
return adminRemark;
}
public void setAdminRemark(String adminRemark) {
this.adminRemark = adminRemark;
}
public admin()
{
}
}
映射文件中该如何编写,由于这些子类和父类將映射至同一个表格,我门使用discriminator作为每个类记录在
表格中的识别,先直接看看映射文件如何编写:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hibernate.Users2" table="users" discriminator-value="Users">
<id name="userid" type="string">
<column name="USERID" length="32" />
<generator class="assigned" />
</id>
<discriminator column="DISCRIMINATOR_USERTYPE" type="string"/>
<property name="username" type="string">
<column name="username" length="30" />
</property>
<property name="pwd" type="string">
<column name="pwd" length="20" />
</property>
<subclass name="hibernate.guest" discriminator-value="guest">
    <property name="guestRemark" type="string">
<column name="guest_remark" length="20" />
</property>
</subclass>
<subclass name="hibernate.admin" discriminator-value="admin">
<property name="adminRemark" type="string">
<column name="admin_remark" length="20" />
</property>
</subclass>
</class>
</hibernate-mapping>
在查询父类时可以查询所有的子类
在查询子类时只查询子类
三、父类与每个子类建立一数据表,
父类映射的表格与子类映射的表格共享相同的主键值,
父类表格只记录本身的属性,如果要查询的是子类,
则透过外键关联从父类表格中取得继承而來的属性数据。
数据库建立如下:
drop table guest3;
drop table admin3;
drop table user3;
create table user3
( USERID varchar(32) primary key,
  username varchar(30),
  pwd      varchar(20)  
);
create table guest3
(
USERID varchar(32) primary key,
guest_remark varchar(20)
);
alter table guest3 add constraint guest3_fk foreign key(userID) references user3(userID);

create table admin3
(
USERID varchar(32)  primary key,
admin_remark varchar(20)
);
alter table admin3 add constraint admin3_fk foreign key(userID) references user3(userID);

其中guest与admin表格的主键值將与users表格的主键值相同,
guest的主键USERID与admin的主键USERID作为一个外键,
以取得父类的数据。

在映射文件中要实现这种映射,我们使用<joined-subclass>标签,
并使用<key>标签指定子类表格与父类表格共享的主键值,
映射文件的编写方式如下:
   <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hibernate.Users2" table="users" schema="dbo" catalog="t29">
<id name="userid" type="string">
<column name="USERID" length="32" />
<generator class="assigned" />
</id>
<property name="username" type="string">
<column name="username" length="30" />
</property>
<property name="pwd" type="string">
<column name="pwd" length="20" />
</property>
<joined-subclass name="hibernate.guest" table="guest">
           <key column="USERID"/>
           <property name="guestRemark" type="string">
<column name="guest_remark" length="20" />
           </property>
                </joined-subclass>
        <joined-subclass name="hibernate.admin" table="admin">
            <key column="USERID"/>
            <property name="adminRemark" type="string">
<column name="admin_remark" length="20" />
</property>
        </joined-subclass>
</class>
    </hibernate-mapping>
   测试类的代码可以用第二种映射的测试方法去测试。。。。
hibenate中用oracle的sequence
create table customer(
customerID int primary key,
customerName varchar2(20)
);
create sequence customer_sequence;
oracle中的操作
创建一个表、一个序列
在myEclipse中的操作
加入一个数据连接
url=jdbc:oracle:thin:@主机名:1521:数据库名
dirver=oracle.jdbc.driver.OracleDriver
oracle驱动包在:D:\oracle92\jdbc\lib\classes12.jar
加入hibernate环境
生成映射文件,主键的生成机制是sequence,具体的配置如下:
<id name="customerid" type="java.lang.Long">
<column name="CUSTOMERID" precision="22" scale="0" />
<generator class="sequence" >
<param name="sequence">序列名称</param>
</generator>
</id>

Oracle登陆:
cmd
sqlplus 用户名/密码@网络服务名
复合主键:一个表的主键列不是一个而是多个
drop table buy1;
create table buy1
(
buyID int not null,
customerName varchar(20) not null,
buyName varchar(20)
);
alter table buy1 add constraint buy1_pk primary key(buyID,customerName);
会生成一个主键类,这个类的属性就是多个主键对应的属性,
将主键类作为一个整体传给真实的类。
通过get/load查询时也是将主键类的实例作为作为主键值。

blob、clob字段映射
drop table testBlob;
create table testBlob
(
id int primary key,
myImage Blob
);
hibernate的回调与拦截机制
拦截与回调的实现
1、高藕合度
1、每一个数据库数据类实现hibernate的Lifecycle接口,Lifecycle有如下方法
public class Users implements Lifecycle
{
//在增加到数据库之前调用
public boolean onSave() thows CallableException
{

}
public boolean onFlush()
{

}
}
2、校验
public class Users implements Validatable
{
//在增加到数据库之前调用,这个方法可被调用多次
public void validate() thows CallbackException
{

}
}
以上两个机制与hibernate的藕合度太高,
所以可以选择Interceptor实现
2、低藕合度:写一个拦截器,在产生SessionFactory产生Session时将
拦截器通过参数传给openSession()方法,
如果调用其它方法对数据进行持久化操作不会重用前一个
session,但可以重用前一个Session中的Connection
具体使用如下:
Session newSession=SessionFactory.openSession(oldSession.connection());
oldSession与newSession共用同一个Connection因事务在
oldSession中已启动,newSession不用管理具体的事务实现。
public class MyInterceptor implements Interceptor
{
//在增加之前调用
public void onSave()
{
}
//在更新之前调用w
public void onDirtyFlush()
{
}
}
MyInterceptor mi=new MyInterceptor();
Session session=SessionFactory.getSession(mi);
分享到:
评论

相关推荐

    hibernate jar包:hibernate-commons-annotations-4.0.1.Final.jar等

    Hibernate.jar包,Hibernate可以应用在任何使用JDBC的场合,包含 hibernate-commons-annotations-4.0.1.Final.jar hibernate-core-4.1.12.Final.jar hibernate-ehcache-4.1.12.Final.jar hibernate-entitymanager-...

    最新版本的Struts2+Spring4+Hibernate4框架整合

    项目原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6 二、 项目目的: 整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + ...

    hibernate.5.1.0.jar全部

    包含hibernate所有所需jar包还有一些其他包日志包、jpa支持包等: 列如:hibernate-core-5.1.0.Final.jar hibernate-ehcache-5.1.0.Final.jar hibernate-entitymanager-5.1.0.Final.jar hibernate-envers-5.1.0....

    Hibernate连接SQLite配置说明和方言代码

    Hibernate连接SQLite配置步骤: 1、添加SQLite库: 1.1、将两个jar包:com.zy.hibernate.dialect.SQLiteDialect.jar、sqlite-jdbc-3.7.2.jar拷贝到“\WEB-INF\lib”文件夹下; 2、配置hibernate: 2.1、将...

    Java Persistence WIth Hibernate 2nd

    Manning出版 Java Persistence With Hibernate 第二版 清晰pdf Hibernate, an open source project that is almost 15 years old. In a recent poll, Hibernate was among the top five tools used by many Java ...

    hibernate-testjar包

    hibernate

    论坛系统项目(Struts 2+Hibernate+Spring实现)

    论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts...

    hibernate 资料hibernate 资料hibernate 资料

    hibernate 资料hibernate 资料hibernate 资料hibernate 资料

    hibernate关联映射详解

    hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,包含4个说明文档,分别详细解说了hibernate...

    java persistence with hibernate

    Java Persistence with Hibernate is the new bible of Hibernate. As a major revision of the popular Hibernate in Action, it builds on the same single example application to introduce and explain the ...

    hibernate关系映射网址

    hibernate

    Hibernate稳定版(hibernate-release-5.3.23.Final.zip)

    Hibernate稳定版(hibernate-release-5.3.23.Final.zip),Hibernate ORM 是一个为应用程序、库和框架提供对象/关系映射 (ORM) 支持的库。它还提供了 JPA 规范的实现,这是 ORM 的标准 Java 规范。

    hibernate4.3完整jar包

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端...

    Hibernate Hibernate5 讲义 PDF

    hibernate5 hibernate PDF 讲义 动力 hibernate ssh hibernate5 节点

    hibernate annotation hibernate3

    hibernate annotation hibernate3

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    深入浅出Hibernate(PDF)第一部分

    本书内容深入浅出,先讲述持久层设计与ORM,再由Hibernate概述、Hibernate基础Hibernate高级特性顺序展开,直至Hibernate实战,重点讲述了Hibernate的基础语法、基础配置、O/R映射、数据关联、数据检索、HQL实用技术...

    Hibernate对象的生命周期

    Hibernate对象的生命周期 Hibernate对象的生命周期 Hibernate对象的生命周期

    hibernate3 hibernate3

    hibernate3hibernate3hibernate3hibernate3hibernate3hibernate3hibernate3hibernate3

    hibernate3.zip 包含hibernate3.jar

    hibernate 用的较频繁的jar包,或者文档

Global site tag (gtag.js) - Google Analytics