hibernate执行sql语句的总结5篇范文修改版.docx
《hibernate执行sql语句的总结5篇范文修改版.docx》由会员分享,可在线阅读,更多相关《hibernate执行sql语句的总结5篇范文修改版.docx(21页珍藏版)》请在冰豆网上搜索。
hibernate执行sql语句的总结5篇范文修改版
第一篇:
hibernate执行sql语句的总结
下面看个示例:
publicListfindMenusByEntityTypeId(Longid){
Stringhql="selectm.idas{menu.id},m.nameas{menu.name},m.urlas{menu.url},m.icon_urlas{menu.iconUrl},m.parent_idas{menu.parentId},"
+"m.serial_numberas{menu.serialNo},m.adminas{menu.adminUse},m.system_adminas{menu.systemAdmin},m.program_nameas{menu.programName}"
+"frommenum,entity_typeet,entity_admin_menueam"
+"whereet.id="+id+""
+"andm.program_name='"+GlobalNames.PROGRAM_NAME_CHSS+"'"
+"andet.id=eam.entity_id"
+"andm.id=eam.menu_id";
List
nu",Menu.class).list();
returnmenus;
}
1.通过addEntity("menu",Menu.class),通过addEntity把要返回的数据强转为Menu,注意Menu必须要是配置hibernate映射了的。
m.idas{menu.id},这是为了如果数据库字段名和Menu模型中不一样所以都as取了个别名,那么这样就能返回menu对象了。
2、如果要执行的sql语句是多表查询,并且是返回一个对象。
但是这个对象是没有配置hibernate映射的。
这种就麻烦了。
hibernate执行SQL默认返回的是一个object类型的数组,
Listmenus
=super.getSessionFactory().getCurrentSession().createSQLQuery(hql).list();
for(inti=0;i
{Object[]objects=(Object[])menus.get(i);for(intj=0;j
运行后报错:
java.lang.ClassCastExceptionjava.lang.Object;cannotbecastto
net.greatsoft.chss.domain.privilege.model.Menu,原来是查询出来的字段并不能自动转换为bean对象,所以要添加addEntity(Clazzclass)。
有人肯定会说添加addEntity了,但是如果Menu没有添加hibernate映射的话,此时会报Menuunmapping。
。
。
。
。
。
就是没添加映射,
所以只能添加setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);//返回一个map,KEY:
为DB中名称一致(大小写一致)遍历list时就可以。
所以只能将返回的值变成Map,这样就好操作了,然后就可用反射取值了,详细看:
hibernate执行sql语句返回自定义对象
3、hibernate中createQuery与createSQLQuery两者区别是:
前者用的hql语句进行查询,后者可以用sql语句查询
前者以hibernate生成的Bean为对象装入list返回,后者则是以对象数组进行存储
所以使用createSQLQuery有时候也想以hibernate生成的Bean为对象装入list返回,就不是很menus=super.getSessionFactory().getCurrentSession().createSQLQuery(hql).addEntity("me
方便
突然发现createSQLQuery有这样一个方法可以直接转换对象
Queryquery=session.createSQLQuery(sql).addEntity(XXXXXXX.class);
XXXXXXX代表以hibernate生成的Bean的对象,也就是数据表映射出的Bean。
但是这个bean必须有映射
呵呵以后多注意,还是时不时的要看看hibernate各个对象方法的使用.
第二篇:
通过分析SQL语句的执行计划优化SQL(总结)
通过分析SQL语句的执行计划优化SQL(总结)
做DBA快7年了,中间感悟很多。
在DBA的日常工作中,调整个别性能较差的SQL语句时一项富有挑战性的工
作。
其中的关键在于如何得到SQL语句的执行计划和如何从SQL语句的执行计划中发现问题。
总是想将日常
经验的点点滴滴总结一下,但是直到最近才下定决心,总共花了3个周末时间,才将其整理成册,便于自
己日常工作。
不好意思独享,所以将其贴出来。
修改日志:
2006.02.20:
根据网友反馈已做部分修改,但pdf文件没有做修改,修改部分在“如何产生执行计划”关于set
autotraceonly的介绍部分
第一章、第2章并不是很重要,是自己的一些想法,关于如何做一个稳定、高效的应用系统的一些想法。
第三章以后都是比较重要的。
附录的内容也是比较重要的。
我常用该部分的内容。
前言
本文档主要介绍与SQL调整有关的内容,内容涉及多个方面:
SQL语句执行的过程、ORACLE优化器,表之间
的关联,如何得到SQL执行计划,如何分析执行计划等内容,从而由浅到深的方式了解SQL优化的过程,使
大家逐步步入SQL调整之门,然后你将发现„„。
该文档的不当之处,敬请指出,以便进一步改正。
请将其发往我的信箱:
xu_yu_jin2000@。
如果引用本文的内容,请著名出处
第1章性能调整综述第2章有效的应用设计
第3章SQL语句处理的过程第4章ORACLE的优化器第5章ORACLE的执行计划访问路径(方法)--accesspath表之间的连接
如何产生执行计划如何分析执行计划
如何干预执行计划-合并连接(SortMergeJoin(SMJ))嵌套循环(NestedLoops(NL))哈希连接(HashJoin)
排序-合并连接(SortMergeJoin,SMJ):
a)对于非等值连接,这种连接方式的效率是比较高的。
b)如果在关联的列上都有索引,效果更好。
c)对于将2个较大的rowsource做连接,该连接方法比NL连接要好一些。
d)但是如果sortmerge返回的rowsource过大,则又会导致使用过多的rowid在表中查询数据时,数据库
性能下降,因为过多的I/O。
嵌套循环(NestedLoops,NL):
a)如果drivingrowsource(外部表)比较小,并且在innerrowsource(内部表)上有唯一索引,或有高选择性非唯一索引时,使用这种方法可以得到较好的效率。
b)NESTEDLOOPS有其它连接方法没有的的一个优点是:
可以先返回已经连接的行,而不必等待所有的连接操作处理完才返回数据,这可以实现快速的响应时间。
哈希连接(HashJoin,HJ):
a)这种方法是在oracle7后来引入的,使用了比较先进的连接理论,一般来说,其效率应该好于其它2种连接,但是这种连接只能用在CBO优化器中,而且需要设置合适的hash_area_size参数,才能取得较好的性能。
b)在2个较大的rowsource之间连接时会取得相对较好的效率,在一个rowsource较小时则能取得更好的效率。
c)只能用于等值连接中
笛卡儿乘积(CartesianProduct)当两个rowsource做连接,但是它们之间没有关联条件时,就会在两个rowsource中做笛卡儿乘积,这通
常由编写代码疏漏造成(即程序员忘了写关联条件)。
笛卡尔乘积是一个表的每一行依次与另一个表中的所
有行匹配。
在特殊情况下我们可以使用笛卡儿乘积,如在星形连接中,除此之外,我们要尽量使用笛卡儿
乘积,否则,自己想结果是什么吧!
注意在下面的语句中,在2个表之间没有连接。
SQL>explainplanforselectemp.deptno,dept,deptnofromemp,dept
QueryPlan------------------------------SLECTSTATEMENT[CHOOSE]Cost=5MERGEJOINCARTESIANTABLEACCESSFULLDEPTSORTJOINTABLEACCESSFULLEMP
CARTESIAN关键字指出了在2个表之间做笛卡尔乘积。
假如表emp有n行,dept表有m行,笛卡尔乘积的结果
就是得到n*m行结果。
7楼
06-01-1217:
48[大中小]
SunnyXu一般会员
注册日期:
2004Nov来自:
技术贴数:
38精华贴数:
1论坛积分:
267论坛排名:
9743论坛徽章:
0
[center]如何产生执行计划[/center]
要为一个语句生成执行计划,可以有3种方法:
1).最简单的办法
Sql>setautotraceonSql>select*fromdual;执行完语句后,会显示explainplan与统计信息。
这个语句的优点就是它的缺点,这样在用该方法查看执行时间较长的sql语句时,需要等待该语句执行成
功后,才返回执行计划,使优化的周期大大增长。
如果想得到执行计划,而不想看到语句产生的数据,可以采用:
Sql>setautotracetraceonly这样还是会执行语句。
它比setautotraceon的优点是:
不会显示出查询的数据,但是还是会将数据输出
到客户端,这样当语句查询的数据比较多时,语句执行将会花费大量的时间,因为很大部分时间用在将数
据从数据库传到客户端上了。
我一般不用这种方法。
Sql>setautotracetraceonlyexplain如同用explainplan命令。
对于select语句,不会执行select语句,而只是产生执行计划。
但是对于dml
语句,还是会执行语句,不同版本的数据库可能会有小的差别。
这样在优化执行时间较长的select语句时
,大大减少了优化时间,解决了“setautotraceon”与“setautotracetraceonly”命令优化时执行
时间长的问题,但同时带来的问题是:
不会产生Statistics数据,而通过tatistics数据的物理I/O的次数
,我们可以简单的判断语句执行效率的优劣。
如果执行该语句时遇到错误,解决方法为:
(1)在要分析的用户下:
Sqlplus>@?
\rdbms\admin\utlxplan.sql
(2)用sys用户登陆
Sqlplus>@?
\sqlplus\admin\plustrce.sqlSqlplus>grantplustracetouser_name;->A)-->C。
如果数据库是基于代价的优化器,它会利用计
算出的代价来决定合适的驱动表与合适的连接顺序。
一般来说,CBO都会选择正确的连接顺序,如果CBO选
择了比较差的连接顺序,我们还可以使用ORACLE提供的hints来让CBO采用正确的连接顺序。
如下所示:
select/*+ordered*/A.col4fromB,A,CwhereB.col3=10andA.col1=B.col1andA.col2=C.col2andC.col3=5
既然选择正确的驱动表这么重要,那么让我们来看一下执行计划,到底各个表之间是如何关联的,从而得
到执行计划中哪个表应该为驱动表:
在执行计划中,需要知道哪个操作是先执行的,哪个操作是后执行的,这对于判断哪个表为驱动表有用处
。
判断之前,如果对表的访问是通过rowid,且该rowid的值是从索引扫描中得来得,则将该索引扫描先从
执行计划中暂时去掉。
然后在执行计划剩下的部分中,判断执行顺序的指导原则就是:
最右、最上的操作
先执行。
具体解释如下:
得到去除妨碍判断的索引扫描后的执行计划:
ExecutionPlan---------------------------0SELECTSTATEMENTOptimizer=CHOOSE10MERGEJOIN21SORT(JOIN)32NESTEDLOOPS43TABLEACCESS(FULL)OF'B'53TABLEACCESS(BYINDEXROWID)OF'A'71SORT(JOIN)87TABLEACCESS(FULL)OF'C'看执行计划的第3列,即字母部分,每列值的左面有空格作为缩进字符。
在该列值左边的空格越多,说明
该列值的缩进越多,该列值也越靠右。
如上面的执行计划所示:
第一列值为6的行的缩进最多,即该行最
靠右;第一列值为
4、5的行的缩进一样,其靠右的程度也一样,但是第一列值为4的行比第一列值为5的行
靠上;谈论上下关系时,只对连续的、缩进一致的行有效。
从这个图中我们可以看到,对于NESTEDLOOPS部分,最右、最上的操作是TABLEACCESS(FULL)OF'B',
所以这一操作先执行,所以该操作对应的B表为第一个驱动表(外部表),自然,A表就为内部表了。
从图中
还可以看出,B与A表做嵌套循环后生成了新的rowsource,对该rowsource进行来排序后,与C表对应的
排序了的rowsource(应用了C.col3=5限制条件)进行MSJ连接操作。
所以从上面可以得出如下事实:
B表
先与A表做嵌套循环,然后将生成的rowsource与C表做排序—合并连接。
通过分析上面的执行计划,我们不能说C表一定在B、A表之后才被读取,事实上,B表有可能与C表同时被
读入内存,因为将表中的数据读入内存的操作可能为并行的。
事实上许多操作可能为交叉进行的,因为
第三篇:
执行多条SQL语句
执行多条SQL语句
使用mysqli一次执行多条SQL语句
php
$mysqli=newMySQLi("localhost","root","","xiaoqiangdb");
/*==========================没有结果集:
insertupdatedelete==========================*/
$sqls="insertintoshops(name,price,num,desn)values('book1','12.16','5','good');";
$sqls.="updatedshopssetname='testname'whereid>50;";
$sqls.="deletefromshopswhereid<20";
if($mysqli->multi_query($sqls)){
echo"多条语句执行成功!
";
echo"最后插入的ID:
".$mysqli->insert_id."
";
//echo"影响的行数:
".$mysqli->affected_rows;//不准确!
}else{
echo"ERROR".$mysqli->errno."---".$mysqli->error;
}
/*==========================有结果集:
select==========================*/$sqls="selectcurrent_user();";
$sqls.="descshops;";
$sqls.="select*fronshops";
if($mysqli->multi_query($sqls)){
echo"多条语句执行成功!
";
do{
$result=$mysqli->store_result();//获取结果集
echo'';
if($mysqli->more_results()){//判断还有没有结果集echo"
";
}
}while($mysqli->next_result());//取得下一个结果集}else{
echo"ERROR".$mysqli->errno."---".$mysqli->error;}
$mysqli->close();
?
>
第四篇:
SQL语句总结
SQL语句总结
一、插入记录
1.插入固定的数值
语法:
INSERT[INTO]表名[(字段列表)]VALUES(值列表)
示例1:
InsertintoStudentsvalues('Mary’,24,’mary@’)
若没有指定给Student表的哪些字段插入数据:
表示给该表的所有字段插入数据,根据数据的个数,可以得知Students表中一共有3个字段表中有4个字段,其中一个字段是标识列。
示例2:
InsertintoStudents(Sname,Sage)values(‘Mary’,24)
指定给表中的Sname,Sage两个字段插入数据。
注意事项:
1)该命令运行一次向表中插入1条记录。
无法实现向已存在的某记录中插入一个数据
2)如果不指定给哪些字段插入数值,则应注意值列表的值个数
3)插入数据时,注意值的数据类型要与对应的字段数据类型匹配
4)插入数据时,如果没有给值的字段必须保证允许其为空
5)插入数据时,要注意字段中的一些约束
2.插入的记录集为一个查询结果
语法:
INSERTINTO表名[(字段列表)]SELECT字段列表FROM表WHERE条件示例1:
InsertintoTeacherselectSname,Sage,SemailfromStudent
从Student表中查询三个字段的全部记录,插入Teacher表,没有指定Teacher表的具体字段,表示给Teacher表的全部字段插入数值
示例2:
InsertintoTeacherselectSname,Sage,SemailfromStudentwhereSage>25
从Student表中查询三个字段的部分记录,插入Teacher表
示例3:
InsertintoTeacher(tid,tname)selectSname,SagefromStudent从Student表中查询两个字段的全部记录,插入到Teacher表中的tid,tname字段注意事项:
查询表的字段要和插入表的字段数据类型一一对应
3.生成表查询
语法:
SELECT字段列表INTO新表名FROM原表WHERE条件
示例1:
SelectSname,Sage,SemailintonewStudentfromStudentwhereSage
共6页当前第1页
示例2:
SelectSname,Sage,SemailintonewStudentfromStudentwhere1=2
利用Student表的表结构生成新表newStudent,newStudent表中记录为空
注意事项:
执行该语句时,确保数据库中不存在into关键字后面的指定的表名
二、删除记录
1)删除满足条件的记录
语法:
DELETEFROM表名WHERE条件
示例1:
DeletefromStudentwhereSage
从Student表中删除年龄小于20岁的学生的记录
示例2:
DeletefromStudent
没有设置条件,删除Student表的全部记录
2)删除表的全部记录
语法:
TRUNCATETABLE表名
示例:
TruncatetableStudent
删除表Student中的全部记录,约束依然存在
三、修改记录
语法:
UPDATE表名SET字段=新值WHERE条件
示例1:
UpdateStudentsetSemail=’Email’+SemailwhereSemailisnotnull
把有email的学员的email地址变为原先的地址前加上‘Email’字符串
示例2:
UpdateStudentsetSage=Sage+1
把所有记录的Sage变为原先的值加1,例如过一年学生要长一岁
四、查询记录
1.基本查询
语法:
SELECT字段列表FROM表
示例1:
SelectsName,sAge,sEmailfromStudents
从Students表中查询3个字段的所有的记录
示例2:
Select*fromStudents
从Students表中查询所有字段的所有的记录(字段列表位置写*代表查询表中所有字段)
2.带WHERE子句的查询
语法:
SELECT字段列表FROM表WHERE条件
示例1:
SelectSNamefromStudentswhereSage>23
查询Students表中年龄大于23的学员的姓名
3.应用别名
语法1:
SELECT字段列表AS别名„„
示例1:
SelectSNameas学员姓名,sAgeas学员年龄fromStudents
将查询的两个字段分别用中文别名显示
语法2:
SELECT别名=字段„„
示例2:
Select学员姓名=sName,学员年龄=sAgefromStudents
注意事项:
别名可以是英文,也可以是中文,别名可以用单引号引起,也可以不引
4.使用常量(利用‘+’连接字段和常量)
示例:
SelectsName+’的年龄是’+convert(varchar
(2),sAge)as学员信息
fromStudents
从Students表中查询,将学员的姓名和年龄信息与一个常量连接起来,显示为一个字段,该字段以“学员信息”为别名
5.限制返回的行数
语法1:
SELECTTOPN字段列表FROM表
示例1:
Selecttop3sName,sAgefromStudents
查询Students表的前三条记录
语法2:
SELECTTOPNPERCENT字段列表FROM表
示例2:
Selecttop30percentsName,sAgefromStudents
查询Students表的前30%条记录
6.排序
语法:
SELECT字段列表FROM表WHERE条件ORDERBY字段ASC/DESC示例1:
Select*fromStudentswheresAge>20orderbysAge
查询年龄大于20岁的学员信息,并且按照年龄升序排序(若不指定升降序,默认为升序)示例2:
Select*fromStudentsorderbysNamedesc
查询所有学生的所有信息,并按照学生的姓名降序排序
7.