在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&¶ms[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&¶ms[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&¶ms[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的转换过程。