srm smartDao
来源:互联网 发布:英雄无敌6加点 知乎 编辑:程序博客网 时间:2024/05/16 10:28
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.config.ConfigurationException;
import org.nutz.castor.Castors;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import com.fujitsu.cn.fnst.framework.dao.BaseDao;
import com.fujitsu.cn.fnst.framework.smartdao.annotation.Arguments;
import com.fujitsu.cn.fnst.framework.smartdao.annotation.Hql;
import com.fujitsu.cn.fnst.framework.smartdao.annotation.Sql;
import com.fujitsu.cn.fnst.framework.util.FreemarkerParseFactory;
import com.fujitsu.cn.fnst.framework.util.ReflectUtils;
import com.fujitsu.cn.fnst.framework.util.SmartDaoUtil;
/**
* 智能Dao自动代理类处理器 The Class SmartDaoInterceptor.<br>
*
* @author FNST)韋 燦楽
* @version 0.1
*/
public class SmartDaoInterceptor implements MethodInterceptor {
private static final Logger logger = Logger.getLogger(SmartDaoInterceptor.class);
private JdbcTemplate jdbcTemplate;
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private BaseDao baseDao;
private boolean showsql;
private LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
public SmartDaoInterceptor() {
}
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
// 如果是代理类,就需要获取代理。getThis会取到null
Object srcObj;
if (methodInvocation instanceof ReflectiveMethodInvocation) {
srcObj = ((ReflectiveMethodInvocation) methodInvocation).getProxy();
} else {
srcObj = methodInvocation.getThis();
}
Method method = methodInvocation.getMethod();
Object args[] = methodInvocation.getArguments();
Object returnObj = null;
String templateSql = null;
Map<String, Object> sqlParamsMap = new HashMap<String, Object>();
if (!SmartDaoUtil.isAbstract(method))
return methodInvocation.proceed();
Map<String, Object> rs = new HashMap<String, Object>();
// BaseDao接口中的方法,由BaseDaoImpl处理
if (processWithBaseDao(srcObj, rs, method, args)) {
return rs.get("returnObj");
}
// 非BaseDao接口的方法
else {
templateSql = setupSqlAndParam(srcObj, method, sqlParamsMap, args);
String executeSql = parseSqlTemplate(method, templateSql, sqlParamsMap);
returnObj = getReturnResult(method, executeSql, sqlParamsMap);
return returnObj;
}
}
/**
* BaseDao接口中的方法,由BaseDaoImpl处理
*
* @param rs
* 运行结果
* @param method
* 方法
* @param args
* 方法参数
* @return 是否使用BaseDao进行处理
*/
private boolean processWithBaseDao(Object src, Map<String, Object> rs, Method method,
Object args[]) {
Class clz2 = null;
try {
Type genType = src.getClass().getInterfaces()[0].getGenericInterfaces()[0];
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
clz2 = (Class) params[0];
} catch (Exception e) {
logger.warn("didn't set the ParameterizedType of BaseDao");
}
String methodName = method.getName();
if ("getHibernateTemplate".equals(methodName)) {
rs.put("returnObj", baseDao.getHibernateTemplate());
return true;
}
if ("save".equals(methodName)) {
baseDao.save(args[0]);
return true;
}
if ("update".equals(methodName)) {
baseDao.update(args[0]);
return true;
}
if ("saveOrUpdate".equals(methodName)) {
baseDao.saveOrUpdate(args[0]);
return true;
}
if ("delete".equals(methodName)) {
baseDao.delete(args[0]);
return true;
}
if ("deleteEntityById".equals(methodName)) {
if (args.length > 1) {
Class<?> clz = (Class<?>) args[0];
baseDao.deleteEntityById(clz, (Serializable) args[1]);
} else {
baseDao.deleteEntityById(clz2, (Serializable) args[0]);
}
return true;
}
if ("get".equals(methodName)) {
if (args.length > 1) {
Class<?> clz = (Class<?>) args[0];
rs.put("returnObj", baseDao.get(clz, (Serializable) args[1]));
} else {
rs.put("returnObj", baseDao.get(clz2, (Serializable) args[0]));
}
return true;
}
if ("getByExample".equals(methodName)) {
rs.put("returnObj", baseDao.getByExample(args[0]));
return true;
}
if ("listAll".equals(methodName)) {
if (args.length > 0) {
Class<?> clz = (Class<?>) args[0];
rs.put("returnObj", baseDao.listAll(clz));
} else {
rs.put("returnObj", baseDao.listAll(clz2));
}
return true;
}
return false;
}
/**
* 用Freemarker解析SQL模版
*
* @param method
* 方法
* @param templateSql
* SQL模版
* @param sqlParamsMap
* SQL参数
* @return
*/
private String parseSqlTemplate(Method method, String templateSql,
Map<String, Object> sqlParamsMap) {
String executeSql = null;
if (StringUtils.isNotEmpty(templateSql)) {
executeSql = (new FreemarkerParseFactory()).parseTemplateContent(templateSql,
sqlParamsMap);
} else {
// TODO sql maker ?
}
logger.debug("SmartDao-execute sql:\n" + executeSql + "\n");
if (showsql) {
System.out.println("SmartDao-execute sql:\n" + executeSql + "\n");
}
return executeSql;
}
/**
* 执行SQL,获取结果
*
* @param method
* @param executeSql
* @param paramMap
* @return
*/
private Object getReturnResult(Method method, String executeSql, Map<String, Object> paramMap) {
// 指定@Hql注解的方法,通过Hibernate执行HQL
if (method.isAnnotationPresent(Hql.class)) {
if (paramMap != null && !paramMap.isEmpty()) {
String[] allParamNames = paramMap.keySet().toArray(new String[0]);
List<String> paramNames = new ArrayList<String>();
List<Object> paramValues = new ArrayList<Object>();
for (String paramName : allParamNames) {
Object parmaValue = paramMap.get(paramName);
// 值为null的参数过滤掉不传递给Hibernate,否则Hibernate会报错;
// 但是同时需要保证传给Hibernate的SQL里面也应该没有这个参数,比如:userName
if (parmaValue != null) {
paramNames.add(paramName);
paramValues.add(parmaValue);
}
}
return baseDao.getHibernateTemplate().findByNamedParam(executeSql,
paramNames.toArray(new String[0]), paramValues.toArray(new Object[0]));
} else {
return baseDao.getHibernateTemplate().find(executeSql);
}
}
String methodName = method.getName();
// 如果是更新,插入,删除 操作,则返回值为整型
if (isUpdateSql(methodName)) {
if (paramMap != null)
return Integer.valueOf(namedParameterJdbcTemplate.update(executeSql, paramMap));
else
return Integer.valueOf(jdbcTemplate.update(executeSql));
}
Class<?> returnType = method.getReturnType();
SqlParameterSource sqlParam = null;
if (paramMap != null) {
sqlParam = new MapSqlParameterSource(paramMap);
}
// 各种类型分解
if (returnType.isPrimitive()) {
Object o = null;
if (paramMap != null) {
o = namedParameterJdbcTemplate.queryForObject(executeSql, sqlParam, returnType);
} else {
o = jdbcTemplate.queryForObject(executeSql, returnType);
}
return Castors.me().cast(o, o.getClass(), returnType);
} else if (returnType.isAssignableFrom(List.class)) {
List<Map<String, Object>> result;
if (paramMap != null)
result = namedParameterJdbcTemplate.queryForList(executeSql, sqlParam);
else
result = jdbcTemplate.queryForList(executeSql);
if (result == null) {
return null;
}
ParameterizedType genType = (ParameterizedType) method.getGenericReturnType();
Type comptype = genType.getActualTypeArguments()[0];
Class<?> compclz = (Class<?>) comptype;
ArrayList objList = new ArrayList();
if (compclz.isPrimitive() || Number.class.isAssignableFrom(compclz)
|| CharSequence.class.isAssignableFrom(compclz)
|| "Date".equals(compclz.toString())) {
Object o = null;
for (Map<String, Object> map : result) {
o = map.values().iterator().next();
objList.add(Castors.me().cast(o, o.getClass(), compclz));
}
return objList;
}
for (Map<String, Object> map : result) {
Object o;
o = ReflectUtils.convert(map, compclz);
if (o != null) {
objList.add(o);
}
}
return objList;
} else if (returnType.isAssignableFrom(Map.class)) {
if (paramMap != null)
return namedParameterJdbcTemplate.queryForMap(executeSql, sqlParam);
else
return jdbcTemplate.queryForMap(executeSql);
} else if (returnType.isAssignableFrom(String.class)) {
try {
if (paramMap != null)
return namedParameterJdbcTemplate.queryForObject(executeSql, sqlParam,
String.class);
} catch (EmptyResultDataAccessException e) {
return null;
}
return jdbcTemplate.queryForObject(executeSql, String.class);
} else if (SmartDaoUtil.isWrapClass(returnType)) {
try {
if (paramMap != null)
return namedParameterJdbcTemplate.queryForObject(executeSql, sqlParam,
returnType);
} catch (EmptyResultDataAccessException e) {
return null;
}
return jdbcTemplate.queryForObject(executeSql, returnType);
}
// RowMapper<?> rm =
// ParameterizedBeanPropertyRowMapper.newInstance(returnType);
Map<String, Object> map;
if (paramMap != null) {
try {
map = namedParameterJdbcTemplate.queryForMap(executeSql, sqlParam);
} catch (EmptyResultDataAccessException e) {
map = null;
}
} else {
map = jdbcTemplate.queryForMap(executeSql);
}
return map == null ? null : ReflectUtils.convert(map, returnType);
}
private String setupSqlAndParam(Object src, Method method, Map<String, Object> sqlParamsMap,
Object args[]) throws Exception {
String templateSql = null;
if (method.isAnnotationPresent(Arguments.class)) {
Arguments argms = method.getAnnotation(Arguments.class);
if (argms.value().length != args.length) {
throw new ConfigurationException("SQL参数与方法参数个数不同: " + method.getName());
}
for (int i = 0; i < args.length; i++) {
sqlParamsMap.put(argms.value()[i], args[i]);
}
} else {
String[] params = u.getParameterNames(method);
if (params == null) {
// 取不到接口参数名
for (int i = 0; i < args.length; i++) {
sqlParamsMap.put("arg" + i, args[i]);
}
} else {
// 使用接口参数名
for (int i = 0; i < args.length; i++) {
sqlParamsMap.put(params[i], args[i]);
}
}
}
if (method.isAnnotationPresent(Sql.class)) {
Sql sql = (Sql) method.getAnnotation(Sql.class);
if (StringUtils.isNotEmpty(sql.value())) {
templateSql = sql.value();
} else if (StringUtils.isNotEmpty(sql.file())) {
templateSql = SmartDaoUtil.getTemplateSql(method.getClass().getClassLoader(),
sql.file());
}
} else {
// 默认文件中的默认sql
Class[] interfacse = src.getClass().getInterfaces();
if (interfacse.length > 0) {
String path = interfacse[0].getName();
path = path.replace('.', '/');
templateSql = SmartDaoUtil.loadSQL(path, method.getName());
} else {
// 否则怎么办?直接用代理类或实现类试试吧
String path = src.getClass().getName();
path = path.replace('.', '/');
templateSql = SmartDaoUtil.loadSQL(path, method.getName());
}
}
logger.debug((new StringBuilder("Sql------------------------------------------")).append(
templateSql).toString());
return templateSql;
}
private static boolean isUpdateSql(String methodName) {
String keys[] = "add,create,insert,edit,modify,update,store,remove,delete".split(",");
for (int i = 0; i < keys.length; i++) {
String s = keys[i];
if (methodName.startsWith(s))
return true;
}
return false;
}
public Class<BaseDao> getBaseDaoDeclare(Class c) {
Class root = c;
if (root.equals(BaseDao.class)) {
return root;
} else {
Class[] clzs = root.getInterfaces();
for (Class class1 : clzs) {
Class clz = getBaseDaoDeclare(class1);
if (clz != null) {
return clz;
}
}
}
return null;
}
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return namedParameterJdbcTemplate;
}
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* @return the baseDao
*/
public BaseDao getBaseDao() {
return baseDao;
}
/**
* @param baseDao
* the baseDao to set
*/
public void setBaseDao(BaseDao baseDao) {
this.baseDao = baseDao;
}
/**
* @return the showsql
*/
public boolean getShowsql() {
return showsql;
}
/**
* @param showsql
* the showsql to set
*/
public void setShowsql(boolean showsql) {
this.showsql = showsql;
}
}
分割线---------------------------------------------------------------------------------------------
package com.fujitsu.cn.fnst.framework.smartdao;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import com.fujitsu.cn.fnst.framework.smartdao.annotation.SmartDao;
import com.fujitsu.cn.fnst.framework.util.PackagesToScanUtil;
import com.fujitsu.cn.fnst.framework.util.SmartDaoUtil;
/**
* 智能Dao自动代理工厂
* The Class SmartDaoBeanFactory.<br>
*
* @author FNST)韋 燦楽
* @version 0.1
*/
public class SmartDaoBeanFactory implements BeanFactoryPostProcessor {
private List<String> packagesToScan;
private List<String> interceptorNames;
public SmartDaoBeanFactory() {
}
/**
* 扫描可以自动代理的接口
* 業務機能メソッドを実装する。<br>
*
* @return 復帰値>0:正常(後続処理なし)、<br>
* 復帰値=0:正常終了、<br>
* 復帰値<0:異常終了、<br>
*/
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
logger.debug("===============SmartDaoBeanFactory_init===================");
try {
for (Iterator<String> iterator = packagesToScan.iterator(); iterator
.hasNext();) {
String pack = (String) iterator.next();
if (StringUtils.isNotEmpty(pack)) {
Set<Class> classSet = PackagesToScanUtil.getClasses(pack);
for (Iterator<Class> iterator1 = classSet.iterator(); iterator1.hasNext();) {
Class daoClass = (Class) iterator1.next();
if (daoClass.isAnnotationPresent(SmartDao.class)) {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setBeanFactory(beanFactory);
proxyFactoryBean.setInterfaces(new Class[] { daoClass });
proxyFactoryBean.setInterceptorNames(interceptorNames.toArray(new String[0]));
String beanName = SmartDaoUtil.getFirstSmall(daoClass.getSimpleName());
if (!beanFactory.containsBean(beanName)) {
logger.info("SmartDao proxy ["+daoClass.getName()+"] as '"+beanName+"'");
beanFactory.registerSingleton(beanName,
proxyFactoryBean.getObject());
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public List<String> getPackagesToScan() {
return packagesToScan;
}
public void setPackagesToScan(List<String> packagesToScan) {
this.packagesToScan = packagesToScan;
}
private static final Logger logger = Logger
.getLogger(SmartDaoBeanFactory.class);
public List<String> getInterceptorNames() {
return interceptorNames;
}
public void setInterceptorNames(List<String> interceptorNames) {
this.interceptorNames = interceptorNames;
}
}
- srm smartDao
- srm
- topcode srm SRM 557
- SRM 443
- SRM 442
- SRM 439
- SRM 438
- SRM 444
- SRM 434
- SRM 445
- SRM 426
- SRM 456
- SRM 467
- SRM 466
- SRM 465
- SRM 466
- SRM 469
- SRM 470
- wampseaver
- /dev/zero
- ARM MMU 创建页表
- 利用共享内存实现消息队列
- Android Matrix几个方法的使用
- srm smartDao
- ALAssetsLibrary,ALAssetsGroup,ALAsset,ALAssetRepresentation用法详解
- 比例尺
- boost interprocess之message queue
- <PY><core python programming笔记>C14 执行环境
- 一个指针变量占几个字节问题
- Android利用Intent调用电话来打电话
- addChildViewController transitionFromViewController nib storyboard
- zTree 简单地实现异步加载