爱上框架之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
分享到:
相关推荐
在IT行业中,Spring、CXF和Hibernate是三个非常重要的开源框架,它们分别在不同的领域有着广泛的应用。Spring作为全面的企业级应用开发框架,CXF用于构建和整合Web服务,而Hibernate则是Java领域中最流行的持久层...
Hibernate Tools 是一个强大的开发工具,它是Hibernate框架的扩展,为开发者提供了一系列便利的功能,主要用于简化Hibernate的使用,尤其是在对象关系映射(ORM)的工作中。这个压缩包包含了两个主要部分:`features...
Hibernate框架: Hibernate是一个强大的ORM框架,它简化了Java应用与数据库之间的交互。在SSH整合中,Hibernate作为数据访问层,处理对象的持久化工作,将Java对象转换为数据库中的记录,并反之。Hibernate支持HQL...
Hibernate是一个优秀的对象关系映射(ORM)框架,解决了Java应用与数据库交互的难题。关键点如下: - **Entity**:表示数据库表的Java类,通过注解或XML配置与表建立映射。 - **Session**:持久化操作的主要接口...
同时,项目还集成了Hibernate,这是一个强大的ORM(对象关系映射)框架,它简化了数据库操作,将Java对象和数据库表之间的映射关系自动化。Hibernate支持JPA规范,可以方便地进行CRUD(创建、读取、更新、删除)操作...
在这个系统中,开发者选择了经典的SSH(Struts2、Spring2.5、Hibernate3.2)框架进行开发,结合JSP、jQuery1.3和MySQL5.0数据库,构建了一个高效、稳定且功能丰富的电子商务平台。下面,我们将深入探讨这些技术在...
对于刚开始接触DWZ和SSH(Struts2、Hibernate、Spring)集成的开发者来说,这是一个很好的学习起点。SSH中的Struts2已被Spring MVC逐渐取代,因为后者提供了更灵活的MVC实现。 在DWZ框架中,你可以找到诸如表单验证...
此外,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 ...
所用框架 前端 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...
对JDBC、Hibernate、JPA等持久化技术的集成更加紧密,提供了更多的便捷工具和API。例如,`JdbcTemplate`和`SimpleJdbcInsert`等类的增强,使得数据库操作更为简便,同时减少了潜在的资源泄漏。 此外,Spring4对AOP...
- **持久层框架**:MyBatis或Hibernate用于数据库操作,减少手动SQL编写,提高代码可维护性。 2. **系统架构** - **MVC模式**:模型-视图-控制器架构,确保业务逻辑、数据处理和用户界面分离。 - **RESTful API...
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式来操作数据库。在Hibernate中,`cascade`和`inverse`是两个重要的概念,它们涉及到对象之间的关系管理和数据持久化。 **1. ...
9、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗? 10、Mybatis 是如何进行分页的?分页插件的原理是什么? 11、...
12. **数据访问**:对于数据库操作,推荐使用ORM框架如MyBatis或Hibernate,并遵循最佳实践,如合理设计SQL,避免N+1问题。 13. **安全性**:提醒开发者注意代码的安全性,如防止SQL注入、XSS攻击,处理敏感数据的...