基于xml配置插入数据库数据例子(一)

(1) package net.atpco.dds.offline.filing.common.datamapper.binder
1.ClassInfo
package net.atpco.dds.offline.filing.common.datamapper.binder;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

/**
 * This class represents a cached set of class definition information that
 * allows for easy mapping between property names and getter methods.
 */
public final class ClassInfo {
 /** logger */
 private static final Logger LOGGER = Logger.getLogger(ClassInfo.class);

private transient final Map<String, Invoker> getMethods = new ConcurrentHashMap<String, Invoker>();
 private transient final Map<String, Class<?>> getTypes = new ConcurrentHashMap<String, Class<?>>();

private final transient String className;

public ClassInfo(final Class<?> clazz) {
  className = clazz.getName();
  addGetMethods(clazz);
 }

/**
  * Add the get methods based on the java bean naming standard.
  * Allowed methods are is and getters method only.
  * @param cls
  */
 private void addGetMethods(final Class<?> cls) {
  final Method[] methods = getClassMethods(cls);
  for (int i = 0; i < methods.length; i++) {
   final Method method = methods[i];
   String name = method.getName();
   if (name.startsWith("get") && name.length() > 3) {
    if (method.getParameterTypes().length == 0) {
     name = dropCase(name);
     addGetMethod(name, method);
    }
   } else if (name.startsWith("is") && name.length() > 2
     && method.getParameterTypes().length == 0) {
    name = dropCase(name);
    addGetMethod(name, method);
   }
  }
 }

/**
  * Add the method to the map.
  * @param name
  * @param method
  */
 private void addGetMethod(final String name, final Method method) {
  getMethods.put(name, new MethodInvoker(method));
  getTypes.put(name, method.getReturnType());
 }

/**
  * This method returns an array containing all methods declared in this
  * class and any superclass. We use this method, instead of the simpler
  * Class.getMethods(), because we want to look for private methods as well.
  *
  * @param cls
  *            The class
  * @return An array containing all methods in this class
  */
 private Method[] getClassMethods(final Class<?> cls) {
  final Map<String, Method> uniqueMethods = new HashMap<String, Method>();
  Class<?> currentClass = cls;
  while (currentClass != null) {
   addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods());

// we also need to look for interface methods -
   // because the class may be abstract
   final Class<?>[] interfaces = currentClass.getInterfaces();
   for (int i = 0; i < interfaces.length; i++) {
    addUniqueMethods(uniqueMethods, interfaces[i].getMethods());
   }

currentClass = currentClass.getSuperclass();
  }

final Collection<Method> methods = uniqueMethods.values();

return methods.toArray(new Method[methods.size()]);
 }

/**
  * Add the unique method to the map. There is a possibility that
  * the class might be inherited.
  * @param uniqueMethods
  * @param methods
  */
 private void addUniqueMethods(final Map<String, Method> uniqueMethods,
   final Method[] methods) {
  for (final Method currentMethod : methods) {
   if (!currentMethod.isBridge()) {
    final String signature = getSignature(currentMethod);
    // check to see if the method is already known
    // if it is known, then an extended class must have
    // overridden a method
    if (!uniqueMethods.containsKey(signature)) {
     currentMethod.setAccessible(true);
     uniqueMethods.put(signature, currentMethod);
    }
   }
  }
 }

/**
  * Get the method signature.
  * @param method
  * @return
  */
 private String getSignature(final Method method) {
  final StringBuffer strBuf = new StringBuffer();
  strBuf.append(method.getName());
  final Class<?>[] parameters = method.getParameterTypes();

for (int i = 0; i < parameters.length; i++) {
   if (i == 0) {
    strBuf.append(‘:‘);
   } else {
    strBuf.append(‘,‘);
   }
   strBuf.append(parameters[i].getName());
  }

return strBuf.toString();
 }

/**
  * Adding only the method name by dropping the is and get word
  * @param methodName
  * @return
  */
 private static String dropCase(final String methodName) {
  String mName;
  if (methodName.startsWith("get")) {
   mName = methodName.substring(3);

} else {
   mName = methodName.substring(2);
  }

if (mName.length() == 1
    || mName.length() > 1 && !Character.isUpperCase(mName
      .charAt(1))) {
   mName = mName.substring(0, 1).toLowerCase(Locale.US)
     + mName.substring(1);
  }

return mName;
 }

