Hibernate 优化技术之调用视图(View)和存储过程(Procedure)
前言
上一篇blog记录了hibernate抓取策略的相关用法(http://blog.csdn.net/wlwlwlwl015/article/details/42705585),它主要是在对象导航时为我们进行HQL方面的优化。本篇blog将介绍一些通用性的优化方式,即在hibernate中使用视图和存储过程。在数据量比较大时(百万级),使用hibernate时不再推荐使用HQL,而是使用原生的SQL语句,而视图、索引、存储过程等数据库对象也都是基于底层数据库和原生的SQL派生出的优化方案,废话不多说,下面就开始通过代码介绍一下如何在hibernate中调用view、proc以及需要注意的一些关键点。
通过hibernate查询视图
数据库视图(View)的概念和优点等等就不说了,这个书上和网上都讲了很多,下面直接通过例子来看一下如何在hibernate中查询视图,依旧是上一篇中的例子,一对多的典型示例:班级→学生,先看一下数据表:
下面写一个简单的视图,例如需要查询以下几个字段:stu_id、sname、sex、birthday、cname,首先根据需求创建视图,
DELIMITER $$ USE `wltestdb`$$ DROP VIEW IF EXISTS `v_stuinfo`$$ CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_stuinfo` AS ( SELECT `t1`.`stu_id` AS `stu_id`, `t1`.`name` AS `sname`, `t1`.`sex` AS `sex`, `t1`.`birthday` AS `birthday`, `t2`.`name` AS `cname` FROM (`t_student` `t1` JOIN `t_classroom` `t2` ON ((`t1`.`cid` = `t2`.`cla_id`))))$$ DELIMITER ;
通过查询语句select * from v_stuinfo即可查询视图,
OK,视图没问题,接下来就是如何映射和查询了,首先是通过hibernate建立view的mapping。
1.映射视图
package com.wl.entity; /** * VStuinfo entity. @author MyEclipse Persistence Tools */ public class VStuinfo implements java.io.Serializable { // Fields private VStuinfoId id; // Constructors /** default constructor */ public VStuinfo() { } /** full constructor */ public VStuinfo(VStuinfoId id) { this.id = id; } // Property accessors public VStuinfoId getId() { return this.id; } public void setId(VStuinfoId id) { this.id = id; } }
package com.wl.entity; import java.util.Date; /** * VStuinfoId entity. @author MyEclipse Persistence Tools */ public class VStuinfoId implements java.io.Serializable { // Fields private Integer stuId; private String sname; private String sex; private Date birthday; private String cname; // Constructors /** default constructor */ public VStuinfoId() { } /** minimal constructor */ public VStuinfoId(Integer stuId) { this.stuId = stuId; } /** full constructor */ public VStuinfoId(Integer stuId, String sname, String sex, Date birthday, String cname) { this.stuId = stuId; this.sname = sname; this.sex = sex; this.birthday = birthday; this.cname = cname; } // Property accessors public Integer getStuId() { return this.stuId; } public void setStuId(Integer stuId) { this.stuId = stuId; } public String getSname() { return this.sname; } public void setSname(String sname) { this.sname = sname; } public String getSex() { return this.sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return this.birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getCname() { return this.cname; } public void setCname(String cname) { this.cname = cname; } public boolean equals(Object other) { if ((this == other)) return true; if ((other == null)) return false; if (!(other instanceof VStuinfoId)) return false; VStuinfoId castOther = (VStuinfoId) other; return ((this.getStuId() == castOther.getStuId()) || (this.getStuId() != null && castOther.getStuId() != null && this.getStuId().equals( castOther.getStuId()))) && ((this.getSname() == castOther.getSname()) || (this .getSname() != null && castOther.getSname() != null && this .getSname().equals(castOther.getSname()))) && ((this.getSex() == castOther.getSex()) || (this.getSex() != null && castOther.getSex() != null && this.getSex().equals( castOther.getSex()))) && ((this.getBirthday() == castOther.getBirthday()) || (this .getBirthday() != null && castOther.getBirthday() != null && this .getBirthday().equals(castOther.getBirthday()))) && ((this.getCname() == castOther.getCname()) || (this .getCname() != null && castOther.getCname() != null && this .getCname().equals(castOther.getCname()))); } public int hashCode() { int result = 17; result = 37 * result + (getStuId() == null ? 0 : this.getStuId().hashCode()); result = 37 * result + (getSname() == null ? 0 : this.getSname().hashCode()); result = 37 * result + (getSex() == null ? 0 : this.getSex().hashCode()); result = 37 * result + (getBirthday() == null ? 0 : this.getBirthday().hashCode()); result = 37 * result + (getCname() == null ? 0 : this.getCname().hashCode()); return result; } }
<?xml version="1.0" encoding="utf-8"?> <!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 Persistence Tools --> <hibernate-mapping> <class name="com.wl.entity.VStuinfo" table="v_stuinfo" catalog="wltestdb"> <composite-id name="id" class="com.wl.entity.VStuinfoId"> <key-property name="stuId" type="java.lang.Integer"> <column name="stu_id" /> </key-property> <key-property name="sname" type="java.lang.String"> <column name="sname" /> </key-property> <key-property name="sex" type="java.lang.String"> <column name="sex" /> </key-property> <key-property name="birthday" type="java.util.Date"> <column name="birthday" length="10" /> </key-property> <key-property name="cname" type="java.lang.String"> <column name="cname" /> </key-property> </composite-id> </class> </hibernate-mapping>
2.查询视图
查询视图很简单,既然已经映射好了,那么就当成普通对象用HQL查询就可以了,下面看一下测试代码和运行结果,通过hibernate调用存储过程
1.创建存储过程
DELIMITER $$ USE `wltestdb`$$ DROP PROCEDURE IF EXISTS `proc_stuinfo`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_stuinfo`( IN pstuid INT ) BEGIN SELECT t1.stu_id AS stuid,t1.name AS sname,t1.sex, t1.birthday,t2.name AS cname FROM t_student t1 INNER JOIN t_classroom t2 ON t1.cid=t2.cla_id WHERE t1.stu_id=pstuid; END$$ DELIMITER ;
可以看到调用存储过程之后成功返回了数据,接下面就是如何通过hibernate去调用存储过程了。
2.在hibernate中调用存储过程
try { Connection connection = SessionFactoryUtils.getDataSource( getSessionFactory()).getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }关于hibernate操作存储过程的内容暂时介绍到这里,以后如果有更深入的学习研究还会陆续更新本篇blog。
总结
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。