hibernate之参数绑定
----------
我们应该拒绝SQL(或HQL)的拼装,应该永远不要编写这样的代码,有这很严重的安全问题,众所周知的SQL注入。我们可以考虑参数绑定,在hibernate中它有两种方式。
1.具名参数
利用具名参数的例子:
- String queryString = "from Item item where item.description like :search";
- String queryString = "from Item item where item.description like :search";
参数名称前面的冒号表示这是一个具名参数。然后,对search参数绑定一个值:
- Query q = session.createQuery(queryString).setString("search",searchString);
- Query q = session.createQuery(queryString).setString("search",searchString);
由于searchString是一个用户提供的字符串变量,你调用Query接口的setString()方法,把它绑定到具名参数(:search)。这个代码更规则、更安全且执行得更好,因为如果只是绑定参数的变化,单独编译过的SQL语句就可以被重用。
多个参数例:
- String queryString = "from Item item where item.description like :search and item.date > :minDate";
- Query q = session.createQuery(queryString).setString("search",searchString).setDate("minDate",mDate);
- String queryString = "from Item item where item.description like :search and item.date > :minDate";
- Query q = session.createQuery(queryString).setString("search",searchString).setDate("minDate",mDate);
你已经调用了setString()和setDate()来把实参绑定查询参数。原生的hibernate Query接口提供类似的便利方法,用来绑定大多数hibernate内建类型的参数:从setInteger()到setTimestamp()和setLocale()的一切。
特别有用的一种方法setEntity(),它让你绑定一个特久化实体,如例:
- session.createQuery("from Item item where item.seller = :seller").setEntity("seller",theSeller);
- session.createQuery("from Item item where item.seller = :seller").setEntity("seller",theSeller);
然而,还有一种允许绑定任何hibernate类型实参的一般方法,如例:
- String queryString = "from Item item where item.seller = :seller and item.description like :desc";
- session.createQuery(queryString).setParameter("seller",theSeller,Hibernate.entity(User.class))
- .setParameter("desc",description,Hibernate.STRING);
- String queryString = "from Item item where item.seller = :seller and item.description like :desc";
- session.createQuery(queryString).setParameter("seller",theSeller,Hibernate.entity(User.class))
- .setParameter("desc",description,Hibernate.STRING);
2.定位参数
如果你喜欢,你可以使用定位参数,如例:
- String queryString = "from Item item where item.description like ? and item.date > ?";
- Query q = session.createQuery(queryString).setString(0,searchString).setDate(1,minDate);
- String queryString = "from Item item where item.description like ? and item.date > ?";
- Query q = session.createQuery(queryString).setString(0,searchString).setDate(1,minDate);
绑定参数位置的每一个变化都需要改变参数绑定代码,这样就产生了易碎和更需要维护的代码,建议避免使用定位
参数。如果必须使用定位参数,要记住hibernate是从0开始计数(JPA是从1开始记数);