一种通用的DAO访问方法

在SpringMVC开发过程中各个层级需要编写大量重复代码,解决方法有三:其一、粘贴复制,似乎不少人这么干;其二,通过代码生成工具,设置变量替换大量文件;其三,构建通用方法实现代码复用。写者疲于复制,没有采用第一种,没有现成好的模板没有采用第二种,于是,通过第三种方法构建通用访问方式。


要点考虑

通用方法必须考虑的几点:通用到何种程度,通用到哪个级别如何控制相应层次,如何解决不同实体的差异访问以及如何进行通用代码的差异访问(此问题主要是后期功能查询的要求)。
考虑之后,决定通过以下方式实现访问通用性:

  • 通过工具类完成参数与语句对照转化;
  • 通过底层接口控制实体调用方法;
  • 通过抽象类实现基础操作;
  • 根据业务不断进行底层封装与抽象。

代码实现

  • 初步定义的抽象接口,为抽象类提供约束,参数传递使用FastJson的JSONObject对象

package cn.cnic.datapub.general;

import java.util.List;

import com.alibaba.fastjson.JSONObject;

public interface IGeneralDAO<T>

{

 public T findById(Object id);

 public List<T> findByParams(JSONObject json);

 public List<T> findAll();

 public boolean add(T model);

 public boolean delete(T model);

 public boolean deleteById(Object id);

 public boolean modify(T model);

 public boolean modifyById(Object id,T model);

 public int count();

}

  • 按照抽象接口通过抽象类完成共性操作

package cn.cnic.datapub.general;

import java.lang.reflect.ParameterizedType;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.jdbc.core.BeanPropertyRowMapper;

import org.springframework.jdbc.core.JdbcTemplate;

import cn.cnic.datapub.util.ParamTransfer;

import com.alibaba.fastjson.JSONObject;

public abstract class AbstractDAO<T> implements IGeneralDAO<T>

{

 @Resource

 JdbcTemplate jdbcTemplate;

 private String tablename;

 public T findByIdTest(Object id)

 {

 T t = null;

 if(id!=null)

 {

 String sql = "select * from "+getTablename()+" where id=?";

 t = this.jdbcTemplate.queryForObject(sql,new Object[]{id}, new BeanPropertyRowMapper<T>(getTClass()));

 }

 return t;

 }

 @Override

 public T findById(Object id)

 {

 T t = null;

 if(id!=null)

 {

 String sql = "select * from "+getTablename()+" where id=?";

 t = this.jdbcTemplate.queryForObject(sql,new Object[]{id}, new BeanPropertyRowMapper<T>(getTClass()));

 }

 return t;

 }

 @Override

 public List<T> findByParams(JSONObject json)

 {

 Object[] params = ParamTransfer.paramsAnalyseSQL(json);

 if(params[0]!=null&&params[1]!=null)

 {

 String sql = " select * from "+getTablename()+" where "+params[0];

 return this.jdbcTemplate.query(sql,(Object[])params[1],new BeanPropertyRowMapper<T>(getTClass()));

 }

 else

 {

 return findAll();

 }

 }

 @Override

 public boolean add(T model)

 {

 if(model!=null)

 {

 JSONObject jmodel = JSONObject.parseObject(model.toString());

 Object[] params = ParamTransfer.paramsAnalyseAddSQLWithoutNull(jmodel);

 if(params[0]!=null&&params[1]!=null)

 {

 int count = ((Object[])params[1]).length;

 StringBuilder paramsb = new StringBuilder();

 for(int i=0;i<count-1;i++)

 {

 paramsb.append("?,");

 }

 paramsb.append("?");

 String sql = "insert into "+getTablename()+"("+params[0]+") values("+paramsb+")";

 int result = this.jdbcTemplate.update(sql,(Object[])params[1]);

 if(result>=1)

 {

 return true;

 }

 }

 }

 return false;

 }

 @Override

 public boolean delete(T model)

 {

 if(model!=null)

 {

 JSONObject jmodel = JSONObject.parseObject(model.toString());

 return deleteById(jmodel.get("id"));

 }

 else

 {

 return false;

 }

 }

