JAVA EE 学习笔记(四)–SSH WEB程序员的必修课之hibernate

碎语:

很久没上博客,突然发现博客多了不少评论,想起建站时候听到的一句话,只要你建博客,肯定会有垃圾评论,无论你的水平如何,应验了。

想起建博的初衷,记录下成长的点点滴滴,回首过去,展望未来,激励自己去不停进步,总有一天我会从一个菜鸟渐渐变成一个高手,而我这走过的路,也可以帮助到一些在学习路上的朋友。

学习整理:

SSH三大框架可以说是一个合格的WEB程序员的必修课,Struts,hibernate,spring各施其职,可以说是解放了程序员。我们为什么用框架,我个人目前的理解是:1,它让开发更加便捷。2,它让程序更有效率。

Hibernate部分:

在这三个框架中,hibernate可以说是最复杂的,学习过后小总结一下。

hibernate的作用主要是提供一个ORM映射,让从数据库取出数据变得更加方便,省略了一次次无聊的get。

hibernate主要适用于oa系统,行业软件(crm,财务管理),不适合联机数据查询分析为主的系统,对性能要求高的,也不适用。

大致使用:

在hibernate.cfg.xml中配置数据库的信息,配置对应对象的*.hbm.xml文件,建立关系映射。

sessiongFactory->session->开启事务->获取query->进行操作->提交事务->关闭资源

可以使用Myeclipse给我们生成的一个HibernateSessionFactory.java来进行操作,建议去看下其具体实现,很有好处。

HQL:这个是重点了,基本上都是在和hql文打交道。

hql也支持sql中常见的distinct, between,in / not in, group by ,having 等语句,写的时候注意要基于对象来写。

使用hql来实现分页可以说是非常简单,只要设定每页数量 setMaxResult,和起始位置setFirstResult就可以了。

给一个分页的示例

/**
	 * queryVo 中除了带有查询字段外,还有 分页大小,当前页,总记录数,总页数等信息
	 * @param queryVo
	 * @return
	 */
public List<ActiveVo> findActiveVoListByQry(ActiveQryVo queryVo){
		Session session = null;
		List<ActiveVo> result = null;
		/**
		 * 查询条件
		 */
		List<Object> conditions = new ArrayList<Object>();
		/**
		 * 查询语句 / 查询总记录数 /拼接条件
		 */
		StringBuilder hql = new StringBuilder();
		StringBuilder rowsHql = new StringBuilder();
		StringBuilder sb = new StringBuilder();
		hql.append("select new com.cares.vo.ActiveVo(id,activeName,startDate,endDate,sponsors,state,creater,createTime) from TblActive where 1=1");
		rowsHql.append("select count(*) from TblActive where 1=1");
		// 拼接hql
		if (!StringUtil.isEmpty(queryVo.getActiveName())) {
			sb.append(" and activeName like ?");
			conditions.add("%"+queryVo.getActiveName()+"%");
		}
		if (queryVo.getStartDate()!=null) {
			sb.append(" and startDate >= ?");
			conditions.add(queryVo.getStartDate());
		}
		if (queryVo.getEndDate()!=null) {
			sb.append(" and endDate <= ?");
			conditions.add(queryVo.getEndDate());
		}
		if (!"-1".equals(queryVo.getState())){
			sb.append(" and state = ?");
			conditions.add(queryVo.getState());
		}
		/**
		 * 拼接
		 */
		hql.append(sb);
		rowsHql.append(sb);
		try {
			session = HibernateSessionFactory.getSession();
			Query query = session.createQuery(hql.toString());
			Query queryRow = session.createQuery(rowsHql.toString());

			for (int i = 0; i < conditions.size(); i++) {
					Object obj = conditions.get(i);
					query.setParameter(i, obj);
					queryRow.setParameter(i,obj);
			}
			// 设定总记录数
			int n = ((Long)queryRow.iterate().next()).intValue();;
			queryVo.setAllSize(n);

			// 设定分页
			query.setFirstResult((queryVo.getCurPage()-1)*queryVo.getPageSize());
			query.setMaxResults(queryVo.getPageSize());
			result = query.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.closeSession();
		}
		return result;
	}
关系映射:主要有三种
many to one  会生成 外键的一个对象(可以配置many to one 特例,一对一)
one to many  会生成 对象的集合
one to one  一对一

缓存:

使用query接口查询数据,是不会从缓存中获取数据的,但是其获取的数据会放到缓存中供get/load来使用。

hibernate有二级缓存,不会默认开启,要手动配置缓存,有挺多缓存框架可以用,以下是OScache的示例,其它配置大同小异。

<property name="cache.use_second_level_cache" >true</ property>
<property name="cache.provider_class" >org.hibernate.cache.OSCacheProvider</ property>
<property name="hibernate.generate_statistics" >true</ property>
<class-cache usage="read-only" class ="com.cares.pojo.TblInterest" />
解决懒加载问题
建议many-to-one可以配置下
解决方法:
1.扩展session作用域(sessionInView)
2.配置xml 中对应的对象lazy 为 false
3.显示初始化对象集合hibernate.initialize()
4.ssh整合的时候 可以注解方式 (这个没使用过)
主键生成策略,手册第五章
①increament:用于long,short,int类型生成唯一标识。// 单进程状态可以使用
<id name=”id” type=”java.lang.String”>
<generator />
<id>
②identity:需要数据库支持,mysql ,sqlserver。
③sequence:db2,oracle可以使用。
④native:根据底层数据库,选择identity,sequence,hilo中的一种。
⑤hilo:高地位算法
<id name=”id” type=”java.lang.Integer” column=”ID”>
<generator>
<param name=”table”>my_hi_value</param>
<param name=”column”>next_value</param>
</generator>
</id>
⑥uuid
128位2
⑦assigned
用户自己设定的主键
(8)复合主键
(9)foreign
sequence / identify / uuid / hilo
使用原则
Oracle 主键是 int/long/short  使用sequence
          主键是字符串,uuid/assigned
Mysql  int/long/short   使用increament
          字符串,uuid/assigned