`
demojava
  • 浏览: 551532 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate初探(-)

    博客分类:
  • JAVA
阅读更多

  在hibernate的配置文件中出现了
  <property name="password" type="java.lang.String">
            <column name="password" length="45" not-null="true" />
 </property>
 表明当前的属性不允许为空,Hibernate在持久化给对象时,会检查password属性是否为NULL 如果为NULL 那么就会抛出下面的异常:
 org.hibernate.PropertyValueException:not-null property refrences a null or transient value:包名.类名.属性名
 如果数据库中的映射的字段时不允许为空,但配置文件中没有设置not-null 属性时:<column name="password" length="45" />
 因此数据库会抛出错误:ERROR JDBCExceptionReporter:58 -General error,message from server:"Column 'password' cannot be null"

Hibernate配置文件-添加静态方法
<property name="username" type="java.lang.String">
          <meta attribute="find-method">findByName</meta>
            <column name="username" length="45" not-null="true" />
</property>
其中<meta>标签的find-method 选项用于设置find 的方法名,以上代码表明在某一个类中定义一个静态的方法叫:findByName(Session session,String username),该方法按照username属性到数据库中检索匹配的对象

Hibernate设置包名
<class>元素的name属性时必须提供完整的类名即,类所在的包的名字,如果在一个配置文件包含多个类,并且这些类都位于一个包中,每次都设定类的名字很烦,此时一下两中映射方式是等价的:
<hibernate-mapping package="com.entity">
 <class name="User" table="UserInfo" catalog="demo">.....
 <class name="Role" table="RolrInfo" catalog="demo">.....
</hibernate-mapping>
<hibernate-mapping>
    <class name="org.entry.User" table="UserInfo" catalog="demo">
    <class name="org.entry.Role" table="RolrInfo" catalog="demo">
 </hibernate-mapping>

HIbernate的Ssession的commit()和flush()方法的区别:flush()方法进行清理缓存的操作,执行一系列的sql语句,打不会提交事物,commit()方法会先调用flush()方法,然后提交事物,提交事物意味着对数据库的所有操作将被永久保存下来

Betch procession批量处理
使用Hibernate将100000条记录插入到数据库中是一个很自然的做法可能是这样的:
Session session=sessionFactory.openSession();
Transaction tx= session.beginTransaction();
for (int i = 0; i < 100000; i++) {
 User user=new User(.....);
 session.save(user);
}
tx.commit();
session.close();
这个程序大概运行到50000行会出现内存溢出异常,这是因为Hibernate把所有的新插入的记录保存在session级别的缓存区进行缓存的原因
一般在使用时我们配置的jdbc批量抓取数量(bath size)是10-50之间
hibernate.jdbc.batch_size 20当然在执行批处理时关闭二级缓存:
hibernate.cache.use_second_level_cache false
批量插入(Batch inserts):
Session session=sessionFactory.openSession();
Transaction tx= session.beginTransaction();
for (int i = 0; i < 100000; i++) {
 User user=new User(.....);
 session.save(user);
 if(i%20==0)
 {
 session.flush();
 session.clear();
 }
}
tx.commit();
session.close();
批量更新(Batch updates):
Session session=sessionFactory.openSession();
Transaction tx= session.beginTransaction();
String hql="select distinct s.billNumber,s.billDate,s.billState,s.department from StockRequisition as s";
命名查询
<hibernate-mapping>
  <sql-query name="queryStaffBySex">
    <![CDATA[update userInfo set sex=:sex where sex is null ]]>
    <return alias="s" class="com.form.Staff"/>
  </sql-query>
</hibernate-mapping>

ScrollableResults resluts=session.getNamedQuery("queryStaffBySex").setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
  int count=0;
 while (resluts.next()) {
   User user=(User)resluts.get(0);
 user.setSex("男");
 if(++count%20==0)
 {
 session.flush();
 session.clear();    
 }
}

1 将整个继承关系放在一张表中,为了区分具体的子类信息,表中需要创建一个额外的列
 create table paymeny(
  .....
  type varchar2(12)
 );
 <class name="Payment" table="payment">
  .....
  <discriminitor column="type" type="string">
  <sub-class name="CardPayment" discriminitor-value="card">
   子类属性
  </sub-class>
  <sub-class name="CashPayment" discriminitor-value="cash">
   子类属性
  </sub-class>
 </class>
 操作方便 效率较高 多态
 冗余 浪费空间
2 将父类信息和每个子类信息结合在一起,创建多张具体的表
 create table cardpayment(
  父类信息
  信用卡子类信息
 )
 create table cashpayment(
  父类信息
  现金子类信息
 )
 <class name="Payment">
  .....
 
  <union-sub-class name="CardPayment" table="cardpayment">
   子类属性
  </union-sub-class>
  <union-sub-class name="CashPayment" table="cashpayment">
   子类属性
  </union-sub-class>
 </class>
 操作方便 效率较高 空间利用率较高
 冗余 没有多态
3 针对每个具体的对象,创建其对应得表
 create table payment(
  父类信息
 )
 create table cardpayment(
  信用卡子类信息
  外键cardid
 )
 create table cashpayment(
  现金子类信息
  外键cashid
 )
 <class name="Payment" table="payment">
  .....
 
  <joined-sub-class name="CardPayment" table="cardpayment">
   <key column="cardid"></key>
   子类属性
  </joined-sub-class>
  <joined-sub-class name="CashPayment" table="cashpayment">
   <key column="cashid"></key>
   子类属性
  </joined-sub-class>
 </class>
 多态 没有冗余 空间利用率较高
 操作复杂 效率较低


hibernate查询:
 1 native sql
  程序员精通sql
  自己控制sql的效率
  查询到的信息只能自己封装
 2 hql Student1 ----1 Address
  在sql框架基础之上,面向对象
  from Student;
  select s.name from Student s;
  from Student s where s.age > 20;
  from Student s inner join address a where a.name=...;
 3 criteria
  标准面向对象式查询
  session.createCriteria(Student.class);
  session.createCriteria(Student.class)
   .add(Restrictions.gt("age",20));
  session.createCriteria(Student.class)
   .createCriteria("address")
   .add(Restrictions.eq("name","..."));
 4 named query
  将sql语句彻底从源代码中提取到映射文件中
  *.hbm.xml
  <hibernate-mapping>
   <class>
    .....
   </class>
   <query name="sql变量名">
    <![CDATA[
     hql语句... ?/:name
    ]]>
   </query>
  </hibernate-mapping>

  session.getNamedQuery("sql变量名")


hibernate对数据源的支持:
 1 hiebrnate内置数据源,仅用于测试
 <property name="connection.username">scott</property>
 <property name="connection.url">
  jdbc:oracle:thin:@localhost:1521:sinojava
 </property>
 <property name="dialect">
  org.hibernate.dialect.Oracle9Dialect
 </property>
 <property name="connection.password">tiger</property>
 <property name="connection.driver_class">
  oracle.jdbc.driver.OracleDriver
 </property>

 2******* hibernate整合c3p0*******
 <property name="connection.username">scott</property>
 <property name="connection.url">
  jdbc:oracle:thin:@localhost:1521:sinojava
 </property>
 <property name="dialect">
  org.hibernate.dialect.Oracle9Dialect
 </property>
 <property name="connection.password">tiger</property>
 <property name="connection.driver_class">
  oracle.jdbc.driver.OracleDriver
 </property>

 添加以下信息:
 <property name="connection.provider_class">
  org.hibernate.connection.C3P0ConnectionProvider
 </property>
 <property name="c3p0.max_size">5</property>
 <property name="c3p0.timeout">2000</property>
 ..........

 3 jndi
 <property name="connection.username">scott</property>
 <property name="connection.url">
  jdbc:oracle:thin:@localhost:1521:sinojava
 </property>
 <property name="dialect">
  org.hibernate.dialect.Oracle9Dialect
 </property>
 <property name="connection.password">tiger</property>
 <property name="connection.driver_class">
  oracle.jdbc.driver.OracleDriver
 </property>

 添加以下信息:
 <property name="jndi">java:comp/env/userDs</property>

 程序中必须手动获取连接,传递给hibernate:
  getSession(){
   Context env = new IntialContext();
   DataSource ds = (DataSource)env.lookup("java:comp/env/userDs");
   Conenction con = ds.getConnection();
   ...
   sessionFactory.openSession(conn);
   ....
  }

hibernate对于分页的支持:
 query.setFirstResult(起始位置);
 query.setMaxResults(查询条数);
 query.list();

锁:
 读锁/写锁
 表级锁/列级锁

JDBC中的并发控制:
 1 数据库
  隔离级别
  TRANSACTION_NONE  0
  TRANSACTION_UNCOMMITED_READ 1
  TRANSACTION_COMMIED_READ 2
  TRANSACTION_REPEATABLE_READ 4
  TRANSANTION_SERIALIZABLE 8
  Connection.setTransactionIsolation(...)

  select **** 【for update】;
 2 应用程序
  synchronized
******hibernate对多线程并发的控制:
 1 数据库
  隔离级别
  TRANSACTION_NONE  0
  TRANSACTION_UNCOMMITED_READ 1
  TRANSACTION_COMMIED_READ 2
  TRANSACTION_REPEATABLE_READ 4
  TRANSANTION_SERIALIZABLE 8

  hibernate.cfg.xml
   <property name="connection.isolation">2</property>

 
  select **** 【for update】;
 2 应用程序
  悲观锁:
   认为一定会有两个线程同时访问一个数据
   必须针对操作进行加锁:
    Query q = session.createQuery("from Student s")
    q.setLockMode("s",LokeMode.WRITE);
    LockMode:
     NONE 不加锁
     READ 读锁
     WRITE 写锁
     UPDATE 表级锁 <===> select **** for update;
  乐观锁:
   认为一个线程访问的时候,不一定会并发
  
      线程1    线程2
    ------------------------------------------------------
    balance=1000
      1000    1000
      1000-600 commit  
     400     1000-200 commit
     800

    解决:采用一个标志位控制数据的有效性
   
    balance     identity 线程1    线程2
    -----------------------------------------------------------------
    1000    1
       1000 1   1000 1
       1000-600 1+1 commit
    400    if(2>1)提交 
           1000-200 1+1 commit
        if(2>2)不许提交

    标志位:
     时间戳:
     
     **版本号:
  
hibernate缓存机制:
 一级缓存:Session对象
  session.get(Class,Serializble)
  session.load(Class,Serializble)

  get/load共性:
   get和load发送的sql语句结构相同
   session--->SessionFactory--->DB
  get/load区别:
   get:
    1 只要调用get方法,则直接发送sql查询
    2 get直接查找信息,找不到则返回null
   
   load:
    1 调用了load方法,默认不发送sql语句
    直到真正使用该对象时,才发送sql查询
    load方法返回的对象:没用到信息,则返回代理对象
          使用到信息,则返回真正的对象      2 load方法查找不到信息,则报异常         org.hibernate.ObjectNotFoundException

 二级缓存:SessionFactory
  1 在hibernate.cfg.xml中添加属性
  --设置二级缓存类
  <property name="cache.provider_class">
   org.hibernate.cache.EhCacheProvider
  </property>二级
  --设置query操作使用缓存,否则是对get/load生效
  <property name="cache.use_query_cache">true</property>

  2 在hbm映射文件中设置使用二级缓存
  <class name="Concur" table="concur_time">
   <cache usage="read-only|read-write"/>
   ...
  </class>
 
  3 如果使用query语句查询,并且想使用二级缓存
   Query.setCacheable(true);
   Query.list....

hibernate对象状态及session的各个方法:
 transient 临时对象
 detached 游离对象
 persist  持久化对象

  Configuration cfg = new Configuration().configure();
  SessionFactory sf = cfg.buildSessionFactory();
  Session session = sf.openSession();
  Transaction tx = session.beginTransaction();  内存 session  DB
  Concur c = new Concur("hehe");     

 session.save(c);
  tx.commit();       

  session.close();      

 

hibernate中的N+1问题

在hibernate中,当进行一个表的查询时,当这个表与另外的表是多对一,
     或者是一对多关联时,就会出现N+1问题,当查询一条语句时,比如主键name=1,
     而与这个name相关联的另一张表对应name的有N个记录,这时就出另外发出N条语句去查询,而我又不要那些记录,这时就是N+1问题。
            解决方法:
            1.设置lazy=true;
            2.在本类DTO中有关联另外表的表对象的声明,在他的get方法上面加上一个@fetch=fetchtype.lazy;
            3.在关联的类上面设置@batchsize=2;这时就只发出两条语句。
            4.用SQL来查询,写SQL语句时就写成联合查询的形式。

  • 大小: 107.4 KB
分享到:
评论

相关推荐

    hibernate3.3.2jar包part1

    《Hibernate 3.3.2:Java对象持久化框架初探》 Hibernate,作为一个流行的开源对象关系映射(ORM)框架,为Java开发者提供了一种简单而强大的方式来管理数据库操作。在Java应用中,Hibernate使得开发人员可以将业务...

    Hibernate介绍

    3. **Hibernate初探** 初始化Hibernate配置,创建SessionFactory,然后通过Session对象进行数据库操作。Hibernate支持XML配置和注解配置两种方式来定义对象与数据库表的映射关系。 4. **Hibernate的基本映射** ...

    hibernate first

    《Hibernate初探:深入理解Hibernate第一映射》 Hibernate,作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作,将Java对象与数据库表之间的映射关系自动化处理。"Hibernate first"通常指...

    struts2 初探

    同时,Struts2可以与其他开源库如Hibernate、Spring等无缝集成,进一步提升开发效率。 Struts2的插件机制也是其特色之一。通过插件,开发者可以轻松地扩展Struts2的功能,比如Tiles插件用于布局管理,Freemarker或...

    hibernate3.2开篇

    《Hibernate3.2初探:源码与工具的深度融合》 Hibernate,作为一款强大的Java对象关系映射(ORM)框架,极大地简化了数据库操作。在3.2版本中,它进一步提升了性能,优化了API,并引入了更多实用功能。本文将深入...

    hibernate+spring_struts开发的学生信息管理系统(初级版)

    《基于Hibernate+Spring+Struts的学生信息管理系统初探》 在Java开发领域,Spring、Hibernate和Struts是经典的“SSH”框架组合,常用于构建企业级应用,如本例中的学生信息管理系统。这个初级版系统展示了如何将这...

    pring初探共18页.pdf.zip

    很抱歉,根据您提供的信息,"pring初探共18页.pdf.zip" 和 "pring初探共18页.pdf." 看起来像是一个关于Spring框架的教程文档,但是具体的文件列表只提到了 "赚钱项目",这与Spring框架的学习内容不直接相关。...

    eapp-corp-quick-start-java_后台_

    《小程序后台快速构建:eapp-corp-quick-start-java初探》 在当前数字化时代,小程序作为轻量级的应用形态,已经广泛应用于各个行业。为了快速构建高效、稳定的小程序后台,开发者通常会借助于一些预设的脚手架工具...

    SQL注入初探,实例

    5. **使用ORM(对象关系映射)**:如Hibernate或Entity Framework,它们可以自动处理SQL语句,降低注入风险。 6. **代码审计和更新**:定期检查代码中可能存在的SQL注入漏洞,并及时修复已知的安全问题。 7. **...

    Struts2讲义-作者:吴峻申

    - 它支持多种数据库访问技术和框架,如Hibernate、Spring等。 - Struts2提供了强大的插件体系,开发者可以根据项目需求轻松地添加新功能。 - Struts2拥有活跃的社区支持,大量的文档和教程可供参考。 - **Web项目...

    学生选课系统

    《SSH框架下的学生选课系统初探》 SSH(Struts2、Spring、Hibernate)是Java Web开发中常用的三大框架,它们的组合为构建高效、灵活的企业级应用提供了可能。本篇文章将围绕“学生选课系统”这一主题,探讨如何利用...

    java学习之spring2.0

    - **Spring 初探**:Spring的核心在于依赖注入(DI)和面向切面编程(AOP),提供了一个轻量级的容器来管理对象的生命周期和相互依赖关系。 - **Spring 体系**:包括Core Container(核心容器)、Data Access/...

    JEECG_v3开发指南v3.3

    - **技术栈**:JEECG V3.0版本采用了SpringMVC + Hibernate + UI快速开发库作为其基础架构,并采用了面向声明式的开发模式,利用泛型机制使得少量的代码就能实现复杂的业务逻辑处理。 - **架构特点**: - **高度...

    C# 通过反射初探ORM框架的实现原理(详解)

    在Java中,我们经常使用Mybatis、Hibernate等ORM框架来实现数据访问层。然而,在C#中,我们可以使用反射机制来实现简单的ORM框架。 什么是反射?反射是指程序可以访问、检测和修改它本身状态或行为的一种能力,并能...

    JSF资料以及深入开发

    **JSF初探.pdf** 可能是一份介绍性的资料,概述了JSF的主要特性和优势,帮助读者快速了解JSF并决定是否深入学习。 **JSF教程.pdf** 这可能是更为全面的JSF教程,涵盖了JSF的各个方面,包括但不限于组件体系结构、...

    Nhibernate从入门到精通

    - **数据查询和获取**:提供了丰富的查询方式,包括HQL(Hibernate Query Language)、LINQ to NHibernate等,方便开发者根据需求选择合适的查询方式。 - **事务管理**:NHibernate提供了一套完整的事务管理机制,...

    Spring3.x权威开发指南

    Spring支持与Hibernate的集成,这使得开发者可以利用Hibernate的强大功能来处理持久化层的逻辑。 **5.2 JPA集成支持** Java Persistence API (JPA) 是一种规范,Spring支持JPA的集成,使得开发者可以使用JPA来...

    javaeye热点阅读

    15. Apache Click框架初探:Click是一个轻量级的Web开发框架,它的易用性和简洁性使得快速构建应用变得可能。 16. Spring AOP详解:AOP(面向切面编程)是Spring的重要特性,用于实现如日志、权限检查等功能的横切...

Global site tag (gtag.js) - Google Analytics