 @Override

 public boolean deleteById(Object id)

 {

 if(id!=null)

 {

 String sql = "delete from "+getTablename()+" where id=?";

 int num = this.jdbcTemplate.update(sql,new Object[]{id});

 if(num>0)return true;

 else return false;

 }

 else

 {

 return false;

 }

 }

 @Override

 public boolean modify(T model)

 {

 if(model!=null)

 {

 JSONObject jmodel = JSONObject.parseObject(model.toString());

 Object[] params = ParamTransfer.paramsAnalyseUpdateSQL(jmodel);

 if(params[0]!=null&&params[1]!=null)

 {

 String sql = "update "+getTablename()+" set "+params[0]+" where id=?";

 int num = this.jdbcTemplate.update(sql,(Object[])params[1]);

 if(num>0)return true;

 }

 }

 return false;

 }

 @Override

 public boolean modifyById(Object id, T model)

 {

 if(id!=null)

 {

 JSONObject jmodel = JSONObject.parseObject(model.toString());

 Object[] params = ParamTransfer.paramsAnalyseUpdateSQLWithId(jmodel,id);

 String sql = "update "+getTablename()+" set "+params[0]+" where id=?";

 int num = this.jdbcTemplate.update(sql,(Object[])params[1]);

 if(num>0)return true;

 else return false;

 }

 else

 {

 return false;

 }

 }

 @Override

 public List<T> findAll()

 {

 String sql = " select * from "+getTablename()+" ";

 return this.jdbcTemplate.query(sql,new Object[]{},new BeanPropertyRowMapper<T>(getTClass()));

 }

 @Override

 public int count()

 {

 String sql = " select count(*) from "+getTablename()+" ";

 return this.jdbcTemplate.queryForObject(sql,new Object[]{},Integer.class);

 }

 @SuppressWarnings("unchecked")

 public Class<T> getTClass()

 {

 Class<T> tClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

 return tClass;

 }

 public String getTablename()

 {

 return tablename;

 }

 public void setTablename(String tablename)

 {

 this.tablename = tablename;

 }

}


  • 操作中按照不同方式进行组合的工具类
package cn.cnic.datapub.util;

import java.util.ArrayList;

import java.util.List;

import com.alibaba.fastjson.JSONObject;

public class ParamTransfer

{

 public static Object[] paramsAnalyseSQL(JSONObject params)

 {

 if(params!=null)

 {

 List<String> names = new ArrayList<String>();

 List<Object> values = new ArrayList<Object>();

 for(String key:params.keySet())

 {

 names.add(key);

 values.add(params.get(key));

 }

 StringBuilder sb = new StringBuilder();

 for(int i=0;i<names.size()-1;i++)

 {

 sb.append(names.get(i)+"=? and ");

 }

 sb.append(names.get(names.size()-1)+"=? ");

 return new Object[]{sb.toString(),values.toArray()};

 }

 else

 {

 return new Object[]{null,null};

 }

 }

 public static Object[] paramsAnalyseAddSQL(JSONObject params)

 {

 if(params!=null)

 {

 List<String> names = new ArrayList<String>();

 List<Object> values = new ArrayList<Object>();

 for(String key:params.keySet())

 {

 if(!key.equals("id"))

 {

 names.add(key);

 values.add(params.get(key));

 }

 }

 StringBuilder sb = new StringBuilder();

 for(int i=0;i<names.size()-1;i++)

 {

 sb.append(names.get(i)+", ");

 }

 sb.append(names.get(names.size()-1)+" ");

 return new Object[]{sb.toString(),values.toArray()};

 }

 else

 {

 return new Object[]{null,null};

 }

 }

 public static Object[] paramsAnalyseAddSQLWithoutNull(JSONObject params)

