`
goto0917
  • 浏览: 48006 次
  • 性别: 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 配置各种数据库

    Hibernate 配置各种数据库 Hibernate 是一个基于 Java 的持久层框架,提供了一个抽象的数据访问层,能够与多种数据库进行集成。在 Hibernate 的配置文件中,我们可以配置不同的数据库连接,包括驱动程序、URL 等...

    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-...

    Hibernate入门到精通

    "Hibernate入门到精通" Hibernate 是一个基于Java的ORM(Object-Relational Mapping,对象关系映射)框架,它提供了一种简洁高效的方式来访问和操作关系数据库。下面是 Hibernate 的主要知识点: Hibernate 简介 ...

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

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

    hibernate学习资料大全

    【hibernate学习资料大全】 Hibernate 是一个开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序对数据库的操作。这个压缩包包含了丰富的Hibernate学习资源,旨在帮助开发者深入理解和熟练掌握这一强大的...

    Hibernate-extensions 完整安装包

    《Hibernate-Extensions全面指南》 Hibernate,作为Java领域中的一款著名对象关系映射(ORM)框架,极大地简化了数据库操作。然而,为了满足更复杂的业务需求,Hibernate还提供了丰富的扩展功能,这就是我们今天要...

    hibernate-release-4.1.4

    【描述】中的"hibernate的jar包"指的是Hibernate框架的运行库文件,这些JAR文件包含了Hibernate的所有核心API、实现和依赖库,如Hibernate Commons Annotations、Hibernate EntityManager、Hibernate Core等。...

    hibernate基础jar包

    Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者使用面向对象的方式来操作数据库,极大地简化了数据访问层的编程工作。这个压缩包包含了Hibernate的基础jar包,这些jar文件是开发Hibernate应用所...

    HibernateTools-3.2.4

    HibernateTools是Java开发人员在使用Hibernate ORM框架时的有力辅助工具集,主要目的是为了提高开发效率,简化数据库操作。在HibernateTools 3.2.4版本中,它包含了一系列的特性与插件,以支持更便捷地进行对象关系...

    kingbaseV8 hibernate jdbc 驱动

    在Java开发环境中,与KingbaseV8数据库进行交互通常会用到Hibernate框架和JDBC驱动。 Hibernate是一个优秀的对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作,通过将Java对象与数据库表进行映射,...

    hibernate3全部jar包:hibernate3.jar.zip 下载

    Hibernate3 是一个强大的Java持久化框架,它允许开发者将数据库操作与业务逻辑解耦,使得应用程序的开发更为简便。这个“hibernate3全部jar包:hibernate3.jar.zip”包含了所有必要的库文件,方便用户一次性下载并...

    Hibernate3的依赖包

    Hibernate3是一个广泛使用的Java对象关系映射(ORM)框架,它允许开发者用面向对象的方式处理数据库操作,极大地简化了Java应用程序与数据库之间的交互。在这个"Hibernate3的依赖包"中,包含了运行Hibernate3应用...

    hibernate和MySQL的jar

    标题中的“hibernate和MySQL的jar”指的是Hibernate ORM框架与MySQL数据库之间的连接库。Hibernate是一种流行的Java对象关系映射(ORM)工具,它允许开发者使用面向对象的编程方式来操作数据库,而无需直接编写SQL...

    hibernate4.3完整jar包

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

    Hibernate 中文api 等学习资料

    标题"Hibernate 中文api 等学习资料"暗示了这是一组针对Hibernate ORM框架的中文学习资源,包括API文档和其他指南,旨在帮助用户更好地理解和使用Hibernate。 描述中的"hibernate orm框架api中文文档,学习资料,...

    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入门jar包

    Hibernate是一款强大的Java持久化框架,它简化了数据库与Java对象之间的交互,使开发者可以更加专注于业务逻辑而不是数据访问层的实现。本压缩包提供的是Hibernate入门所需的jar包,包括了Hibernate的核心库以及与之...

    hibernate3必要jar包

    Hibernate3 是一个非常重要的Java持久化框架,它允许开发者将对象模型与数据库关系模型进行映射,从而简化了数据存取的过程。这个压缩包“hibernate3必要jar包”显然是针对Hibernate3版本的,已经去除了冗余的库文件...

    hibernate_3.2官方开发包

    Hibernate 是一个著名的开源对象关系映射(ORM)框架,它为Java开发者提供了便捷的数据持久化方式,使得在Java应用程序中操作数据库变得更加简单。这个“hibernate_3.2官方开发包”包含了所有你需要开发基于...

    hibernate需要的10个jar

    在Java开发领域,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。当涉及到Hibernate项目时,为了使其正常运行,通常需要一系列的JAR(Java ...

Global site tag (gtag.js) - Google Analytics