Java 使用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

我正在使用Tapestry5和Hibernate。我正在尝试构建一个使用从URL生成的动态限制的条件查询。我的URL上下文被设计成一个键/值对

范例

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));
            }
        };
    }
}