 {

 if(params!=null)

 {

 List<String> names = new ArrayList<String>();

 List<Object> values = new ArrayList<Object>();

 for(String key:params.keySet())

 {

 Object value = params.get(key);

 if(value!=null&&!value.toString().equals("")&&!key.equals("id"))

 {

 names.add(key);

 values.add(params.get(key));

 }

 }

 StringBuilder sb = new StringBuilder();

 for(int i=0;i<names.size()-1;i++)

 {

 sb.append(names.get(i)+", ");

 }

 sb.append(names.get(names.size()-1)+" ");

 System.out.println(params);

 System.out.println(names);

 System.out.println(values);

 return new Object[]{sb.toString(),values.toArray()};

 }

 else

 {

 return new Object[]{null,null};

 }

 }

 public static Object[] paramsAnalyseUpdateSQL(JSONObject params)

 {

 if(params!=null)

 {

 List<String> names = new ArrayList<String>();

 List<Object> values = new ArrayList<Object>();

 Object id = null;

 for(String key:params.keySet())

 {

 if(!key.equals("id"))

 {

 names.add(key);

 values.add(params.get(key));

 }

 else

 {

 id=params.get("id");

 }

 }

 StringBuilder sb = new StringBuilder();

 for(int i=0;i<names.size()-1;i++)

 {

 sb.append(names.get(i)+"=?, ");

 }

 sb.append(names.get(names.size()-1)+"=? ");

 values.add(id);

 return new Object[]{sb.toString(),values.toArray()};

 }

 else

 {

 return new Object[]{null,null};

 }

 }

 public static Object[] paramsAnalyseUpdateSQLWithId(JSONObject params,Object id)

 {

 if(params!=null)

 {

 List<String> names = new ArrayList<String>();

 List<Object> values = new ArrayList<Object>();

 for(String key:params.keySet())

 {

 names.add(key);

 values.add(params.get(key));

 }

 StringBuilder sb = new StringBuilder();

 for(int i=0;i<names.size()-1;i++)

 {

 sb.append(names.get(i)+"=?, ");

 }

 sb.append(names.get(names.size()-1)+"=? ");

 values.add(id);

 return new Object[]{sb.toString(),values.toArray()};

 }

 else

 {

 return new Object[]{null,null};

 }

 }

}


  • 在实现时,仅需要提供数据库中table的名称即可
package cn.cnic.datapub.job.manager;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.stereotype.Repository;

import cn.cnic.datapub.general.AbstractDAO;

@Repository(value="parseDataDAO")

public class ParseDataDAO extends AbstractDAO<ParseDataM>

{

 @Resource

 JdbcTemplate jdbcTemplate;

 public ParseDataDAO()

 {

 setTablename("job_sub_parse");

 }

}


  • 在实体层可根据自己业务需要构建代码即可,需要注意实现toJSONString方法完成到Json的转换过程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么我们要使用通用DAO接口呢,因为我们的数据库操作无非是增删改查,CRUD操作,我们不需要为每个实体去编写一个dao接口,对于相似的实体操作可以只编写一个通用接口,然后采用不同的实现DAO已经成为持久层的标准模式,DAO使结构清晰,面向接口编程为代码提供了规范。而泛型DAO是一个类型安全的,代码精简的设计模式(相对于传统DAO),尤其在DAO组件数量庞大的时候,代码量的减少更加明显。 泛型DAO的核心是定义一个GenericDao接口,声明基本的CRUD操作: 用hibernate作为持久化解决方案的GenericHibernateDao实现类,被定义为抽象类,它提取了CRUD操作,这就是简化代码的关键,以便于更好的重用,这个就不给例子了,增删改都好写,查就需要各种条件了。 然后是各个领域对象的dao接口,这些dao接口都继承GenericDao接口,这样各个领域对象的dao接口就和传统dao接口具有一样的功能了。 下一步是实现类了,个自领域对象去实现各自的接口,还要集成上面的抽象类,这样就实现了代码复用的最大化,实现类中只需要写出额外的查询操作就可以了。当然还要获得域对象的Class实例,这就要在构造方法传入Class实例。用spring提供的HibernateTemplate注入到GenericHibernateDao中,这样在各个实现类就可以直接调用HibernateTemplate来实现额外的查询操作了。 如果在实现类中不想调用某个方法(例如:update()),就可以覆盖它,方法中抛出UnsupportedOperationException()异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值