`
Sunflower-13
  • 浏览: 73985 次
  • 性别: Icon_minigender_2
  • 来自: 长沙
社区版块
存档分类
最新评论

爱上框架之Hibernate框架

阅读更多
爱上框架之hibernate框架

一、使用hibernate开发的步骤:
1.创建工程
2.导入jar包
3.创建hibernate核心配置文件 hibernate.cfg.xml
路径:hibernate-release-5.2.10.Final\project\etc,放在src中。

二、hibernate对象的三种状态:
1.瞬时对象 当对象被new出来时候,此对象为瞬时对象。超过作用域会被JVM垃圾回收器回收。
数据库中没有此对象对应的记录。
2.持久对象:数据库中存在数据与对象一一对应,但是此对象必须是与session相关联的
并且此session没有关闭。
3.脱管状态,数据库中存在此对象,但是此时session已经关闭了,但是此对象还存在。
此对象发生改变,hibernate检测不到。

三、hibernate的get和load方法的区别:
1.对于get方法,hibernate会确认一下该id对应的数据是否存在,
首先在session缓存中查找,然后在二级缓存中查找,
还没有就查询数据库,数据库中没有就返回null。这个相对比较简单,也没有太大的争议。
主要要说明的一点就是在这个版本中get方法也会查找二级缓存!
2.load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true),
分情况讨论:
(1)若为true,则首先在Session缓存中查找,看看该id对应的对象是否存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子类,由CGLIB动态生成)。等到具体使用该对象(除获取OID以外)的时候,再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
(2)若为false,就跟get方法查找顺序一样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。

四、save()方法和persist()方法的区别:
1.save()方法不提交事务,都会插入数据到数据库,但是没有提交,数据会进行回滚。
2.persist()如果不添加事务,则根本不会提交数据到数据库中。

五、hibernate查询
1.Get/load主键查询
Dept dept =  (Dept) session.get(Dept.class, 10);
Dept dept =  (Dept) session.load(Dept.class, 10); (支持懒加载)


2.对象导航查询
Dept dept =  (Dept) session.get(Dept.class, 10);
	System.out.println(dept.getDname());
	System.out.println(dept.getEmps());


3.HQL查询,  Hibernate Query language  hibernate 提供的面向对象的查询语言。
注意点:此时的sql中的表必须要替换成为类,而表的列名必须要对应类的属性名。
注意:使用hql查询的时候 auto-import="true" 要设置true,如果是false,写hql的时候,要指定类的全名
        Query q = session.createQuery("from Dept");
     	System.out.println(q.list());


4.Criteria 查询,   完全面向对象的查询(Query By Criteria  ,QBC)
        Criteria criteria = session.createCriteria(Emp.class);
	criteria.add(Restrictions.eq("empNo", 12));


5.SQLQuery, 本地SQL查询
缺.点:不能跨数据库平台: 如果该了数据库,sql语句有肯能要改
使用场景: 对于复杂sql,hql实现不了的情况,可以使用本地sql查询。
SQLQuery q = session.createSQLQuery("select * from Dept where deptno = 20 ")	 	System.out.println(q.list());


例:分页查询:先查询总记录数,再分页查询。
@Test
	public void all() {
		Session session = HibernateSessionFactory.getSession();
		Transaction tr = session.beginTransaction();
		 Query q = session.createQuery("from Emp");
		
		 ScrollableResults scroll = q.scroll();  // 得到滚动的结果集
		 scroll.last();							//  滚动到最后一行
		 int totalCount = scroll.getRowNumber() + 1;// 得到滚到的记录数,即总记录数 
		 // 设置分页参数
		 q.setFirstResult(0);
		 q.setMaxResults(5);
		 System.out.println(q.list()); // 查询
		 System.out.println("总记录数:" + totalCount);
		 tr.commit();
		 HibernateSessionFactory.closeSession();
	}


六、hibernate C3P0连接池的配置:
为什么不使用hibernate自带的连接池,而去使用C3P0连接池?
C3P0是一款流行的开源的数据库连接池,使用此连接池,可以提高对数据库的访问和使用的效率。
C3P0的配置,配置在hibernate.cfg.xml文件中
<!-- hibernate连接池的供应类 -->
<property name="connection.provider_class">
	org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider
</property>
<!-- hibernate连接池的最小个数 -->
<property name="c3p0.min_size">3</property>
<!-- hibernate连接池中的最大个数 -->
<property name="c3p0.max_size">20</property>
<!-- 连接池中执行sql语句的最大个数,同时执行50条sql语句 -->
<property name="c3p0.max_statements">50</property>
<!-- 连接超时数,单位为毫秒 -->
<property name="c3p0.timeout">1800</property>
<!-- 连接自动增长的个数 -->
<property name="c3p0.acquire_increment">2</property>




七、hibernate的主键生成策略:
1.assigned:
特点:可以跨数据库,人为控制主键生成,。Hibernate不负责维护主键生成。
与Hibernate和底层数据库都无关,应尽量避免。
语法:
<id name="id" column="id">
<generator class="assigned" />
</id>

2.increment:
由Hibernate从数据库中取出主键的最大值(每个session只取1次),
以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库。
<id name="id" column="id">
<generator class="increment" />
</id>
Hibernate调用org.hibernate.id.IncrementGenerator类里面的generate()方法,
使用select max(idColumnName) from tableName语句获取主键最大值。
特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

3.hilo:
特点:跨数据库,hilo算法生成的标志只能在一个数据库中保证唯一。

4.seqhilo
与hilo类似,通过hi/lo算法实现的主键生成机制,
只是将hilo中的数据表换成了序列sequence,
需要数据库中先创建sequence,适用于支持sequence的数据库,如Oracle。
<id name="id" column="id">
<generator class="seqhilo">
<param name="sequence">hibernate_seq</param>
<param name="max_lo">100</param>
</generator>
</id>

5.sequence
采用数据库提供的sequence机制生成主键,需要数据库支持sequence。
如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence。
MySQL这种不支持sequence的数据库则不行(可以使用identity)。
<generator class="sequence">
<param name="sequence">hibernate_id</param>
</generator>
hibernate_id 指定sequence的名称
特点:只能在支持序列的数据库中使用,如Oracle。

八、hibernate的关联关系
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!
配置一对多与多对一,这种叫“双向关联”
只配置一对多,           叫“单项一对多”
只配置多对一,           叫“单项多对一”
注意:配置了哪一方,哪一方才有维护关联关系的权限!

1、Inverse属性
是在维护关联关系的时候起作用的。
    表示控制权是否转移。(在一的一方起作用)
Inverse , 控制反转。
Inverse = false  不反转;   当前方有控制权
True  控制反转; 当前方没有控制权

2、cascade  表示级联操作  【可以设置到一的一方或多的一方】
none          不级联操作, 默认值
save-update     级联保存或更新
delete   级联删除
save-update,delete    级联保存、更新、删除
all                 同上。级联保存、更新、删除

九、hibernate延迟加载
hibernate为了提高程序的效率,优化访问数据的数据,默认加载数据的时候设置了延迟加载。
延迟加载一般使用在one对多或者多对多的关系上面。
但是有时候延迟加载当我们关闭Session的时候会抛出异常,所以解决延迟加载有如下方法:
1.查询的方法当中即时打印数据。
2.使用hibernate.initlize(代理对象);初始化代理对象
3.在*.hbm.xml中配置延迟加载的数据 lasy=false false代表取消延迟加载。

十、Hibernate的缓存
1、Hibernate的一级缓存(Session级别的缓存)
缓存容器Map:save(),get(),load()
第一个用户:Object ->Map容器中 key,value (class,id)
第二个用户:先去容器中去取(如果容器中存在,则直接提取,如果不存在,查询数据库,查询到数据存在容器中)
Session:clear();close();s.evict(Object);清除单个对象
缺点:声明周期短,数据存储在内容中,如果数据量过大,很容易导致内存溢出

2、二级缓存:SessionFactory:
1).在项目的src文件下面创建ehcache.xml
2).修改hibernate.cfg.xml,
在此配置文件中加上二级缓存的相关配置
               <!-- 二级缓存供应工厂 -->
		<property name="cache.region.factory_class">
			org.hibernate.cache.ehcache.EhCacheRegionFactory
		</property>
		<!-- 是否使用二级缓存,默认为true:使用。可设置为false不启用 -->
		<property name="cache.use_second_level_cache">true</property>
		<!-- 查询时应用缓存 -->
		<property name="cache.use_query_cache">true</property>


3).配置需要查询的对象的映射文件*.hbm.xml
<!-- 缓存的策略
    1.read-only 只读
    2.read-write 允许读取或者更新数据 推荐使用
    3.nonstrict-read-write 脏读,不严格的读写
    4.transactional 支持事务,如果读取或者更新数据时报错,可以回滚。
    -->
   <cache usage="read-only"/>
用户查询数据的顺序:效率从高到低。
session(以及缓存)->cache(二级缓存)->db(数据库中去取)

二级缓存使用的注意事项:
1.一般适用于查询的数据,数据量处于中等。(10W下)
2.如果使用多个dao层的框架,hibernate在某些情况下不能检测到数据的一些更新状态时,则不推荐使用二级缓存
3.如果长期进行一些增删改的操作,也不推荐使用二级缓存。

MVC各层所对应框架
M - 模型层
dao -> hibernate,mybits,dbutils 基于orm的框架,推荐只使用一种
service -> spring ,springmvc
pojo
controll -> struts2,springmvc
view -> jsp

hibernate使用在dao层:
/**
 * 封装对数据库中的表的操作 (新增 / 修改 / 删除 / 根据id查询)
 * 
 */
public class HibernateDao<T> {
  public T find(Class<T> classz, Serializable id) {
    Session session = HibernateSessionFactory.getSession();
    T t = session.get(classz, id);
    HibernateSessionFactory.closeSession();
    return t;
  }

  public void add(T t) {
    Session session = HibernateSessionFactory.getSession();
    Transaction tx = session.beginTransaction();
    session.save(t);
    tx.commit();
    HibernateSessionFactory.closeSession();
  }

  public void modify(T t) {
    Session session = HibernateSessionFactory.getSession();
    Transaction tx = session.beginTransaction();
    session.update(t);
    tx.commit();
    HibernateSessionFactory.closeSession();
  }

  public void remove(T t) {
    Session session = HibernateSessionFactory.getSession();
    Transaction tx = session.beginTransaction();
    session.delete(t);
    tx.commit();
    HibernateSessionFactory.closeSession();
  }
}



查询所有的方法:(对emp表进行查询,可实现根据雇员名称和薪水进行模糊查询)
public class EmpDao extends HibernateDao<Emp> {
   /**
   * 多条件查询
   * @param ename
   * @param sal
   * @return
   */
  @SuppressWarnings("unchecked")
  public List<Emp> find(String ename, Double sal) {
Session session = HibernateSessionFactory.getSession();
Transaction tr = session.beginTransaction();

    String hql = "from Emp where 1=1 ";
    if (ename != null && ename.trim().length() > 0) {
      hql += " and ename like :ename ";
    }
    if (sal != null && sal > 0D) {
      hql += " and sal > :sal ";
}

Query query = session.createQuery(hql);

    if (ename != null && ename.trim().length() > 0) {
      query.setString("ename", "%" + ename.toUpperCase() + "%");
    }
    if (sal != null && sal > 0D) {
      query.setDouble("sal", sal);
}

ScrollableResults scroll = query.scroll();//得到滚动结果集
scroll.last();						//滚动到最后一条记录
int totalCont = scroll.getRowNumber()+1;	//得到总记录数
query.setFirstResult(0);					// 设置分页参数
query.setMaxResults(10);

List<Emp> emps = query.list();

//强制加载关联的数据、得到dept表中的数据
for(Emp emp:emps){
	Hibernate.initialize(emp.getDept());
}

tr.commit();
    HibernateSessionFactory.closeSession();
    return emps;
  }
}



四种查询结果的hql语句分解:
1.hql:from Emp where 1=1//查询所有雇员信息
2. hql:from Emp where 1=1 and ename like :ename//根据雇员名称模糊查询雇员信息
3.hql:from Emp where 1=1 and sal > :sal//根据雇员薪水模糊查询雇员信息
4.hql:from Emp where 1=1 and ename like :ename and sal > :sal//根据雇员名称和薪水模糊查询雇员信息

查询结果如下图所示:
[img]

[/img]
  • 大小: 49.3 KB
0
1
分享到:
评论

相关推荐

    springmvc_cxf_hibernate.zip

    在IT行业中,Spring、CXF和Hibernate是三个非常重要的开源框架,它们分别在不同的领域有着广泛的应用。Spring作为全面的企业级应用开发框架,CXF用于构建和整合Web服务,而Hibernate则是Java领域中最流行的持久层...

    hibernateTools

    Hibernate Tools 是一个强大的开发工具,它是Hibernate框架的扩展,为开发者提供了一系列便利的功能,主要用于简化Hibernate的使用,尤其是在对象关系映射(ORM)的工作中。这个压缩包包含了两个主要部分:`features...

    ssh整合jar包

    Hibernate框架: Hibernate是一个强大的ORM框架,它简化了Java应用与数据库之间的交互。在SSH整合中,Hibernate作为数据访问层,处理对象的持久化工作,将Java对象转换为数据库中的记录,并反之。Hibernate支持HQL...

    ssh用到的jar包

    Hibernate是一个优秀的对象关系映射(ORM)框架,解决了Java应用与数据库交互的难题。关键点如下: - **Entity**:表示数据库表的Java类,通过注解或XML配置与表建立映射。 - **Session**:持久化操作的主要接口...

    spring+cxf 实例项目

    同时,项目还集成了Hibernate,这是一个强大的ORM(对象关系映射)框架,它简化了数据库操作,将Java对象和数据库表之间的映射关系自动化。Hibernate支持JPA规范,可以方便地进行CRUD(创建、读取、更新、删除)操作...

    java商城系统.zip

    在这个系统中,开发者选择了经典的SSH(Struts2、Spring2.5、Hibernate3.2)框架进行开发,结合JSP、jQuery1.3和MySQL5.0数据库,构建了一个高效、稳定且功能丰富的电子商务平台。下面,我们将深入探讨这些技术在...

    dwz_springmvc

    对于刚开始接触DWZ和SSH(Struts2、Hibernate、Spring)集成的开发者来说,这是一个很好的学习起点。SSH中的Struts2已被Spring MVC逐渐取代,因为后者提供了更灵活的MVC实现。 在DWZ框架中,你可以找到诸如表单验证...

    Spring-study.rar

    此外,Spring还提供了数据访问集成,包括JDBC抽象层、ORM(Object-Relational Mapping)支持,如Hibernate和MyBatis,以及对JPA(Java Persistence API)的全面支持。这些功能让开发者可以方便地操作数据库,处理...

    在线教师测评系统开题报告

    研究目标集中在如何优化教学互动,采用SSH(Struts+Spring+Hibernate)框架进行Web开发,熟悉基于Struts或Spring的MVC模式,以及Servlet+JSP+JavaBean的快速开发模式。同时,研究还涉及JSP标签库、EL表达式以及软件...

    在线汽车租赁系统

    2. **持久化框架**:Hibernate或MyBatis用于简化数据库操作,提高开发效率。 3. **前端技术**:HTML、CSS和JavaScript构建用户界面,可能结合Bootstrap或Vue.js等库增强用户体验。 4. **安全控制**:Spring ...

    基于SpringBoot,更简洁的后台管理系统 Guns

    所用框架 前端 1. Bootstrap v3.3.6 2. jQuery v2.1.4 3. bootstrap-table v1.9.0 4. layer v2.1 5. zTree core v3.5.28 6. WebUploader 0.1.5 后端 1. SpringBoot 1.5.3.RELEASE 2. MyBatis-Plus 2.0.8 3. MyBatis...

    Spring4JAR包、Spring4API,Spring4源码

    对JDBC、Hibernate、JPA等持久化技术的集成更加紧密,提供了更多的便捷工具和API。例如,`JdbcTemplate`和`SimpleJdbcInsert`等类的增强,使得数据库操作更为简便,同时减少了潜在的资源泄漏。 此外,Spring4对AOP...

    java网上书城

    - **持久层框架**:MyBatis或Hibernate用于数据库操作,减少手动SQL编写,提高代码可维护性。 2. **系统架构** - **MVC模式**:模型-视图-控制器架构,确保业务逻辑、数据处理和用户界面分离。 - **RESTful API...

    Hibenate cascade

    Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式来操作数据库。在Hibernate中,`cascade`和`inverse`是两个重要的概念,它们涉及到对象之间的关系管理和数据持久化。 **1. ...

    1000道 互联网Java架构师面试题.pdf和JAVA核心知识整理.zip

    9、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗? 10、Mybatis 是如何进行分页的?分页插件的原理是什么? 11、...

    阿里巴巴开发手册-Java-华山版

    12. **数据访问**:对于数据库操作,推荐使用ORM框架如MyBatis或Hibernate,并遵循最佳实践,如合理设计SQL,避免N+1问题。 13. **安全性**:提醒开发者注意代码的安全性,如防止SQL注入、XSS攻击,处理敏感数据的...

Global site tag (gtag.js) - Google Analytics