将方法转换为 DAO 层中的泛型方法
Convert methods to a generic method in DAO layer
目前我的 DAO 层中有一些方法有多个 select 查询。我在想的是为所有这三种方法提供一个通用方法,以便它也可以用于进一步的用途。这是我的方法。
public List<Customer> findAll(){
String sql = "SELECT * FROM CUSTOMER";
List<Customer> customers = getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(Customer.class));
return customers;
}
用于查找客户的 phone 个号码。
public List<Phone> findPhoneNumbers(int custId){
String sql = "SELECT * FROM PHONE WHERE CUST_ID="+custId;
List<Phone> phoneNumbers = getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(Phone.class));
return phoneNumbers;
}
等等。
能否将这些方法转换为单个泛型方法,以便从我的服务层调用它。任何建议或想法将不胜感激。
你可以使用继承来实现这个
1) class Customer
2)class PhoneNumber extends Customer
3) class Address extends Customer
4) 将方法声明为
public List<T> findPhoneNumbers(Customer customer){
if(customer instanceOf PhoneNumber) {sql ="get phone number query ...."}
else if(customer instanceOf Address) {sql ="get address query ...."}
else {sql = get customer query}
}
现在在调用方法(ServiceLayer)中,您可以传递适当的对象来选择查询并获取结果
您可以使用通用方法并让调用者指定 class。
findAll
很容易
public <T> List<T> findAll(Class<T> entityClass, String tableName){
String sql = "SELECT * FROM " + tableName;
return getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(entityClass));
return phoneNumbers;
}
您可以使用 class 元数据进一步改进这一点,例如指定注释:
@Target(ElementType.Type)
public @interface MappedTable {
String tableName();
}
//apply the annotation to bean classes:
@MappedTable(tableName="CUSTOMERS")
public class Customer {}
这将使您的 findAll
方法看起来像:
public <T> List<T> findAll(Class<T> entityClass){
String sql = "SELECT * FROM " + entityClass
.getAnnotation(MappedTable.class).tableName();
return getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(entityClass));
return phoneNumbers;
}
实施 findByXyZ
会比较棘手,但您可以使用类似的方法,从调用方获取完整查询或使用额外的基于注释的元数据。
注意这种代码的复杂度增长得非常快。这就是为什么考虑使用 ORM 工具而不是重新发明它们是一个好主意(以上只是针对问题中的简单案例的想法)。
public <T> List<T> findAll(String sql, Class<T> clazz) {
return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
}
那你打电话
String sql = "SELECT * FROM CUSTOMER";
List<Customer> customers = findAll(sql, Customer.class);
或
String sql = "SELECT * FROM PHONE WHERE CUST_ID="+custId;
List<Phone> phoneNumbers = findAll(sql, Phone.class);
问题是您必须在调用该方法之前构造 sql 语句。
也许您想要一个 android sql 类似数据库的接口并在方法中构造 sql 语句。
public <T> List<T> findAll(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, Class<T> clazz) {
String sql = // construct sql statement
return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
}
我不熟悉 sql 声明,您可能会在 Android SDK SQLiteQueryBuilder.buildQueryString(...)
.
中找到一些内容
如果你真的想要 return 单个项目而不是包含一个项目的列表,你需要另一种方法。
public <T> T findOne(String sql, Class<T> clazz) {
// your sql statement should contains something like "limit 1"
List<T> result = findAll(sql, clazz);
return result.isEmpty() ? null : result.get(0);
}
如果您需要一种方法,但您需要 return List<T>
用于多个数据,T
用于单个数据。试试这个:
public <T> Object findAll(String sql, Class<T> clazz, bool one) {
List<T> all = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
return one ? all.get(0) : all;
}
但我真的不建议使用这种方法。我认为没有必要 return 单个项目而不是包含单个项目的列表。
目前我的 DAO 层中有一些方法有多个 select 查询。我在想的是为所有这三种方法提供一个通用方法,以便它也可以用于进一步的用途。这是我的方法。
public List<Customer> findAll(){
String sql = "SELECT * FROM CUSTOMER";
List<Customer> customers = getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(Customer.class));
return customers;
}
用于查找客户的 phone 个号码。
public List<Phone> findPhoneNumbers(int custId){
String sql = "SELECT * FROM PHONE WHERE CUST_ID="+custId;
List<Phone> phoneNumbers = getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(Phone.class));
return phoneNumbers;
}
等等。
能否将这些方法转换为单个泛型方法,以便从我的服务层调用它。任何建议或想法将不胜感激。
你可以使用继承来实现这个
1) class Customer
2)class PhoneNumber extends Customer
3) class Address extends Customer
4) 将方法声明为
public List<T> findPhoneNumbers(Customer customer){
if(customer instanceOf PhoneNumber) {sql ="get phone number query ...."}
else if(customer instanceOf Address) {sql ="get address query ...."}
else {sql = get customer query}
}
现在在调用方法(ServiceLayer)中,您可以传递适当的对象来选择查询并获取结果
您可以使用通用方法并让调用者指定 class。
findAll
public <T> List<T> findAll(Class<T> entityClass, String tableName){
String sql = "SELECT * FROM " + tableName;
return getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(entityClass));
return phoneNumbers;
}
您可以使用 class 元数据进一步改进这一点,例如指定注释:
@Target(ElementType.Type)
public @interface MappedTable {
String tableName();
}
//apply the annotation to bean classes:
@MappedTable(tableName="CUSTOMERS")
public class Customer {}
这将使您的 findAll
方法看起来像:
public <T> List<T> findAll(Class<T> entityClass){
String sql = "SELECT * FROM " + entityClass
.getAnnotation(MappedTable.class).tableName();
return getJdbcTemplate().query(sql,
new BeanPropertyRowMapper(entityClass));
return phoneNumbers;
}
实施 findByXyZ
会比较棘手,但您可以使用类似的方法,从调用方获取完整查询或使用额外的基于注释的元数据。
注意这种代码的复杂度增长得非常快。这就是为什么考虑使用 ORM 工具而不是重新发明它们是一个好主意(以上只是针对问题中的简单案例的想法)。
public <T> List<T> findAll(String sql, Class<T> clazz) {
return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
}
那你打电话
String sql = "SELECT * FROM CUSTOMER";
List<Customer> customers = findAll(sql, Customer.class);
或
String sql = "SELECT * FROM PHONE WHERE CUST_ID="+custId;
List<Phone> phoneNumbers = findAll(sql, Phone.class);
问题是您必须在调用该方法之前构造 sql 语句。
也许您想要一个 android sql 类似数据库的接口并在方法中构造 sql 语句。
public <T> List<T> findAll(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, Class<T> clazz) {
String sql = // construct sql statement
return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
}
我不熟悉 sql 声明,您可能会在 Android SDK SQLiteQueryBuilder.buildQueryString(...)
.
如果你真的想要 return 单个项目而不是包含一个项目的列表,你需要另一种方法。
public <T> T findOne(String sql, Class<T> clazz) {
// your sql statement should contains something like "limit 1"
List<T> result = findAll(sql, clazz);
return result.isEmpty() ? null : result.get(0);
}
如果您需要一种方法,但您需要 return List<T>
用于多个数据,T
用于单个数据。试试这个:
public <T> Object findAll(String sql, Class<T> clazz, bool one) {
List<T> all = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
return one ? all.get(0) : all;
}
但我真的不建议使用这种方法。我认为没有必要 return 单个项目而不是包含单个项目的列表。