Java 使用URL键/值样式参数休眠查询限制
我正在使用Tapestry5和Hibernate。我正在尝试构建一个使用从URL生成的动态限制的条件查询。我的URL上下文被设计成一个键/值对 范例Java 使用URL键/值样式参数休眠查询限制,java,hibernate,tapestry,Java,Hibernate,Tapestry,我正在使用Tapestry5和Hibernate。我正在尝试构建一个使用从URL生成的动态限制的条件查询。我的URL上下文被设计成一个键/值对 范例 www.mywebsite.com/make/ford/model/focus/year/2009 我对参数进行如下解码 private Map<String, String> queryParameters; private List<Vehicle> vehicles; void onActivate(Eve
www.mywebsite.com/make/ford/model/focus/year/2009
我对参数进行如下解码
private Map<String, String> queryParameters;
private List<Vehicle> vehicles;
void onActivate(EventContext context) {
//Count is 6 - make/ford/model/focus/year/2009
int count = context.getCount();
if (count > 0) {
int i;
for (i = 0; (i + 1) < count; i += 2) {
String name = context.get(String.class, i);
String value = context.get(String.class, i + 1);
example "make"
System.out.println("name " + name);
example "ford"
System.out.println("value " + value);
this.queryParameters.put(name, value);
}
}
this.vehicles = this.session.createCriteria(Vehicle.class)
...add dynamic restrictions.
}
私有映射查询参数;
私家车名单;
激活时无效(事件上下文){
//计数为6-品牌/福特/车型/焦点/年份/2009
int count=context.getCount();
如果(计数>0){
int i;
对于(i=0;(i+1)
我希望有人能帮我弄清楚如何在我的查询中动态添加限制列表。我相信这已经完成了,所以如果有人知道一个帖子,那也会很有帮助。谢谢我假设您只需在参数映射上循环,并为每一对添加一个限制
请注意,如果不小心,这将使您面临sql注入攻击。防止这种情况发生的最简单方法是,在添加标准之前,根据已知的车辆属性检查钥匙。我假设您只需在参数图上循环,并为每对钥匙添加一个限制
请注意,如果不小心,这将使您面临sql注入攻击。防止这种情况发生的最简单方法是,在添加标准之前,根据已知的车辆属性检查钥匙。与另一个答案所说的完全相同,但这里更详细。我认为你问题的关键是“告诉我如何添加限制”。这就是我的解释 您需要将每个限制解码到它自己的字段中 您需要知道每个字段的Java实体属性名称 然后构建这两件事的映射,关键是已知的静态Java实体属性名,值是URL解码数据(可能有类型转换)
私有映射查询参数;
私家车名单;
激活时无效(事件上下文){
//计数为6-品牌/福特/车型/焦点/年份/2009
int count=context.getCount();
queryParameters=newHashMap();
如果(计数>0){
int i;
对于(i=0;(i+1)
另见
使用上述方法,应该不会有SQL注入的风险,因为“name”和“n”部分应该根据已知的良好列表进行100%验证。“value”和“v”被正确转义,就像使用SQL位置占位符“?”一样
E&OE与另一个答案所说的一模一样,但这里更详细。我认为你问题的关键是“告诉我如何添加限制”。这就是我的解释 您需要将每个限制解码到它自己的字段中 您需要知道每个字段的Java实体属性名称 然后构建这两件事的映射,关键是已知的静态Java实体属性名,值是URL解码数据(可能有类型转换)
私有映射查询参数;
私家车名单;
激活时无效(事件上下文){
//计数为6-品牌/福特/车型/焦点/年份/2009
int count=context.getCount();
queryParameters=newHashMap();
如果(计数>0){
int i;
对于(i=0;(i+1)private Map<String, Object> queryParameters;
private List<Vehicle> vehicles;
void onActivate(EventContext context) {
//Count is 6 - make/ford/model/focus/year/2009
int count = context.getCount();
queryParameters = new HashMap<String,Object>();
if (count > 0) {
int i;
for (i = 0; (i + 1) < count; i += 2) {
String name = context.get(String.class, i);
String value = context.get(String.class, i + 1);
Object sqlValue = value;
if("foobar".equals(name)) {
// sometime you don't want a String type for SQL compasition
// so convert it
sqlValue = UtilityClass.doTypeConversionForFoobar(value);
} else if("search".equals(name) ||
"model".equals(name) ||
"year".equals(name)) {
// no-op this is valid 'name'
} else if("make".equals(name)) {
// this is a suggestion depends on your project conf
name = "vehicleMake.name";
} else {
continue; // ignore values we did not expect
}
// FIXME: You should validate all 'name' values
// to be valid and/or convert to Java property names here
System.out.println("name " + name);
System.out.println("value " + value);
this.queryParameters.put(name, sqlValue);
}
}
Criteria crit = this.session.createCriteria(Vehicle.class)
for(Map.Entry<String,Object> e : this.queryParameters.entrySet()) {
String n = e.getKey();
Object v = e.getValue();
// Sometimes you don't want a direct compare 'Restructions.eq()'
if("search".equals(n))
crit.add(Restrictions.like(n, "%" + v + "%"));
else // Most of the time you do
crit.add(Restrictions.eq(n, v));
}
this.vehicles = crit.list(); // run query
}
Vehicle vehicle = new Vehicle();
int count = context.getCount();
int i;
for (i = 0; (i + 1) < count; i += 2) {
String name = context.get(String.class, i);
String value = context.get(String.class, i + 1);
// This will call the setter for the name, passing the value
// So if name is 'make' and value is 'ford', it will call vehicle.setMake('ford')
BeantUtils.setProperty(vehicle, name, value);
}
// This is using a Hibernate example query:
vehicles = session.createCriteria(Vehicle.class).add(Example.create(vehicle)).list();
public class Vehicles {
@ActivationRequestParameter
private String make;
@ActivationRequestParameter
private String model;
@ActivationRequestParameter
private String year;
@Inject
private Session session;
@OnEvent(EventConstants.ACTIVATE)
void activate() {
Criteria criteria = session.createCriteria(Vehicle.class);
if (make != null) criteria.add(Restrictions.eq("make", make));
if (model != null) criteria.add(Restrictions.eq("model", model));
if (year != null) criteria.add(Restrictions.eq("year", year));
vehicles = criteria.list();
}
public class Vehicles {
@ActivationRequestParameter
private String make;
@ActivationRequestParameter
private String model;
@ActivationRequestParameter
private String year;
@Inject
private Session session;
@OnEvent(EventConstants.ACTIVATE)
void activate() {
}
public GridDataSource getVehicles() {
return new HibernateGridDataSource(session, Vehicles.class) {
@Override
protected void applyAdditionalConstraints(Criteria criteria) {
if (make != null) criteria.add(Restrictions.eq("make", make));
if (model != null) criteria.add(Restrictions.eq("model", model));
if (year != null) criteria.add(Restrictions.eq("year", year));
}
};
}
}