データアクセスに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);
}
}
または、Criteria APIの代わりにHQLを使用する場合は、検索メソッドを次のように書き直すことができます。
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;
}
この記事では、休止状態を使用して汎用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
}
すべての例でわかるように、パラメータタイプを明示的に指定する必要はなく、オブジェクトパラメータとして追加するだけです。
このような場合に直接JDBCを使用する場合は、PreparedStatementとそのsetObject(..)メソッドを使用することをお勧めします。クエリテキストは、JdbcTemplateの例に示されているものと同様になります。