/**
  * Returns the getter invoker object
  * @param propertyName
  * @return
  */
 public Invoker getGetInvoker(final String propertyName) {
  final Invoker method = getMethods.get(propertyName);
  if (method == null) {
   LOGGER.info("There is no READABLE property named ‘" + propertyName
       + "‘ in class ‘" + className + "‘");
  }
  return method;
 }
}

2.DataLoadConfig
package net.atpco.dds.offline.filing.common.datamapper.binder;

import java.sql.Types;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import net.atpco.dds.offline.filing.common.datamapper.parser.ClassConfig;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("dataLoadConfig")
@Scope("singleton")
public class DataLoadConfig {
 /** logger */
 private static Logger LOGGER = Logger.getLogger(DataLoadConfig.class);
 private transient final Map<String, Integer> JDBC_TYPE_MAP = new ConcurrentHashMap<String, Integer>();
 private transient final Map<String, String> SQL_CACHE = new ConcurrentHashMap<String, String>();
 private transient final Map<String, ClassConfig> MAPPING_CONFIG = new ConcurrentHashMap<String, ClassConfig>();
 private transient final Map<Class<?>, ClassInfo> CLASS_INFO_MAP = new ConcurrentHashMap<Class<?>, ClassInfo>();
 @PostConstruct
 public void initialize() {
  JDBC_TYPE_MAP.put("BIGINT", Types.BIGINT);
  JDBC_TYPE_MAP.put("CHAR", Types.CHAR);
  JDBC_TYPE_MAP.put("DATE", Types.DATE);
  JDBC_TYPE_MAP.put("DECIMAL", Types.DECIMAL);
  JDBC_TYPE_MAP.put("DOUBLE", Types.DOUBLE);
  JDBC_TYPE_MAP.put("FLOAT", Types.FLOAT);
  JDBC_TYPE_MAP.put("INTEGER", Types.INTEGER);
  JDBC_TYPE_MAP.put("JAVA_OBJECT", Types.JAVA_OBJECT);
  JDBC_TYPE_MAP.put("LONGVARBINARY", Types.LONGVARBINARY);
  JDBC_TYPE_MAP.put("LONGVARCHAR", Types.LONGVARCHAR);
  JDBC_TYPE_MAP.put("NULL", Types.NULL);
  JDBC_TYPE_MAP.put("NUMERIC", Types.NUMERIC);
  JDBC_TYPE_MAP.put("OTHER", Types.OTHER);
  JDBC_TYPE_MAP.put("SMALLINT", Types.SMALLINT);
  JDBC_TYPE_MAP.put("STRUCT", Types.STRUCT);
  JDBC_TYPE_MAP.put("TIME", Types.TIME);
  JDBC_TYPE_MAP.put("TIMESTAMP", Types.TIMESTAMP);
  JDBC_TYPE_MAP.put("TIMESTMP", Types.TIMESTAMP);
  JDBC_TYPE_MAP.put("TINYINT", Types.TINYINT);
  JDBC_TYPE_MAP.put("VARBINARY", Types.VARBINARY);
  JDBC_TYPE_MAP.put("VARCHAR", Types.VARCHAR);
 }
 
 /**
  * Returns the jdbc type
  * @param jdbcTypeName
  * @return
  */
 public Integer getJdbcType(final String jdbcTypeName) {
  if(JDBC_TYPE_MAP !=null && JDBC_TYPE_MAP.containsKey(jdbcTypeName)) {
   return JDBC_TYPE_MAP.get(jdbcTypeName);
  }
  return null;
 }

/**
  * Gets an instance of ClassInfo for the specified class.
  *
  * @param clazz
  *            The class for which to lookup the method cache.
  * @return The method cache for the class
  */
 public ClassInfo getClassInfo(final Class<?> clazz) {
  synchronized (clazz) {
   ClassInfo cached = CLASS_INFO_MAP.get(clazz);
   if (cached == null) {
    cached = new ClassInfo(clazz);
    CLASS_INFO_MAP.put(clazz, cached);
   }
   return cached;
  }
 }

/**
  * Get the class config object
  * @param identifier
  * @return
  */
 public ClassConfig getClassConfig(final String identifier) {
  return MAPPING_CONFIG.get(identifier);
 }

/**
  * Set the class config object based on the identifier
  * @param identifier
  * @param config
  */
 public void setClassConfig(final String identifier,
   final ClassConfig config) {
  if(MAPPING_CONFIG.containsKey(identifier)) {
   LOGGER.warn("Identifier: " + identifier + " already exists ");
  }
  MAPPING_CONFIG.put(identifier, config);
 }
 
