文档章节

hibernate调用mysql存储过程

Evyn_lv
 Evyn_lv
发布于 2016/06/06 18:10
字数 1235
阅读 86
收藏 0

hibernate调用mysql存储过程

    文章转自:anxpp.com

    在最近的项目中,碰到一小段数据库数据分析的程序,需要结合多张表联合查询或涉及到子查询,项目主要采用的java ee开发,使用了hibernate框架,由于这些表没用从实体通过hibernate直接生成,也没有外键之类的东西,于是就开始写sql,写完sql再放入程序中转为hql,然后查询。

navicat

    写好的sql:中文:50 英文:1075 数字:0 中文+标点:50 中文+数字:50 。字符总数:共记1175个字符 (汉字算两个字符,数字、空格、英文字母算做一个字符),放入程序中相当难看,java中不像c#可以使用@“”将一个字符串分多行书写(或许有有种方法鄙人没发现),写作一行太长,多行使用“+”连接总感觉效率低了那么一点点心里不舒服。
    最主要的原因是:后期维护实在太难

    鉴于如上几点,就将一个大的sql联合查询改为视图,将子查询也做成视图,最终可以直接查询单一视图获取需要的数据,代码中也简洁,好维护,需要修改直接改视图就行了。

    但是,查询的数据是要经过动态的传入参数作查询条件的,视图依然不是最好的解决方案,所以就只能用存储过程了,因为以前从来没用过mysql的存储过程,所以一开始就没选这种方法,实在不行了,还得学,不过学起来还是很快的,很快就做好了,完成后程序代码也简洁,后期好维护,效率也可以。

    上面涉及到的一些知识总结如下:

    1、子查询:

SELECT H.hosCode,H.hosName,K.keshiName,N.doctornum,R.receivedcount,T.keshitime
FROM(/*统计科室医生接待人数*/
		SELECT Q.keshiId,COUNT(*) AS receivedcount
		FROM(		/*医生和科室关系*/
				SELECT D.doctorId,K.keshiId
				FROM erpsinglekeshi K,erpsingledoctor D
				WHERE K.keshiId=D.keshiId) as Q,erpdoctorreceivedcount R
		WHERE Q.doctorId=R.doctorId
		GROUP BY R.doctorId) AS R,
		(/*统计科室医生在线时间*/
		SELECT Q.keshiId,SUM(T.onlineTime) AS keshitime
		FROM(		/*医生和科室关系*/
				SELECT D.doctorId,K.keshiId
				FROM erpsinglekeshi K,erpsingledoctor D
				WHERE K.keshiId=D.keshiId) as Q,erpdoctoronlinetime T
		WHERE Q.doctorId=T.doctorId
		GROUP BY T.doctorId) as T,
		(/*科室人数统计*/
		SELECT D.keshiId,COUNT(*) AS doctornum
		FROM erpsingledoctor D
		GROUP BY D.keshiId) AS N,erpsinglehospital H,erpsinglekeshi K
WHERE N.keshiId=T.keshiId AND R.keshiId=N.keshiId AND H.hospitalId=K.hospitalId AND K.keshiId=N.keshiId

    2、sql转hql

    sql转hql其实不难,hibernate其实是可以直接调用sql的,如果一定要将sql转为hql(好处是可以直接将实体与表对应起来),只要将表名改为实体名,字段名与实体定义相同即可。

    3、视图

    视图其实就是一个写好的sql,可以将需要的数据(通常是从多张表组合而来)生成一张表,但这个表是虚拟的,硬盘上并不保存这张表的数据,只会保存这个生成过程,但对于用户,查询普通表和视图是一样的,使用视图可以让用户不能直接操作表,只用作查询的时候很有用,视图创建如下(其中联合查询的几张表也是视图):
    

/*single_doctor*/
create view single_doctor as
SELECT H.hosCode,H.hosName,K.keshiName,N.doctornum,R.receivedcount,T.keshitime
FROM keshi_received AS R,keshi_onlinetime as T,keshi_num AS N,erpsinglehospital H,erpsinglekeshi K
WHERE N.keshiId=T.keshiId AND R.keshiId=N.keshiId AND H.hospitalId=K.hospitalId AND K.keshiId=N.keshiId

    4、存储过程

    存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它:
 

#使用Navicat创建的存储过程
BEGIN
	#Routine body goes here...
	SELECT H.hosCode,H.hosName,K.keshiName,N.doctornum,R.receivedcount,T.keshitime,T.docType
