2013年第2周修改bug遇到的问题汇总
早上过来遇到第一个不确定问题就是mysql中exist的用法,上网搜索知道:mysql中的exist和in的用法与sqlserver用法相同。
mysql in和exists性能比较和使用
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。 如果查询的两个表大小相当,那么用in和exists差别不大。 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)
select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) 效率高,用到了B表上cc列的索引。
相反的
select * from B where cc in (select cc from A) 效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc) 效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');
与 select name from student where name='zhang' or name='li' or name='wang' or name='zhao' 的结果是相同的。
问题2,避免编译时异常@suppressWarnings("unchecked") java 中是什么意思?
屏蔽某些编译时的警告信息
比如在强制类型转换的时候编译器会给出警告
如果@SuppressWarnings("unchecked")就不会警告了
J2SE 提供的最后一个批注是 @SuppressWarnings。该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。
一点背景:J2SE 5.0 为 Java 语言增加了几个新的特性,并且和它们一起增加了许多新的警告并承诺在将来增加更多的警告。您可以为 "javac" 增加 -Xlint 参数来控制是否报告这些警告(如上面的 @Deprecated 部分所示)。
默认情况下,Sun 编译器以简单的两行的形式输出警告。通过添加 -Xlint:keyword 标记(例如 -Xlint:finally),您可以获得关键字类型错误的完整说明。通过在关键字前面添加一个破折号,写为 -Xlint:-keyword,您可以取消警告。(-Xlint 支持的关键字的完整列表可以在 javac 文档页面上找到。)下面是一个清单:
关键字 用途
deprecation 使用了不赞成使用的类或方法时的警告
unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。
fallthrough 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。
path 在类路径、源文件路径等中有不存在的路径时的警告。
serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告。
finally 任何 finally 子句不能正常完成时的警告。
all 关于以上所有情况的警告。
问题3,Hibernate中是否可执行原生的Sql语句?如何获取结果集?
可以用使用SQLQuery
对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。然后是为了获取结果集花费了1个多小时,才明白方法。
- 如果要直接返回hibernate对应的映射对象,则用原生sql查询不能直接把hibernate生成的bean作为对象装入List,所以应该是list = session.createSQLQuery(sql).addEntity(XXXX.class).list();
- 如果只查询一列string类型且要返回结果集list,则要用此法:
session.createSQLQuery(sqlSelect).addScalar("indexCode", Hibernate.STRING).list();注意一定要指定类型,不能直接用session.createSQLQuery(sqlSelect).addScalar("indexCode").list();否则结果是一个char值list,其中list的每一项是对应的string结果的第一个字符。为此浪费了几十分钟的时间,要谨记不能偷懒。
- hibernate 的createSQLQuery的几种用法(转)
使用SQLQuery
对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。最简单的情况下,我们可以采用以下形式:
List cats = sess.createSQLQuery( " select * from cats " ).addEntity(Cat. class ).list();
这个查询指定了:SQL查询字符串查询返回的实体.这里,结果集字段名被假设为与映射文件中指明的字段名相同。对于连接了多个表的查询,这就可能造成问题,因为可能在多个表中出现同样名字的字段。下面的方法就可以避免字段名重复的问题:
List cats = sess.createSQLQuery( " select {cat.*} from cats cat " ).addEntity( " cat " , Cat. class ).list();
这个查询指定了: SQL查询语句,它带一个占位符,可以让Hibernate使用字段的别名.查询返回的实体,和它的SQL表的别名. addEntity()方法将SQL表的别名和实体类联系起来,并且确定查询结果集的形态。addJoin()方法可以被用于载入其他的实体和集合的关联.
List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.addEntity( " cat " , Cat. class )
.addJoin( " kitten " , " cat.kittens " )
.list();
原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。
Double max = (Double) sess.createSQLQuery( " select max(cat.weight) as maxWeight from cats cat " )
.addScalar( " maxWeight " , Hibernate.DOUBLE);
.uniqueResult();
除此之外,你还可以在你的hbm文件中描述结果集映射信息,在查询中使用。
List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.setResultSetMapping( " catAndKitten " )
.list();
命名SQL查询
可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们不 需要调用addEntity()方法.
< sql - query name = " persons " >
< return alias = " person " class = " eg.Person " />
Select person.NAME AS {person.name},person.AGE AS {person.age},person.SEX AS {person.sex} FROM PERSON person Where person.NAME LIKE :namePattern
</ sql - query >
List people = sess.getNamedQuery( " persons " ).setString( " namePattern " , namePattern)
.setMaxResults( 50 )
.list();
Session session =HSessionFactory.getSession();
// List list=session.createSQLQuery("select * from dept where rownum <1000 and DEPTNO=? and dname=?").addEntity(Dept.class).setInteger(0, 187).setString(1, "sdfsdfsdf").list();
Query query=session.createSQLQuery("select * from dept where rownum <1000 and DEPTNO=? and dname=?").addEntity(Dept.class);
query.setString(1, "sdfsdfsdf");
query.setInteger(0, 187);
List list=query.list();
for(Object o:list)
{
System.out.println(((Dept)o).getDname()+"-------"+((Dept)o).getDeptno());
}