 /**
  * Get the sql from cache if its already compiled
  * @param identifier
  * @return
  */
 public String getSqlFromCache(final String identifier) {
  return SQL_CACHE.get(identifier);
 }

/**
  * Set the sql into cache
  * @param identifier
  * @param sql
  */
 public void setSqlIntoCache(final String identifier, final String sql) {
  SQL_CACHE.put(identifier, sql);
 }
}

3.DataLoadDAO
package net.atpco.dds.offline.filing.common.datamapper.binder;

import org.springframework.jdbc.core.namedparam.SqlParameterSource;

public interface DataLoadDAO {
 int[] batchUpdate(String sql, SqlParameterSource[] paramSource);
}

4.DataLoadDAOImpl
package net.atpco.dds.offline.filing.common.datamapper.binder;

import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Responsible for persisting the data into database as a batch
 *
 * @author atp1axi
 * @version 1.0
 *
 */
@Repository("dataLoadDAO")
public class DataLoadDAOImpl extends DDSDAO implements DataLoadDAO {
 /** logger */
 private static final Logger LOGGER = Logger.getLogger(DataLoadDAOImpl.class);

/**
  * Do a batch update. The parameters are configured sql paramter source.
  *
  * @param sql
  *            - Inser/update sql
  * @param paramSource
  *            - MapSqlparametersource, eventually it will set the values in
  *            prepared statement.
  */
 @Override
 @Transactional(propagation = Propagation.REQUIRED)
 public int[] batchUpdate(final String sql,
   final SqlParameterSource[] paramSource) {
  System.out.println("keys and values====");
  for (int i = 0; i < paramSource.length; i++) {
   System.out.println("sql==" + sql);
   MapSqlParameterSource ps = (MapSqlParameterSource) paramSource[i];
   Map<String, Object> objectMap = ps.getValues();
   for (Entry<String, Object> entry : objectMap.entrySet()) {
    SqlParameterValue rr = (SqlParameterValue) entry.getValue();
    System.out.println(entry.getKey() + " : " + rr.getValue()
      + "=====");
    System.out.println(rr.getValue() == null ? "null" : rr
      .getValue().getClass());
   }
  }

return namedJdbcTemplate.batchUpdate(sql, paramSource);
 }

}

5.DataLoadRequest
package net.atpco.dds.offline.filing.common.datamapper.binder;

import java.util.List;

import org.springframework.util.CollectionUtils;

public class DataLoadRequest {

public DataLoadRequest(final Mode mode, final String identifier,
   final List<?> objects) {
  this.mode = mode;
  this.identifier = identifier;
  this.dataList = objects;
 }

private Mode mode;
 private String identifier;
 private List<?> dataList;

public void setMode(final Mode mode) {
  this.mode = mode;
 }

public void setIdentifier(final String identifier) {
  this.identifier = identifier;
 }

public void setDataList(final List<?> dataList) {
  this.dataList = dataList;
 }

public Mode getMode() {
  return mode;
 }

public String getIdentifier() {
  return identifier;
 }

public List<?> getDataList() {
  return dataList;
 }

public boolean isValid() {
  boolean isValid;
  if (mode == null || CollectionUtils.isEmpty(getDataList())
    || isEmpty(getIdentifier())) {
   isValid = false;
  } else {
   isValid = true;
  }
  return isValid;
 }
 
 public boolean isEmpty(String paramString){
  if((paramString!=null) && (paramString.length()>0)){
   for(int i=0;i<paramString.length();i++){
    if(paramString.charAt(i)!=‘ ‘){
     return false;
    }
   }
  }
  return true;
 }

@Override
 public String toString() {
  
  final StringBuffer request = new StringBuffer();
  if(mode != null){
   request.append("mode: ");
   request.append(mode.toString());
  }
  if(identifier != null){
   request.append("identifier: ");
   request.append(identifier);
  }
  if(dataList != null && !dataList.isEmpty()){
   request.append("dataList: ");
   request.append(dataList.toString());
  }
  return super.toString() + request;
 }
}

