阅读:2785回复:0
Hibernate对注入的简单测试
◆0 背景
前段时间遇到一个使用了Hibernate框架的站,以前没怎么接触过(由于是Java盲,所以大家勿喷),再注入的事情发生了许多奇奇怪怪的事情,于是向本地搭一个看看是个神马情况。Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询。 ◆1 测试 本次测试的环境是JDK5.0+Tomcat8+Hibernate3.0+Servlet。数据库情况如下: 图片:2013112511500521075.png 通过百度知道Hibernate的查询大概有5、6种,通过分析对注入能产生不同影响的应该有如下三种: 1、HQL方式 2、原生SQL方式 3、Criteria方式 重点是HQL方式,HQL相当于Hibernate自己有一套SQL语法,在用Hibernate作为查询中间层的时候,它会将你写的HQL翻译成对应数据库的SQL语句,Hibernate支持N种数据库。 会一丢丢Java的童鞋都知道Hibernate的使用流程: 首先要告诉Hibernate数据库的连接信息,hibernate.cfg.xml文件: #!xml org.hibernate.dialect.Oracle9Dialect jdbc:oracle:thin:@192.168.79.151:1521:orcl system xxoo oracle.jdbc.driver.OracleDriver oracle_connet //这里是包含表的映射文件 其实是映射你想使用的数据表(系统会按照表明自动生成文件,比如我的Userlist表会生成Userlist.hbm.xml),Userlist.hbm.xml文件: 分别将ID、USERNAME、USERPWD列映射为id、username、userpwd,而在实际环境中,开发者可能映射成他们喜欢的名字。 注: 1、未映射的表是不能查询的; 2、使用映射后表名、列名时大小写敏感; 3、不能使用数据库中的列名,比如USERNAME映射为username之后,不能再使用USERNAME,否则报错。 </br> #!xml 1、原生的HQL方式:大概代码: try{ s=HibernateSessionFactory.getSession(); tx=s.beginTransaction(); Query query=s.createQuery("from Userlist as u where username='" +userName + "'"); Qstring=query.getQueryString(); // Iterator it = query.iterate(); //这是Iterate数据返回方式 List it=query.list();//这是List数据返回方式 // ul = (Userlist) it.next(); ul=(Userlist)it.get(0); mUserPwd=ul.getUserpwd(); }catch (Exception e) { System.out.println(e.getMessage()); return e.getMessage(); }//这里加了返回抛出的异常的代码 tx.commit(); //关闭连接 HibernateSessionFactory.closeSession(); 上面提到的Iterate和List数据返回方式没发现对注入产生多大的影响,他们呢的具体差别请google。 使用单引号测试(有返回异常的代码,数据库报错): 图片:2013112511500521075.png 使用单引号测试(没有返回异常的代码,默认情况,Tomcat报错): 图片:2013112511500521075.png And 'a'='a 图片:2013112511500521075.png And 'a'='b 图片:2013112511500521075.png 跨库查系统表?想都不要想: 图片:2013112511500521075.png *号也是不能用滴: 图片:2013112511500521075.png 不支持union: 图片:2013112511500521075.png 单独内嵌select作为条件(正常执行): 图片:2013112511500521075.png 单独执行substr(),ASCII()函数没问题: 图片:2013112511500521075.png 但是执行 ASCII(SUBSTR((select userpwd from Userlist where ROWNUM=1),1,1))>0 就不行了: 图片:2013112511500521075.png 结论:这里能爆的列还得看前面那个select的心情。 小刺猬和它的小伙伴们都惊呆了: 图片:2013112511500521075.png 对于第二种使用原生SQL的方式,写法大概是这样: s=HibernateSessionFactory.getSession(); tx=s.beginTransaction(); Query query=s.createSQLQuery("select USERPWD from Userlist where USERNAME='" +userName + "'"); Qstring=query.getQueryString(); List it = query.list(); mUserPwd=(String)it.get(0); 就不多说了,就可普通注入一样。毫无压力: 图片:2013112511500521075.png 说说第三种,写法大概是这样: s=HibernateSessionFactory.getSession(); List UserLists=s.createCriteria(Userlist.class).add(Restrictions.eq("username",userNameString)).list(); Userlist u=(Userlist)UserLists.get(0); mUserPwd=u.getUserpwd(); 如果说我们在HQL下还能用 ascii(substr(userpwd,1,1))>1 来猜解前面SELECT中选择的列中有的列的内容的话,那么在第三种Criteria方式下,基本就绝望了: 图片:2013112511500521075.png 图片:2013112511500521075.png 图片:2013112511500521075.png 图片:2013112511500521075.png 本来要结束的时候,我发现了第四种,是HQL的另一种写法,大概代码这么写: s=HibernateSessionFactory.getSession(); tx=s.beginTransaction(); Query query=s.createSQLQuery("select {p.*} from Userlist {p} where {p}.USERNAME="+userNameString).addEntity("p", Userlist.class); Qstring=query.getQueryString(); List it = query.list(); mUserPwd=(String)it.get(0); 貌似这样的也没得玩,歇菜了: 图片:2013112511500521075.png 图片:2013112511500521075.png ◆2 总结 最后:时间有限,只做了字符型的简单粗浅表面测试,抛个砖,希望有更多经验的留言啊,毕竟这方面的资料网上真心极少,为了方便大众,请大牛们现身说法。 </p> |
|