开发基于ssm框架的平台,由于系统涉及的对象,实体多,数据表非常复杂,通过传统的mybatis generator创建相应的mapper,dao,entity的方式固然可行,但是代码不够简洁不够高效,修改一处之后需要重新生成相应的一整套文件,用了统一的,通用的dao层操作接口,全过程只需要提供mapper(xml),其他都直接调用接口即可。
首先是,dao层的接口,配置了所用到的基本操作:
public interface DAO {
/**
* 保存对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object save(String str, Object obj) throws Exception;
/**
* 修改对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object update(String str, Object obj) throws Exception;
/**
* 删除对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object delete(String str, Object obj) throws Exception;
/**
* 查找对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object findForObject(String str, Object obj) throws Exception;
/**
* 查找对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object findForList(String str, Object obj) throws Exception;
/**
* 查找对象封装成Map
* @param s
* @param obj
* @return
* @throws Exception
*/
public Object findForMap(String sql, Object obj, String key , String value) throws Exception;
}
接下来,通过spring的依赖注入,注入sqlSessionTemplate模板,实现dao接口,操作都是通用的:
@Repository("commondaoSupport")
public class CommonDaoSupport implements DAO {
@Resource(name = "sqlSessionTemplate")
private SqlSessionTemplate sqlSessionTemplate;
/**
* 保存对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object save(String str, Object obj) throws Exception {
return sqlSessionTemplate.insert(str, obj);
}
/**
* 批量更新
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object batchSave(String str, List<?> objs )throws Exception{
return sqlSessionTemplate.insert(str, objs);
}
/**
* 修改对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object update(String str, Object obj) throws Exception {
return sqlSessionTemplate.update(str, obj);
}
/**
* 批量更新
* @param str
* @param obj
* @return
* @throws Exception
*/
public void batchUpdate(String str, List<?> objs )throws Exception{
SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
//批量执行器
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
try{
if(objs!=null){
for(int i=0,size=objs.size();i<size;i++){
sqlSession.update(str, objs.get(i));
}
sqlSession.flushStatements();
sqlSession.commit();
sqlSession.clearCache();
}
}finally{
sqlSession.close();
}
}
/**
* 批量更新
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object batchDelete(String str, List<?> objs )throws Exception{
return sqlSessionTemplate.delete(str, objs);
}
/**
* 删除对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object delete(String str, Object obj) throws Exception {
return sqlSessionTemplate.delete(str, obj);
}
/**
* 查找对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object findForObject(String str, Object obj) throws Exception {
return sqlSessionTemplate.selectOne(str, obj);
}
/**
* 查找对象
* @param str
* @param obj
* @return
* @throws Exception
*/
public Object findForList(String str, Object obj) throws Exception {
return sqlSessionTemplate.selectList(str, obj);
}
public Object findForMap(String str, Object obj, String key, String value) throws Exception {
return sqlSessionTemplate.selectMap(str, obj, key);
}
}
经过简单的封装之后,接下来为Service接口提供一个简单的基类,这里只是简单的注入了dao接口对象,也可以自行对该基类的Service做一些增强的功能:
public class BaseService {
@Resource(name = "commondaoSupport")
protected CommonDaoSupport dao;
}
上面的步骤之后,还必须做的一个操作就是实体类,实体类还是需要声明的,那这个时候为了更加简洁,实体类也可以不用写(会造成无法知道字段信息,可能有些人会觉得有点不方便),我们用Map对象来存放所有dao操作的入参和结果映射,这个增强了map的功能,可以将request提交的信息提取到map对象中:
public class Kvmap extends HashMap implements Map{
private static final long serialVersionUID = 1L;
Map map = null;
HttpServletRequest request;
public Kvmap(HttpServletRequest request){
this.request = request;
Map properties = request.getParameterMap();
Map returnMap = new HashMap();
Iterator entries = properties.entrySet().iterator();
Map.Entry entry;
String name = "";
String value = "";
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if(null == valueObj){
value = "";
}else if(valueObj instanceof String[]){
String[] values = (String[])valueObj;
for(int i=0;i<values.length;i++){
value = values[i] + ",";
}
value = value.substring(0, value.length()-1);
}else{
value = valueObj.toString();
}
returnMap.put(name, value);
}
map = returnMap;
}
public Kvmap() {
map = new HashMap();
}
@Override
public Object get(Object key) {
Object obj = null;
if(map.get(key) instanceof Object[]) {
Object[] arr = (Object[])map.get(key);
obj = request == null ? arr:(request.getParameter((String)key) == null ? arr:arr[0]);
} else {
obj = map.get(key);
}
return obj;
}
public String getString(Object key) {
String str = null;
if(key instanceof String){
str = (String) key;
str = str.toUpperCase();
return (String)get(str);
}
return (String)get(key);
}
@SuppressWarnings("unchecked")
@Override
public Object put(Object key, Object value) {
String str = null;
if(key instanceof String){
str = (String) key;
str = str.toUpperCase();
return map.put(str, value);
}
return map.put(key, value);
}
@Override
public Object remove(Object key) {
return map.remove(key);
}
public void clear() {
map.clear();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public Set entrySet() {
return map.entrySet();
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set keySet() {
return map.keySet();
}
@SuppressWarnings("unchecked")
public void putAll(Map t) {
map.putAll(t);
}
public int size() {
return map.size();
}
public Collection values() {
return map.values();
}
}
这样就完成了一大半,接下来我们只要提供mapper,编写我们需要的数据库语句,将参数和结果都设置成Kvmap对象,Service类都继承Service基类并使用dao层进行数据的持久化操作,这样可以达到我们的目的啦。
这里只是简单地写一下思想,大家在实际使用过程中可以根据自己的需求,增加相应的功能,改造成自己适用的工具类,大大减少了代码量和修改时产生工作量。
多交流,多学习,多讨论~