6.DataLoadService
/*
 * Created on Oct 17, 2013
 *
 * Copyright 2006 ATPCO Confidential and Proprietary. All Rights Reserved.
 */
package net.atpco.dds.offline.filing.common.datamapper.binder;

/**
*
* Load the data based on the based on the object to table name mapping.
* Identifier is the key to identify the corresponding data from cache
* and generate the sql based on update and insert
*
* @author atp1axi
* @version 1.0
*
*/
public interface DataLoadService {

/**
  * Responsible for generating the insert or update script based on the
  * identifier. The configuration file will be loaded at container
  * start up. The generated sql‘s and parsed configurations will be in
  * in-memory cache.
  * @throws Exception
  */
 boolean update(DataLoadRequest request) throws Exception;
}

7.DataLoadServiceImpl
package net.atpco.dds.offline.filing.common.datamapper.binder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.atpco.dds.offline.filing.common.datamapper.parser.ClassConfig;
import net.atpco.dds.offline.filing.common.datamapper.parser.PropertyConfig;

import org.apache.log4j.Logger;
import org.omg.CORBA.portable.ApplicationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service("dataLoadService")
@Scope("prototype")
public class DataLoadServiceImpl implements DataLoadService {
 
 private static Logger LOGGER = Logger.getLogger(DataLoadServiceImpl.class);
 
 @Autowired
 @Qualifier("sqlPreparator")
 private transient SqlPreparator sqlPreparator;
 
 @Autowired
 @Qualifier("dataLoadDAO")
 private transient DataLoadDAO dataLoadDAO;

@Autowired
 @Qualifier("dataLoadConfig")
 private transient DataLoadConfig dataLoadConfig;
 
 @Value("${jdbc.batch.size}")
 private transient Integer batchSize;

/**
  * Responsible for generating the insert or update script based on the
  * identifier. The configuration file will be loaded at container start up.
  * The generated sql‘s and parsed configurations will be in in-memory cache.
  */
 @Override
 @Transactional(propagation = Propagation.REQUIRED)
 public boolean update(final DataLoadRequest dataLoadRequest)
   throws Exception {
  if (!dataLoadRequest.isValid()) {
   throw new Exception("Inputs are null");
  }

final ClassConfig config = dataLoadConfig
    .getClassConfig(dataLoadRequest.getIdentifier());

if (config == null) {
   throw new Exception(
     "The identifier "
       + dataLoadRequest.getIdentifier()
       + " is null. Make sure the file is included in mapping xml.");
  }
  // Get the generated sql from cache
  String sql = dataLoadConfig.getSqlFromCache(dataLoadRequest
    .getIdentifier() + "_" + dataLoadRequest.getMode().toString());

// if sql does not exist in cache prepare a new one and put it in cache
  if (sql == null) {
   sql = sqlPreparator.prepareSql(config, dataLoadRequest.getMode());
   dataLoadConfig.setSqlIntoCache(dataLoadRequest.getIdentifier()
     + "_" + dataLoadRequest.getMode().toString(), sql);
  }
  final List<SqlParameterSource> paramSourceList = new ArrayList<SqlParameterSource>();
  for (final Object object : dataLoadRequest.getDataList()) {
   final MapSqlParameterSource parameterSource = sqlPreparator
     .prepareSqlParameter(dataLoadRequest.getMode(), config, object);
   paramSourceList.add(parameterSource);
  }
  // Persist the data based on the batch size.
  final List<SqlParameterSource[]> batchList = getBatches(paramSourceList);
  int processingCount = 0;
  for (final SqlParameterSource[] sources : batchList) {
   LOGGER.info("Processing from "+processingCount+
     " th record to the maximum of "+sources.length+ " records");
   dataLoadDAO.batchUpdate(sql, sources);
   processingCount = processingCount + sources.length;
  }
  return true;
 }
 
