如何编写搜索类来接受任何类型的参数?

时间:2012-08-11 05:02:06

标签: spring

我正在使用spring mvc,我创建了CRUD功能。但是我想创建一个搜索功能,允许我通过任何参数(变量)找到用户'userid'或'username'或'lastname'或'social security number'或者其他什么。

我的用户ID是整数类型。

我该怎么做?那个SQL查询是什么?

如何检查输入是整数还是字符串,然后通过给定参数遍历数据库并搜索用户?

1 个答案:

答案 0 :(得分:1)

如果您使用Hibernate进行数据访问,则可以使用条件API轻松创建通用查找器:

抽象DAO类:

public abstract class AbstractHibernateDAO<T> {

    private static final String PARAM_VALUE_PARAMETER = "paramValue";

    private final Class<T> clazz;

    @Autowired
    private SessionFactory sessionFactory;

    public AbstractHibernateDAO(Class<T> clazz) {
        this.clazz = clazz;
    }

    public T findOne(String paramName, Object paramValue) {
        Session session = sessionFactory.getCurrentSession();

        @SuppressWarnings("unchecked")
        T fetchedObject = (T) session.createCriteria(clazz).add(Restrictions.eq(paramName, paramValue)).uniqueResult();

        return fetchedObject;
    }

    // Other CRUD methods.

}

实体的具体DAO类:

@Repository
@Transactional
public class ProductHibernateDAO extends AbstractHibernateDAO<Product> {

    public ProductHibernateDAO() {
        super(Product.class);
    }

}

或者,如果您更喜欢使用HQL而不是Criteria API,则可以将搜索方法重写为:

public T findOne(String paramName, Object paramValue) {
    Session session = sessionFactory.getCurrentSession();

    StringBuilder queryText = new StringBuilder();

    queryText.append("from ");
    queryText.append(clazz.getSimpleName());
    queryText.append(" where ");
    queryText.append(paramName);
    queryText.append("=:");
    queryText.append(PARAM_VALUE_PARAMETER);

    @SuppressWarnings("unchecked")
    T fetchedObject = (T) session.createQuery(queryText.toString()).setParameter(PARAM_VALUE_PARAMETER, paramValue).uniqueResult();

    return fetchedObject;
}

In this article你可以找到很好的描述如何使用hibernate创建通用DAO(或者如果你更喜欢JPA,还有如何用JPA来描述它。)

或者如果您更喜欢使用JDBC进行数据访问,我建议您查看Spring的JdbcTemplate。它简化了开发过程。在这里,您可以使用JdbcTemplate实现通用查找器:

@Repository
@Transactional
public class ProductJDBCDAO implements DAO<Product> {

    private static final String TABLE_NAME = "product";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Product findOne(String paramName, Object paramValue) {
        RowMapper<Product> rowMapper = new RowMapper<Product>(){

            public Product mapRow(ResultSet rs, int rowNum) throws SQLException {

                long productId = rs.getLong("product_id");
                // Other properties

                Product product = new Product(...);

                return product;
            }

        };

        StringBuilder queryText = new StringBuilder();
        queryText.append("select * from ");
        queryText.append(TABLE_NAME);
        queryText.append(" where ");
        queryText.append(paramName);
        queryText.append("=?");

        Product fetchedObject = jdbcTemplate.queryForObject(queryText.toString(), rowMapper, paramValue);

        return fetchedObject;
    }


    // Other CRUD methods
}

您可以在所有示例中看到,您不需要显式指定参数类型,只需将其添加为Object参数即可。

如果您在这种情况下使用直接JDBC,我建议您使用 PreparedStatement 并使用 setObject(..)方法。查询文本将与使用JdbcTemplate的示例中显示的类似。