FROM(/*统计科室医生接待人数*/
		SELECT Q.keshiId,COUNT(*) AS receivedcount
		FROM(		/*医生和科室关系*/
				SELECT D.doctorId,K.keshiId
				FROM erpsinglekeshi K,erpsingledoctor D
				WHERE K.keshiId=D.keshiId) as Q,erpdoctorreceivedcount R
		WHERE Q.doctorId=R.doctorId AND R.currentTime<endTime AND R.currentTime>startTime
		GROUP BY R.doctorId) AS R,
		(/*统计科室医生在线时间*/
		SELECT Q.keshiId,SUM(T.onlineTime) AS keshitime,T.docType
		FROM(		/*医生和科室关系*/
				SELECT D.doctorId,K.keshiId
				FROM erpsinglekeshi K,erpsingledoctor D
				WHERE K.keshiId=D.keshiId) as Q,erpdoctoronlinetime T
		WHERE Q.doctorId=T.doctorId AND T.currentTime<endTime AND T.currentTime>startTime
		GROUP BY T.doctorId) as T,
		(/*科室人数统计*/
		SELECT D.keshiId,COUNT(*) AS doctornum
		FROM erpsingledoctor D
		GROUP BY D.keshiId) AS N,erpsinglehospital H,erpsinglekeshi K
WHERE N.keshiId=T.keshiId AND R.keshiId=N.keshiId AND H.hospitalId=K.hospitalId AND K.keshiId=N.keshiId AND N.doctornum<startTime;
END
#参数
IN `startTime` bigint,IN `endTime` bigint

    5、hibernate调用存储过程

    

@Autowired
	protected HibernateTemplate hibernateTemplateMysql;
public List<DoctorOnlineDetail> getDoctorOnlineDetails(final long startTime,final long endTime) {
		return hibernateTemplateMysql.execute(new HibernateCallback() {
			@SuppressWarnings("deprecation")
			public Object doInHibernate(Session session) throws HibernateException,SQLException {
				List<DoctorOnlineDetail> doctorOnlines = new ArrayList<>();
				String procdure = "{Call pro_doctor_online_detail(?,?)}";  
				CallableStatement cs;
				cs = session.connection().prepareCall(procdure);
				cs.setLong(1, startTime);
				cs.setLong(2, endTime);
				ResultSet rs = cs.executeQuery();
				//H.hosCode,H.hosName,K.keshiName,D.doctorName,T.time,R.received
				while(rs.next()){
					doctorOnlines.add(new DoctorOnlineDetail(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4),rs.getLong(5),rs.getInt(6),rs.getInt(7)));
				}
				return doctorOnlines;
			}
		});
	}
    文章转自:anxpp.com

本文转载自:http://blog.csdn.net/anxpp/article/details/50585322

Evyn_lv
粉丝 2
博文 76
码字总数 49292
作品 0
杭州
高级程序员
私信 提问
hibernate调用mysql存储过程

 在mysql中创建两个存储过程,如下: 1、根据id查找某条数据: 1 CREATE PROCEDURE (IN id INTEGER(11))2 begin3 select * from emp where empId=id;4 end; 2、根据id查找某个字段,并返回 ...

开源中国-首席码农
2016/03/22
9
0
MySQL 使用 JPA + Hibernate 的 9 个高性能技巧

本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 介绍 尽管有SQL标准,但每个关系数据库终将是唯一的,因此你需要调整数据访问层,以便充分利用在使...

码农网
2017/10/27
0
0
mybatis怎么配置和调用分页功能存储过程?

在mysql里面写了一个分页的存储过程,返回的是结果集和总的条数 请问在mybatis里面怎么配置和调用,刚接触mybatis,以前用hibernate和springjdbc都没有问题 请各位高手指教,感谢不尽....

关注
2011/12/21
3.1K
4
hibernate sql 查询

Hibernate 支持使用原生的SQL查询,使用原生SQL查询可以利用某些数据库特性,原生SQL查询也支持将SQL语句放在配置文件中配置,从而提高程序的解耦,命名SQL查询还可以用于调用存储过程。 SQL查...

DaDa-da
2018/04/23
21
0
hibernate中调用存储过程

我搭建的一个ssh1(spring2.5.6+hibernate3.4+struts1.3.8)框架中需要提供一个调用存储过程的公有方法。 原理:这个其实和ssh没啥关系,主要是我们的java.sql.Connection中已经提供了这样的...

索隆
2012/06/23
129
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部