 /**
  * Split the single collection into multiple collections based on the batch
  * size.
  *
  * @param collection
  * @return
  */
 private List<SqlParameterSource[]> getBatches(
   final List<SqlParameterSource> collection) {
  int batchCount = 0;
  final List<SqlParameterSource[]> batches = new ArrayList<SqlParameterSource[]>();
  while (batchCount < collection.size()) {
   final int nextInc = Math.min(collection.size() - batchCount,
     batchSize);
   final List<SqlParameterSource> batch = collection.subList(
     batchCount, batchCount + nextInc);
   batches.add(batch.toArray(new SqlParameterSource[batch.size()]));
   batchCount = batchCount + nextInc;
  }
  return batches;
 }

}

时间: 2024-10-23 18:01:16

基于xml配置插入数据库数据例子(一)的相关文章

基于xml配置插入数据库数据例子(二)

8.DataMappingConfigurer/* * Created on Oct 8, 2013 * * Copyright 2006 ATPCO Confidential and Proprietary. All Rights Reserved. */package net.atpco.dds.offline.filing.common.datamapper.binder; import java.io.IOException;import java.util.ArrayList;impo

基于xml配置插入数据库数据例子(三)

16.Utilpackage net.atpco.dds.offline.filing.common.datamapper.binder; public class Util { private static String userId; public static String getUserId() {  return userId; } public static void setUserId(String userId) {  Util.userId = userId; }} 17.Sp

Spring Security应用开发(02)基于XML配置的用户登录

1.1. 基于XML配置的登录功能 经过一系列配置之后,可以使用Spring Security内置功能实现最基本的用户登录功能以及角色验证功能,这种内置的功能没有任何实用价值,仅仅用于了解Spring Security的工作方式. (1)配置web.xml. 主要是为Spring MVC和Spring Security提供一些入口,以便有机会进行Spring MVC以及Spring Security的初始化和过滤处理等工作. <servlet> <servlet-name>spri

基于xml配置的springMVC-快速入门

一:准备工作 将需要用到的spring包放进lib文件夹内,具体需要什么包自己网上查,或在我的例子里找. 二:配置文件:web.xml 主要是配置servlet路径方式和指定上下文xml文件. 1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="

Spring IOC的初始化过程——基于XML配置(一)

前言:在面试过程中,Spring IOC的初始化过程,基本上属于必答题,笔者的亲身经历.因此本文基于Spring的源码对其IOC的初始化过程进行总结. 注:spring版本为4.3.0. 1.调试前准备 在spring源码中,添加如下内容(有关spring源码如何导入idea,请查询相关资料): 说明: ①User为简单bean,含有name和gender两个属性. ②User.xml为spring配置文件,仅仅对User进行简单的配置. ③SpringIoCDebug为测试类. 先看执行结果:

MyBatis入门程序(基于XML配置)

创建一个简单的MyBatis入门程序,实现对学生信息的增删改查功能(基于XML配置) 一.新建一个Java工程,导入MyBatis核心jar包.日志相关的jar包以及连接Oracle数据库所需驱动包,目录结构如下 二.创建MyBatis核心配置文件mybatis-config.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//myba

[刘阳Java]_Spring AOP基于XML配置介绍_第9讲

基于注解配置的Spring AOP固然简单,但是这节我们会给大家介绍基于XML配置的AOP是如何应用的.为什么这么说了,因为后面我们还会介绍到Spring对Dao操作的事务管理(基于AOP的XML文件方式来配置事务) 1. 基于XML文件方式来配置Spring的AOP,则我们需要的一些基本元素如下 <aop:config.../>,此标签很重要.它是在XML里配置AOP功能的核心标签 all aspect and advisor elements must be placed within a

转载 - Struts2基于XML配置方式实现对action的所有方法进行输入校验

出处:http://www.cnblogs.com/Laupaul/archive/2012/03/15/2398360.html 使用基于XML配置方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类放在同一个包下,文件的取名格式为:ActionClassName-validation.xml.ActionClassName为action的简单类名,-validation为固定写法.如果Action类为cn.validate.acti

AOP实现日志打印 基于xml配置的AOP实现 切入点表达式

前置通知,后置通知,异常通知,返回通知 使用注解需要加入 在xml中加入  <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 环绕通知(跟以上结果一样)  需要有返回值return rs: 基于xml配置的AOP实现(上面的注解全去掉,配置以下) ①切入点表达式的语法格式[参见第5章AOP细节] execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表])) 参见第5章AOP细节:演示验证 1.任