在ssh框架下会经常用到hql查询,和jdbc编程一样我们也需防止hql注入。所谓的hql注入,总结起来就是利用表单输入“'”以及“or”等sql语法的保留字或语法符号,来巧妙的避开常用的验证的手段而已。
通常的解决办法就是进行动态参数设置。具体做法是:
先将hql拼装起来。用"?"代替变量值。然后在hibernate里将参数值动态注入。表达起来比较费劲。还是贴代码吧:
/**
* 通过hql分页查询
* @param form
* @param pageNo
* @param pageSize
*/
public Page pageByHql(TeamForm form, int pageNo, int pageSize){
String teamCode = form.getTeamCode();
String teamName = form.getTeamName();
String principal = form.getTeamPrincipal();
String eventCode = form.getSecondType();
if(StringUtils.isEmpty(eventCode))
eventCode = form.getFirstType(); //如果没选小类,则按大类来查询
//
StringBuffer hql = new StringBuffer("select distinct c from Team c ");
List params = new ArrayList();
if(eventCode!=null && !eventCode.equals(""))
hql.append(",PreEventTypeRes p ");
hql.append(" where 1=1 ");
if(teamCode!=null && !teamCode.equals("")){
hql.append(" and c.teamCode like ?");
params.add("%"+teamCode+"%");
}
if(teamName!=null && !teamName.equals("")){
hql.append(" and c.teamName like ?");
params.add("%"+teamName+"%");
}
if(principal!=null && !principal.equals("")){
hql.append(" and c.teamPrincipal like ?");
params.add("%"+principal+"%");
}
if(eventCode!=null && !eventCode.equals("")){
hql.append(" and c.teamId=p.resId and p.eventTypeCode like ?");
params.add("%"+eventCode+"%");
}
hql.append(" and c.delSign!='1' ");
hql.append(" order by c.teamCode asc");
return teamDao.findPageByHQL(hql.toString(), pageNo, pageSize,params.toArray());
}
上面代码的思路就是先拼装hql串的时间全部用"?"代替变量。同时将变量值装入一个list中。本来是要求数组的(后面将提到dao层的实现),因为数组长度不能动态增长,所以先用list最后进行转换
这里有一点要注意:一般我们直接拼hql里总要对变量加上单引号。但在参数list里不能加。hibernate会为我们自动加上。我想这也许就是为什么这种方式可以防止hql注入的关键所在吧。
为了便于理解下面,将最后的核心实现代码贴出来。
/**
* <ol>
* <li> 返回指定的一页记录数。用于翻页查询。返回对象列表
* </ol>
*
* @param queryString
* final String -查询条件
* @param currentPage
* final int -返回记录起始点
* @param rows
* final int -返回记录数
* @return -结果集
*/
protected List findPageListByHQL(final String queryString, final int currentPage, final int rows, final Object[] params) throws DAOException {
try {
return getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
Query q = session.createQuery(queryString);
// 设置参数
if (params != null){
for (int i = 0; i < params.length; i++) {
q.setParameter(i, params[i]);
}
}
if (currentPage > -1) {
q.setFirstResult((currentPage - 1) * rows);
}
if (rows > -1) {
q.setMaxResults(rows);
}
List list = q.list();
if (list == null) {
list = Collections.EMPTY_LIST;
}
return list;
}
});
} catch (DataAccessException e) {
logger.error(e.getMessage(), e);
throw new DAOException(e);
}
}
当然,如果不分页就不必写那多代码了直接用getHibernateTemplate().find(String queryString, Object[] values)就可以了。。
关键的是防人之心不可无啊。哈。。。
分享到:
相关推荐
以下是Hibernate中防止SQL注入的几种策略: 1. **对参数名称进行绑定**: 这是Hibernate提供的标准方法,通过创建HQL(Hibernate Query Language)查询并使用`setString()`方法来设置参数。例如: ```java Query...
4. **使用ORM框架的安全特性**:例如Hibernate的`hibernate.query.instruction.strict`配置项,可防止不安全的HQL注入。 5. **使用SQL注入检测工具**:如OWASP ZAP、SQLMap等,定期扫描系统,发现并修复潜在的SQL...
类似于SQL的预编译语句,HQL也支持参数绑定,防止SQL注入。例如: ```sql FROM Employee e WHERE e.name = :name ``` 然后在执行时传入参数值。 5. **HQL与Criteria查询的比较** Hibernate还提供了Criteria ...
1. **类型安全**:HQL在编译时就能检查语法错误,避免了运行时的SQL注入问题。 2. **移植性**:由于是面向对象的,HQL与具体的数据库方言解耦,使得应用更容易跨数据库迁移。 3. **自动类型转换**:HQL自动处理Java...
为了防止SQL注入,HQL支持参数化查询,使用`?`作为占位符。 ```sql String name = "John"; Query query = session.createQuery("FROM Person p WHERE p.name = ?"); query.setParameter(0, name); ``` ### HQL的...
- 在使用原生SQL时,需要确保参数绑定的安全性,防止SQL注入攻击。 - 需要注意类型转换和数据一致性问题,确保数据的正确性。 - 直接使用原生SQL时,可能需要手动管理事务,以保证数据的一致性和完整性。 #### ...
- **避免SQL注入**: 使用HQL可以减少SQL注入的风险。 - **提高开发效率**: 直接使用实体类和属性名进行查询,简化了开发过程。 - **数据库无关性**: HQL查询不受特定数据库的影响,提高了应用的可移植性。 **2.2 ...
- 参数化查询可防止SQL注入,参数用`?`表示,如`String hql = "SELECT * FROM User WHERE id = ?";` - 参数可以通过`setParameter(int index, Object value)`或`setParameter(String name, Object value)`设置,...
**正文** Hibernate是一款强大的Java持久化框架,它简化了数据库操作,使得开发者可以更专注于业务逻辑,而不是数据库的细节。...在进行HQL编程时,应注意避免SQL注入风险,合理使用命名参数,以确保代码的安全性。
`或`:paramName`作为参数占位符,防止SQL注入,例如: ```java String query = "from Employee e where e.name = :name"; Query q = session.createQuery(query); q.setParameter("name", "John"); ``` 以上内容...
5. 参数化查询:避免SQL注入,提高代码复用,如“SELECT u FROM User u WHERE u.name=:name”,然后设置参数“query.setParameter("name", "张三")”。 五、HQL的执行 在Hibernate中,通过Session对象的createQuery...
这种方式将查询条件直接拼接到HQL字符串中,虽然看起来更为简洁,但在安全性方面可能存在隐患,因为这容易导致SQL注入攻击。因此,在实际开发中应尽量避免直接拼接字符串的方式,而是采用参数绑定的方式。 ### 示例...
Hibernate HQL,全称为Hibernate Query Language,是Hibernate框架中用于操作对象关系映射(ORM)的查询语言。...在使用时,需要注意避免SQL注入等安全问题,并合理利用分页和命名参数来优化查询性能。
此外,HQL还支持参数绑定,防止SQL注入攻击。你可以使用占位符`?`或`:paramName`,然后在执行前设置参数值: ```java query.setParameter("age", 18); ``` 除了基本的查询,HQL还提供了复杂的联接操作,如内连接、...
- 使用HQL模糊查询时,注意防止SQL注入,确保传入的参数是安全的。 - 大量的模糊查询可能导致性能问题,应合理设计索引并优化查询。 - 在处理大量数据时,考虑分页查询以提高效率。 综上所述,Hibernate的HQL模糊...
- **SQL注入**:在动态构建SQL语句时,务必警惕SQL注入攻击。使用预编译语句(如Hibernate的`Criteria` API或`NamedQuery`)可以降低这种风险。 - **数据类型匹配**:确保数组中的元素类型与数据库字段类型匹配,以...
`作为参数占位符,避免SQL注入,如`from Employee where salary > ?`,然后在执行时传入参数值。 **Java时间日期方法大全讲解** 在Java中,处理日期和时间主要涉及`java.util.Date`, `java.sql.Date`, `java.time`...
在 JPA 中,使用 HQL 查询需要先获得 EntityManager,通过 @PersistenceContext 注解可以注入 EntityManager,然后使用 createQuery 方法创建查询对象,最后使用 getResultList 方法获取查询结果。 在 HQL 查询中,...
`或`:paramName`,然后通过`setXXX()`方法将参数值传入,避免SQL注入问题。 5. **多态查询**: HQL支持多态查询,可以直接查询基类,返回所有继承自基类的子类对象。 6. **命名查询**: 可以在Hibernate配置文件...