动态数据源1之综合版--分库(备份主库、建库,并动态创建数据源、动态切换数据源)

最近刚刚做完个项目,觉得分库这里可以归纳一下,给未来的自己备个份^_^

技术目标:实现自动备份库、自动建库,动态创建数据源、动态切换数据源

需求:给甲方A开发个项目,A有着很大的用户群,涉及A公司、B公司、c、d......(动态变化的:即可能继续延伸、也可能摸某个公司会终止业务),故A要求针对不同的业务客户有自己的独立库,这里强调一下:虽然是不同的库,A对每个公司的具体业务表示一样的。


目标需求:由于我不愿意为了写这个博客去剥离纯粹的逻辑代码,故这里只提供关键的实现点,具体的jsp调用逻辑等细节不再关注。

环境:win7,eclipse kepler,jdk7 ,tomcat7,jQuery v1.11.1,mysql5.6(mysql的命令必须配到环境变量里,建库时要用),springmvc4 , hibernate4(可以不用hibernate)

代码地址:http://download.csdn.net/detail/rainyspring4540/9568014

实现逻辑:

第一步:项目启动时有个默认的基础库和对应的数据源(就是有个能访问的库作为默认库),以后统称为主库

第二步:我们会在主库的界面下进行创建新库(这里涉及先备份基础库表、视图,然后创建新库)并为新库创建数据源使之能被访问,以后统称新库为从库

第三步:由于有些业务可能涉及主库和从库、从库和从库的同步数据问题,故要再具体的某个库的数据源操作下动态切换到别的库,去更改其他需要同步的数据

我先贴出所有代码,大家完全可以自己边运行边分析,我花了一天从项目中抽离的的demo很简单的,没必要听我唠叨,故先贴代码:

代码目录:





其中temp里有个maindb.sql,是mysql的库文件,主库的名字固定是maindb

maindb.sql内容

/*
Navicat MySQL Data Transfer

Source Server         : local
Source Server Version : 50517
Source Host           : localhost:3306
Source Database       : maindb

Target Server Type    : MYSQL
Target Server Version : 50517
File Encoding         : 65001

Date: 2016-07-05 17:23:21
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `msg`
-- ----------------------------
DROP TABLE IF EXISTS `msg`;
CREATE TABLE `msg` (
  `name` varchar(255) NOT NULL DEFAULT '',
  `note` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of msg
-- ----------------------------

-- ----------------------------
-- Table structure for `project`
-- ----------------------------
DROP TABLE IF EXISTS `project`;
CREATE TABLE `project` (
  `PROJECTID` varchar(50) NOT NULL,
  `PROJECTNAME` varchar(200) DEFAULT NULL,
  `userId` varchar(255) DEFAULT NULL,
  `pwd` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`PROJECTID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of project
-- ----------------------------

-- ----------------------------
-- Table structure for `sys_db`
-- ----------------------------
DROP TABLE IF EXISTS `sys_db`;
CREATE TABLE `sys_db` (
  `id` varchar(255) NOT NULL DEFAULT '',
  `projectId` varchar(255) DEFAULT '',
  `dbname` varchar(255) DEFAULT NULL,
  `urlPrefix` varchar(255) DEFAULT NULL,
  `host` varchar(255) DEFAULT NULL,
  `port` varchar(255) DEFAULT NULL,
  `urlSuffix` varchar(255) DEFAULT NULL,
  `driverClassNameValue` varchar(255) DEFAULT NULL,
  `dataSourceId` varchar(255) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `pwd` varchar(255) DEFAULT NULL,
  `createdate` varchar(255) DEFAULT '',
  `status` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_db
-- ----------------------------
这个文件你用命令或Navicat mysl工具都能自动生成文件,你也可以看着表结构自己去创建。


然后是src文件,我逐个包贴出来

config包是配置文件,其中project-config.xml是springmvc的配置文件;dataSourceCfgTemplate.vm是动态数据源创建的配置文件,里面的参数都是替换符,因为是动态数据源嘛,参数是变化的。

而util.db是真正核心创建库和创建数据源包,且我个人认为代码完全独立

其他包就见明知义,controller是我demo的一些控制类:包含登录、初始化默认数据源。。。;dto就是展示层用于封装实体到jsp的数据传输;entity是实体


看demo的时候从login.jsp开始,一点点看就ok了。

提示自己:

1 。切换数据源的方式是当时找到的比较通用的,看完代码后可以网上看看原理,

2 。创建数据源虽然在四个测试人员下依然稳定,但个人总觉得不一定能撑住大数据并发,

3。如果你采用了这种方式,切库一定要小心!一定要小心!一定要小心!可能会出现卡死,幽灵数据、切换错误现象,那一定坚信是自己使用不当:

     原因一 :如果你用了hibernate,session的不正常关闭很恶心;如果因为异常不关闭session,导致池中的链接马上耗完,如果涉及同步,不正常关闭上一个session也会连累下边的不正常执行,建议不用hibernate,我的逻辑仔细看会发现  只有具体业务才用了hibernate,建库、创建数据源并没有用hibernate,而切换数据源可以直接采用如下代码即可:

contextHolder.set("defaultDataSource");
hibernateTemplate.find(sql);//采用hibernatetemplate,是spring封装了hibernate,无需考虑session关闭
或者你干脆用jdbctemplate,当然你的spring配置文件也要相应改下。

4.不要多个数据源的session嵌套进行CRUD,你会死的很惨,必须分开,比如同步操作,且对每个数据数据源的操作加Try-catch,然后进行下一个数据源的操作,这是测试的结果

5 建议不要将上一个数据源的session获取的实体(仅仅是实体,其他的没事,比如具体的数据列)用于下一个数据源的CRUD,仅仅是建议,我都是尽量避开可能的问题,当时项目太忙,没时间测试,先记下

6 以上都是针对使用了hibernate的session后的一些警告,还是那句话,如果能说服领导,别用hibernate,至少在多数据源上问题很多。

下面贴贴代码:

config.propties

##主库配置
main.driver=com.mysql.jdbc.Driver
main.url=jdbc:mysql://localhost:3306/maindb?useUnicode=true&characterEncoding=utf8
main.username=root
main.password=root

##默认的备份库地址
dataSourceRecord.urlPrefix=jdbc:mysql://
dataSourceRecord.urlSuffix=
backup.host=localhost
backup.port=3306
backup.dbName=maindb
backup.username=root
backup.password=root
backup.exportPath=d:/database.sql

##导入地址
importDB.host=localhost
importDB.port=3306
importDB.dbName=ggg
importDB.username=root
importDB.password=root
importDB.importPath=d:/database.sql
# hibernate.X
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=none

dataSourceCfgTemplate.vm

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
	        http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
			http://www.springframework.org/schema/context 
			http://www.springframework.org/schema/context/spring-context-3.2.xsd
			http://www.springframework.org/schema/aop
			http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
			http://www.springframework.org/schema/tx
			http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
	<bean id="${dataSourceId}" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${driverClassName}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
	</bean>
</beans>

project-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
	        http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
			http://www.springframework.org/schema/context 
			http://www.springframework.org/schema/context/spring-context-3.2.xsd
			http://www.springframework.org/schema/aop
			http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
			http://www.springframework.org/schema/tx
			http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
	<context:component-scan base-package="controller"/>
	<bean id ="dynamicLoadBean" class="util.db.DynamicLoadBean" ></bean>
	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<!-- 单独文件 -->
		<!-- <property name="location" value="/WEB-INF/config.properties" /> -->
		<!-- 多个文件 -->
		<property name="locations">
		 	<list>
                <!-- method1 标准配置 -->
                <value>classpath*:/config/config.properties</value>
                <!-- method2 -->
                <!-- <value>/WEB-INF/config.properties</value> -->
                <!--method3 服务器生产环境配置 -->
                <!-- <value>file:/var/myapp/application.server.properties</value> -->
            </list>
		</property>
	</bean>
	<!-- 连接mysql -->
	<bean id="defaultDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${main.driver}" />
		<property name="url" value="${main.url}" />
		<property name="username" value="${main.username}" />
		<property name="password" value="${main.password}" />
	</bean>

	<bean id="dynamicDataSource" class="util.db.DynamicDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				 <entry key="defaultDataSource" value-ref="defaultDataSource" /> 
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="defaultDataSource" />
	</bean>

	<!-- 类型2:DB2、SQL Server、MySQL 等非 Oracle 的其它数据库,则只要简单配置一个 DefaultLobHandler -->
	<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" 
		lazy-init="true" />

	<!--Hibernate4 sessionFactory -->
	<bean id="sessionFactory"  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dynamicDataSource" />
        <property name="packagesToScan">
            <list>
                <!-- 可以加多个包 -->
                <value>entity</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto" >${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <!-- hibernate.jdbc.fetch_size 对mysql无效 -->
                
               <!--  <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.jdbc.batch_size">20</prop>
                 -->
                <!-- 配置二级缓存 -->
                  
			   <!--  <prop key="hibernate.cache.use_second_level_cache">true</prop>  
			    <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
				 -->
				<!-- 开启查询缓存 -->
				<!-- <prop key="hibernate.cache.use_query_cache">true</prop> -->
              
                <!--  <prop key="hibernate.current_session_context_class">thread</prop> --> 
            </props>
        </property>
    </bean>
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
    <!-- 配置Hibernate事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      
      <property name="sessionFactory" ref="sessionFactory" />
      
     
   </bean>
   
   <!-- 配置事务异常封装 -->
   <bean id="persistenceExceptionTranslationPostProcessor" 
       class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
	<!-- jdbc事务管理器 -->
	<!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref local="dataSource_mysql" />
		</property>
	</bean> -->

	<!-- 启用注解 -->
	<context:annotation-config />
	<!-- 注解事务驱动 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	
	
	<!-- ViewResolver -->
	<bean id="internalResourceViewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<!-- <property name="prefix" value="/justwin/"/> -->
		<property name="suffix" value=".jsp" />
		<!-- 设置解析器的优先级 InternalResourceViewResolver必须总是赋予最低的优先级(最大的order值), 因为不管返回什么视图名称,它都将解析视图。如果它的优先级高于其它解析器的优先级的话, 
			它将使得其它具有较低优先级的解析器没有机会解析视图 -->
		<property name="order" value="0" />
	</bean>
</beans>

LoginController.java

package controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import util.db.DataSourceContextHolder;
/**
 * 
 * @author jx
 * @createDate 2016-06-24
 */
@Controller
public class LoginController {
	@Autowired
	private HibernateTemplate hibernateTemplate;


	/**
	 * 管理员登录
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("/systemLogin.do")
	public String systemLogin(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
	
			// 业务代码--------------------奇妙的分割线-------------------------
			String userId = request.getParameter("userId");
			String pwd = request.getParameter("pwd");
			
			if("admin".equals(userId)&&"admin".equals(pwd)){
				return "adminIndex";
			}else{
				return "login";//返回登录页面
			}
	}
	@RequestMapping("/projectLogin.do")
	public String projectLogin(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
	
			
			Session session = null;
			try {
				session = DataSourceContextHolder.getSystemDB(hibernateTemplate);
		
				// 业务代码--------------------奇妙的分割线-------------------------
				String userId = request.getParameter("userId");
				String pwd = request.getParameter("pwd");
			
				Long count = (Long) session.createQuery("select count(*) from Project where userId=:userId and pwd=:pwd").setString("userId", userId).setString("pwd", pwd).uniqueResult();
				if(count==null||count<=0){
					return "login";//返回登录页面

				}else{
					return "projectIndex";

				}
				
				// 业务代码--------------------奇妙的分割线-------------------------
			} catch (Exception e) {
				return "login";//返回登录页面
			} finally {
				if (session != null) {
					try{
					session.flush();
					session.close();
					}catch(Exception e){
						
					}
					
				}
			}
	}
}

ProjectController.java

package controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import util.base.PrintHelper;
import util.db.DataSourceContextHolder;
import util.db.MyDataSource;
import util.db.MyDatabase;
import dto.DatagridMsg;
import dto.DatagridProject;
import entity.DatabaseBean;
import entity.Msg;
import entity.Project;
/**
 * 
 * @author jx
 * @createDate 2016-06-24
 */
@Controller
@RequestMapping("/project/")
public class ProjectController implements ApplicationContextAware {
	private ApplicationContext ac;
	@Autowired
	private HibernateTemplate hibernateTemplate;
	
	@RequestMapping("/listProjects.do")
	public void listProjects(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {
			session = DataSourceContextHolder.getSystemDB(hibernateTemplate);
	
			// 业务代码--------------------奇妙的分割线-------------------------
			
			List<Project> list = session.createQuery("from Project").list();
			
			List<DatagridProject> olist = this.changeDTO(list);
			PrintHelper.sendJsonMap(response, olist,olist.size());
			
			// 业务代码--------------------奇妙的分割线-------------------------
		} catch (Exception e) {
			
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
	}
	@RequestMapping("/listProjectsByUserIdAndPwd.do")
	public void listProjectsByUserIdAndPwd(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {
			session = DataSourceContextHolder.getSystemDB(hibernateTemplate);
	
			// 业务代码--------------------奇妙的分割线-------------------------
			String userId = request.getParameter("userId");
			String pwd = request.getParameter("pwd");
			List<Project> list = session.createQuery("from Project where userId=:userId and pwd=:pwd").setString("userId", userId).setString("pwd", pwd).list();
			
			List<DatagridProject> olist = this.changeDTO(list);
			PrintHelper.sendJsonMap(response, olist,olist.size());
			
			// 业务代码--------------------奇妙的分割线-------------------------
		} catch (Exception e) {
			
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
	}
	//
	@RequestMapping("/getProject.do")
	public void getProject(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {
			
			session = DataSourceContextHolder.getSystemDB(hibernateTemplate);
	
			// 业务代码--------------------奇妙的分割线-------------------------
			String projectId = request.getParameter("projectId");
			Project p = (Project) session.get(Project.class, projectId);
			if(p!=null){
				DatagridProject o = this.changeDTO(p);
				PrintHelper.sendJsonObject(response, o);
			}else{
				PrintHelper.sendJsonString(response, "");

			}
			
			
			// 业务代码--------------------奇妙的分割线-------------------------
		} catch (Exception e) {
			
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
	}
	private DatagridProject changeDTO(Project p) {
		DatagridProject o = new DatagridProject();
		o.setProjectId(p.getProjectId());
		o.setProjectName(p.getProjectName());
		o.setUserId(p.getUserId());
		o.setPwd(p.getPwd());
		return o;
	}
	/**
	 * 转换结构
	 * @param list
	 * @return
	 */
	private List<DatagridProject> changeDTO(List<Project> list) {
		List<DatagridProject> olist = new ArrayList<DatagridProject>();
		if(list==null||list.size()<=0){
			return olist;
		}
		for(Project p :list){
			olist.add(this.changeDTO(p));
		}
		return olist;
	}


	/**
	 * @updateDate 2016-06-12
	 * @author 
	 * @throws IOException
	 * @description 新增项目
	 */
	@RequestMapping("/addProject")
	public void addProject(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		String projectId = null;
		boolean flag = false;
		try {
			session = DataSourceContextHolder.getSystemDB(hibernateTemplate);
	
			session.beginTransaction();

			// 业务代码--------------------奇妙的分割线-------------------------
			projectId = request.getParameter("projectId");
			String projectName = request.getParameter("projectName");
			String userId = request.getParameter("userId");
			String pwd = request.getParameter("pwd");
			Project p = (Project) session.get(Project.class, projectId);
			if(p!=null){
				PrintHelper.sendJsonString(response, "isUsed");//反馈
			}else{
				// 项目表中生成记录
				Project p1 = new Project();
				p1.setProjectId(projectId);
				p1.setProjectName(projectName);
				p1.setUserId(userId);
				p1.setPwd(pwd);
				session.save(p1);
				
				flag = true;
			}
			session.getTransaction().commit();
			// 业务代码--------------------奇妙的分割线-------------------------

		} catch (Exception e) {
			session.getTransaction().rollback();
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
		// 建立项目库

		try {
			if (flag) {
				//创建项目
				DatabaseBean db = new MyDatabase(hibernateTemplate, projectId)
						.copyMaindbByDBName(null);
				// 将数据源添加到server
				new MyDataSource(db, ac).create();
				PrintHelper.sendJsonString(response, "success");
			} else {
				PrintHelper.sendJsonString(response, "failure");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			PrintHelper.sendJsonString(response, "failure");

		}
		
	}
	@RequestMapping("/listMsgByProjectId.do")
	public void listMsgByProjectId(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {
			String projectId = request.getParameter("projectId");
			if(StringUtils.isBlank(projectId)){
				PrintHelper.sendJsonString(response, "");//反馈
				return;
			}
			session = DataSourceContextHolder.getProjectDB(hibernateTemplate, projectId);
	
			// 业务代码--------------------奇妙的分割线-------------------------
			
			List<Msg> list = session.createQuery("from Msg").list();
			List<DatagridMsg> olist = new ArrayList<DatagridMsg>();
			if(list!=null){
				for(Msg m:list){
					DatagridMsg o = new DatagridMsg();
					o.setName(m.getName());
					o.setNote(m.getNote());
					olist.add(o);
				}
			}
			PrintHelper.sendJsonMap(response, olist,olist.size());
			
			// 业务代码--------------------奇妙的分割线-------------------------
		} catch (Exception e) {
			
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
	}
	/**
	 * @updateDate 2016-06-12
	 * @author 
	 * @throws IOException
	 * @description 新增栏目
	 */
	@RequestMapping("/addMsg")
	public void addMsg(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {
			String projectId = request.getParameter("projectId");
			String name = request.getParameter("name");
			String note = request.getParameter("note");
			if(StringUtils.isBlank(projectId)){
				PrintHelper.sendJsonString(response, "failure");//反馈
				return;
			}
			session = DataSourceContextHolder.getProjectDB(hibernateTemplate, projectId);
	
			session.beginTransaction();
			
			Msg m = (Msg) session.get(Msg.class, name);
			if(m!=null){
				PrintHelper.sendJsonString(response, "isUsed");//反馈
			}else{
				// 项目表中生成记录
				Msg m1 = new Msg();
				m1.setName(name);
				m1.setNote(note);
				session.save(m1);
			}
			session.getTransaction().commit();
			PrintHelper.sendJsonString(response, "success");
			// 业务代码--------------------奇妙的分割线-------------------------

		} catch (Exception e) {
			session.getTransaction().rollback();
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
		
		
	}
	/**
	 * @updateDate 2016-06-12
	 * @author 
	 * @throws IOException
	 * @description 删除栏目
	 */
	@RequestMapping("/delMsg")
	public void delMsg(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {
			String projectId = request.getParameter("projectId");
			String name = request.getParameter("name");
			if(StringUtils.isBlank(projectId)){
				PrintHelper.sendJsonString(response, "failure");//反馈
				return;
			}
			session = DataSourceContextHolder.getProjectDB(hibernateTemplate, projectId);
	
			session.beginTransaction();
			
			Msg m = (Msg) session.get(Msg.class, name);
			if(m!=null){
				session.delete(m);
			}
			session.getTransaction().commit();
			PrintHelper.sendJsonString(response, "success");
			// 业务代码--------------------奇妙的分割线-------------------------

		} catch (Exception e) {
			session.getTransaction().rollback();
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
		
		
	}


	
	
	/**
	 * @updateDate 2016-06-12
	 * @author 
	 * @description 删除项目
	 */
	@RequestMapping("/delProject")
	public synchronized void delProject(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		Session session = null;
		try {

			session = DataSourceContextHolder.getSystemDB(hibernateTemplate);

			String key = request.getParameter("projectId");
			if (!StringUtils.isBlank(key)) {
				session.beginTransaction();
				// 删除主库的项目表记录
				session.createQuery("delete from Project where projectId=:projectId")
						.setString("projectId", key).executeUpdate();
				// 删除db链接
				session.createQuery(
						"delete from DatabaseBean where projectId=:projectId")
						.setString("projectId", key).executeUpdate();
				session.getTransaction().commit();

				// 删除项目库(采用占位符?)
				session.createSQLQuery("drop database ds_" + key)
						.executeUpdate();// 暂时采用这种语法

			}
			PrintHelper.sendJsonString(response, "success");

		} catch (Exception e) {
			session.getTransaction().rollback();
		} finally {
			if (session != null) {
				try{
				session.flush();
				session.close();
				}catch(Exception e){
					
				}
				
			}
		}
	}

	

	@Override
	public void setApplicationContext(ApplicationContext ac)
			throws BeansException {
		this.ac = ac;

	}
}

SysInitData.java

package controller;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

import util.base.DBHelper;
import util.db.DataSourceManager;
import util.db.MyDatabase;
/**
 * 项目启动后--初始化权限类
 * @author jx
 * @date 2015-08-25
 */
@Component
public class SysInitData implements  ApplicationListener<ContextRefreshedEvent>,ServletContextAware{
	private Log log = LogFactory.getLog(SysInitData.class);
	private  ApplicationContext ac  ;
	private  ServletContext sc;
	
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		
		this.ac = event.getApplicationContext();
		//初始化应用级参数
		
		//数据源加载中
		log.info("####-----准备数据源加载");
		DataSourceManager.init(ac,sc);
		log.info("####-----完成数据源加载");
		
		log.info("####-----准备导入存储过程");
		try{

			DBHelper.initAllProcedures((HibernateTemplate) ac.getBean("hibernateTemplate"), sc);
			log.info("####-----完成导入存储过程");
		}catch(Throwable e){
			log.info("####-----导入存储过程失败");
		}
		//数据库连接类型
		InputStream is = MyDatabase.class.getClassLoader().getResourceAsStream(
				MyDatabase.configFile);
		Properties pro = new Properties();
		try {
			pro.load(is);
			String dialect = (String) pro.get("hibernate.dialect");
			if(dialect!=null){
				if(dialect.toLowerCase().contains("mysql")){
					sc.setAttribute("dbtype", "mysql");
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	@Override
	public void setServletContext(ServletContext servletContext) {
		this.sc = servletContext;
	}
	

}

dto层DatagridMsg.java

package dto;

public class DatagridMsg {
	public String name;
	public String note;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getNote() {
		return note;
	}
	public void setNote(String note) {
		this.note = note;
	}
	
}
DatagridProject.java

package dto;

public class DatagridProject {
	public String projectId;
	public String ProjectName;
	public String userId;
	public String pwd;
	public String getProjectId() {
		return projectId;
	}
	public void setProjectId(String projectId) {
		this.projectId = projectId;
	}
	public String getProjectName() {
		return ProjectName;
	}
	public void setProjectName(String projectName) {
		ProjectName = projectName;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
}

entity层DatabaseBean.java

package entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * 数据源
 * 
 * @author jx
 * 
 */
@Entity
@Table(name = "sys_db")
public class DatabaseBean {
	/**
	 * 当出现项目相同的多条记录时, 通过max函数取最大值作为以projectId为条件
	 * 获取数据源的返回记录(保证一个projectId下有且仅有一条有效数据源记录)
	 */
	@Id
	private String id;
	@Column
	private String projectId;
	@Column
	private String dbName;
	@Column
	private String urlPrefix;
	@Column
	private String host;
	@Column
	private String port;
	@Column
	private String urlSuffix;
	@Column
	private String driverClassNameValue;
	@Column
	private String dataSourceId;
	@Column
	private String username;
	@Column
	private String pwd;
	@Column
	private String createdate;
	@Column
	private String status;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getProjectId() {
		return projectId;
	}

	public void setProjectId(String projectId) {
		this.projectId = projectId;
	}

	public String getDbName() {
		return dbName;
	}

	public void setDbName(String dbName) {
		this.dbName = dbName;
	}

	public String getUrlPrefix() {
		return urlPrefix;
	}

	public void setUrlPrefix(String urlPrefix) {
		this.urlPrefix = urlPrefix;
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getPort() {
		return port;
	}

	public void setPort(String port) {
		this.port = port;
	}

	public String getUrlSuffix() {
		return urlSuffix;
	}

	public void setUrlSuffix(String urlSuffix) {
		this.urlSuffix = urlSuffix;
	}

	public String getDriverClassNameValue() {
		return driverClassNameValue;
	}

	public void setDriverClassNameValue(String driverClassNameValue) {
		this.driverClassNameValue = driverClassNameValue;
	}

	public String getDataSourceId() {
		return dataSourceId;
	}

	public void setDataSourceId(String dataSourceId) {
		this.dataSourceId = dataSourceId;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getCreatedate() {
		return createdate;
	}

	public void setCreatedate(String createdate) {
		this.createdate = createdate;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

}

Msg.java

package entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author jx
 * @date 2015-11-16
 * @description 栏目表
 */
@Entity
@Table(name = "msg")
public class Msg {
	@Id
	public String name;
	@Column
	public String note;
	
	public String getNote() {
		return note;
	}
	public void setNote(String note) {
		this.note = note;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

Project.java

package entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
 * @author jx
 * @date 2015-11-16
 * @description 项目表
 */
@Entity
@Table(name = "project")
public class Project {
	
	@Id
	private String projectId;//项目编号
	@Column
	private String projectName;//项目名称
	@Column
	private String userId;
	@Column
	private String pwd;

	public String getProjectName() {
		return projectName;
	}
	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}
	public String getProjectId() {
		return projectId;
	}
	public void setProjectId(String projectId) {
		this.projectId = projectId;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	
}

util.base包DataHelper.java

package util.base;

import java.io.File;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

/*
 * 这个帮助类专门处理 数据格式上的转换问题--多以json和其他格式互转
 * 
 * @author yhr
 * 
 */
/**
 * @author jx
 * @date 2015-08-25
 */
public final class DataHelper {
	

	/**
	 * 获取保存服务器保存文件的基础路径(目录末包含分隔符)
	 * @param sc
	 * @return
	 */
	public static String getSavePath(ServletContext sc){
		if(sc==null) return null;
		return sc.getRealPath("")+ File.separator + "temp" + File.separator;
					
	}
	/**
	 * 获取保存服务器保存文件的基础路径(目录末包含分隔符)
	 * @param sc
	 * @return
	 */
	public static String getSavePath4Base(ServletContext sc){
		if(sc==null) return null;
		return sc.getRealPath("")+ File.separator + "temp" + File.separator+"base"+ File.separator;
					
	}
	/**
	 * 获取服务器文件访问路径(目录末包含分隔符)
	 * @param request
	 * @return
	 */
	public static String getServerPath(HttpServletRequest request){
		if(request==null) return null;
		return request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()
							+ request.getContextPath() + "/temp/";
	}

}
DBHelper.java

package util.base;

import java.io.File;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.springframework.orm.hibernate4.HibernateTemplate;

import util.db.DBProperty;
import util.db.DataSourceContextHolder;
import util.db.MySqlImportAndExport;
import entity.DatabaseBean;

/**
 * 具体sql的生成工具类
 * 
 * @author 
 * 
 */
/**
 * @author jx
 * @date 2015-08-25
 */
public final class DBHelper {

	/**
	 * 在创建项目的时候目前无法将存储过程导入,故单独插入存储过程
	 * @param session 必须是系统库的session
	 * @param projectId 插入的项目,在主库的sys_db中存在记录
	 * @param request
	 */
	public static void initProceduresAfterCreatingProject(HibernateTemplate hibernateTemplate,String projectId,ServletContext sc){
		Session session = null;
		try{
			if(StringUtils.isBlank(projectId)) {
				System.err.println("在创建项目时插入存储过程projectId不能为空");
				return;
			}
			//保存当前数据源名称
			String currentDataSource = DataSourceContextHolder.getDataSourceName();
			//切换到主库
			DataSourceContextHolder.setDataSourceType("defaultDataSource");
			session = hibernateTemplate.getSessionFactory().openSession();
			List<DatabaseBean> db_list = session.createQuery("from DatabaseBean where id='" + projectId + "'").list();
			if(db_list==null||db_list.size()!=1) {
				System.err.println("在创建项目时插入存储过程 数据库实体DatabaseBean为空或大于一个");
				return;
			}
			
			DatabaseBean mydb = db_list.get(0);
		
//			ServletContext sc = request.getSession().getServletContext();
			String fileName = DataHelper.getSavePath4Base(sc)+"package_procedures.sql";
			if(!new File(fileName).exists()) return;
			
			DBProperty pro = new DBProperty(mydb.getHost(), mydb.getDbName(), fileName);
	
			long start = System.currentTimeMillis();
			int exitVal = 0;
			try{
				exitVal = MySqlImportAndExport.importSqlBySource4NoCreateDB(pro);
			}catch(Throwable e){
				exitVal = -1;
			}
			long end = System.currentTimeMillis();
			System.out.println("####-------向数据库"+mydb.getDbName()+" 导入存储过程【运行代码:"+exitVal+" ; 耗时:"+(end-start)/(1000*60)+"m】");
			session.close();
			//切回原来的数据源
			DataSourceContextHolder.setDataSourceType(currentDataSource);
		}catch(Throwable e){
			if(session!=null){
				session.close();
			}
			System.err.println("!!!!!!在创建项目过程中导入存储过程异常!!!!!!!!");
		}
	}
	/**
	 * 目前的项目创建后无法导入存储过程,
	 * 所以要手动向各个项目导入
	 */
	public static  void initAllProcedures(HibernateTemplate hibernateTemplate,ServletContext sc) {
		Session session = null;
		try{
			String fileName = DataHelper.getSavePath4Base(sc)+"package_procedures.sql";
			if(!new File(fileName).exists()) {
				System.err.println("系统存储过程文件丢失");
				return;
			}
			//从系统表中找到所有的现存的库
			String currentDataSource = DataSourceContextHolder.getDataSourceName();
			//HibernateTemplate hibernateTemplate = (HibernateTemplate) ac.getBean("hibernateTemplate");
			
			DataSourceContextHolder.setDataSourceType("defaultDataSource");
			session = hibernateTemplate.getSessionFactory().openSession();
			List<Object[]> list_db = session.createSQLQuery("select id,projectId,dbname,host,username,pwd from sys_db").list();
			System.out.println("需要导入的数据库个数:"+list_db.size());
			if(list_db!=null&&list_db.size()>0){
				for(Object[] db:list_db){
					System.out.println(db[0]+"--"+db[1]+"--"+db[2]+"--"+db[3]+"--"+db[4]+"--"+db[5]);
					if(db.length<6) continue;
					//System.out.println(db[2]+"--"+db[3]+"--"+db[4]+"--"+db[5]);
	
					Object projectId = db[1];
					Object dbname = db[2];
					Object host = db[3];
					Object username = db[4];
					Object pwd = db[5];
					if(projectId==null||dbname==null||host==null||username==null){
						
						continue;
					}
					
					DBProperty pro = new DBProperty(host.toString(), dbname.toString(), fileName);
	
					long start = System.currentTimeMillis();
					int exitVal = 0;
					try{
						exitVal = MySqlImportAndExport.importSqlBySource4NoCreateDB(pro);
					}catch(Throwable e){
						exitVal = -1;
					}
					long end = System.currentTimeMillis();
					System.out.println("####-------向数据库"+dbname+" 导入存储过程【运行代码:"+exitVal+" ; 耗时:"+(end-start)/(1000*60)+"m】");
				}
				
				session.flush();
				session.close();
				//切回原来的数据源
				DataSourceContextHolder.setDataSourceType(currentDataSource);
			
			}
		}catch(Throwable e){
			if(session!=null){
				session.close();
			}
		}
	}
	
}

I.java

package util.base;


/**
 * @author jx
 * @date 2015-08-25
 */
public final class I {
	
	public static final String sys_existentProjectsWithDataSource= "existentProjectsWithDataSource";
	
}


package util.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 专门处理--返回给前台控件格式化的数据,多以json为主
 * @author 
 *
 */
/**
 * @author jx
 * @date 2015-08-25
 */
public class PrintHelper {
	Log log = LogFactory.getLog(PrintHelper.class);
	/**
	 * @return object json:{}
	 * @param response
	 * @param olist
	 * @param total
	 * @throws IOException
	 */
	public static <T> void sendJsonMap(HttpServletResponse response,T olist,int total) throws IOException {
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("total", total);
		map.put("rows",olist);
		String  jsonstr= JSONObject.fromObject(map).toString();
		System.out.println("(***)"+jsonstr);
		response.setContentType("text/plain");
		response.setCharacterEncoding("utf-8");
		PrintWriter out=response.getWriter();
		out.print(jsonstr);
		out.close();
		out.flush();
		
	}
	
	/**
	 * @return object json:{}
	 * @param response
	 * @param map
	 * @throws IOException
	 */
	public static <T> void sendJsonObject(HttpServletResponse response,T o) throws IOException {
	
		String  jsonstr= JSONObject.fromObject(o).toString();
		
		response.setContentType("text/plain");
		response.setCharacterEncoding("utf-8");
		PrintWriter out=response.getWriter();
		out.print(jsonstr);
		out.close();
		out.flush();
		
	}
	/**
	 * @return array json:[]
	 * @param response
	 * @param t
	 * @throws IOException
	 */
	public static    void sendJsonArray(HttpServletResponse response,List  t) throws IOException{
		/*Map<String,Object> map=new HashMap<String, Object>();
		map.put("total", total);
		map.put("rows",olist);*/
		String  jsonstr=JSONArray.fromObject(t).toString();
		response.setContentType("text/plain");
		response.setCharacterEncoding("utf-8");
		PrintWriter out=response.getWriter();
		out.print(jsonstr);
		out.close();
		out.flush();
	}
	public static <T> void sendJsonString(HttpServletResponse response,T  str) throws IOException{
		//response.setContentType("text/html;charset=gbk");
		response.setContentType("text/plain");
		response.setCharacterEncoding("utf-8");
		PrintWriter out=response.getWriter();
		out.print(str);
		out.close();
		out.flush();
	}

	public static <T> void sendJsonHtm(HttpServletResponse response,T  htm) throws IOException{
		//response.setContentType("text/html;charset=gbk");
		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		PrintWriter out=response.getWriter();
		out.print(htm);
		out.close();
		out.flush();
	} 
	/**
	 * 统一下载任意类型文件(浏览器自动识别文件类型)
	 * @param response
	 * @param file
	 * @param customFileName
	 * @throws UnsupportedEncodingException
	 */
	public static void downloadFile4AnyFile(HttpServletResponse response,File file,String customFileName) throws UnsupportedEncodingException{
		if(!file.exists()){
			return;
		}
		if(StringUtils.isBlank(customFileName)){
			customFileName = file.getName();
		}
        //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型  
        response.setContentType("multipart/form-data");  
        //2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf)  
        response.setHeader("Content-Disposition", "attachment;fileName="+URLEncoder.encode(customFileName,"UTF-8"));  
        ServletOutputStream out = null;  
        FileInputStream inputStream = null;
        try {  
            inputStream = new FileInputStream(file);  
  
            //3.通过response获取ServletOutputStream对象(out)  
            out = response.getOutputStream();  
  
            int b = 0;  
            byte[] buffer = new byte[1024];  
            while (b != -1){  
                b = inputStream.read(buffer);  
                //4.写到输出流(out)中  
                if(b!=-1){
                	out.write(buffer,0,b);  
                }
                
            }  
            inputStream.close();  
            out.flush();  
            out.close();  
          
  
        } catch (IOException e) { 
        	try {
	        	if(inputStream!=null){
					inputStream.close();
	        	}
	        	if(out!=null){
	        		out.flush();  
	                out.close();  
	        	}
        	} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}  
            e.printStackTrace();  
        }  
	}
	/**
	 * 统一下载Excel类型文件
	 * @param response
	 * @param file
	 * @param customFileName
	 * @throws UnsupportedEncodingException
	 */
	public static void downloadFile4Excel(HttpServletResponse response,File file,String customFileName) throws UnsupportedEncodingException{
		if(!file.exists()){
			return;
		}
		if(StringUtils.isBlank(customFileName)){
			customFileName = file.getName();
		}
		if(!customFileName.endsWith(".xlsx")&&!customFileName.endsWith(".xls")){
			customFileName +=".xlsx";
		}
		response.setCharacterEncoding("utf-8");
		response.setContentType("application/vnd.ms-excel");
        //response.setContentType("multipart/form-data");
		 /**解决下载的中文名无法显示的问题
         * response.setHeader("Content-Disposition", "attachment; filename=" +  URLEncoder.encode(filename, "UTF-8")); 
         * 
         * fileName = fileName.Replace("+", " ");
         */
        response.setHeader("Content-Disposition", "attachment;fileName="
                + URLEncoder.encode(customFileName,"UTF-8").replace("+", " "));
       
        InputStream inputStream = null;
        OutputStream os = null;
        try {
          
            inputStream = new FileInputStream(file);
 
            os = response.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
 
             // 这里主要关闭。
            os.close();
            inputStream.close();
        
        } catch (Exception e) {
        	 try {
        		  if(os!=null){
        				os.close();
        		  }
        		  if(inputStream!=null){
        			  inputStream.close();
        		  }
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
             
            e.printStackTrace();
        }
            //  返回值要注意,要不然就出现下面这句错误!
            //java+getOutputStream() has already been called for this response

	}
}

下面是util.db包

package util.db;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**

 * @author  
 * @version 
 */
public class CallCmd {
	public static void main(String[] args) {
		Runtime rt = Runtime.getRuntime();
		// 执行CMD命令,能够云行本地程序
		Process p = null;

		// String path =
		// "F:\\Program Files (x86)\\Tencent\\QQ\\QQProtect\\Bin\\QQProtect.exe";
		//
		// try {
		// p = rt.exec(path);
		// } catch (IOException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }

		// 调用浏览器,可以打开指定的网站
		// String
		// path="C:\\Users\\jrs521wlh\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe";
		// String chrome ="www.google.com";
		// String[] cmd={path,chrome};
		// try {
		// p = rt.getRuntime().exec(cmd);
		// } catch (IOException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		printProcess();
		System.out.println("开始查找进程");
		if (findProcess("QQ.exe")) {
			System.out.println("查找进程存在");

		} else {
			System.out.println("不存在进程");

		}

	}

	// 打印所有的进程信息
	public static void printProcess() {
		BufferedReader buff = null;

		Process p = null;

		try {
			// 打印所有进程的信息
			p = Runtime.getRuntime().exec("tasklist");
			// 用流读出来
			buff = new BufferedReader(new InputStreamReader(p.getInputStream()));

			System.out.println("打印进程系信息");

			String temp = null;
			// 遍历
			while ((temp = buff.readLine()) != null) {
				System.out.println(buff.readLine());

			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (buff != null) {
				try {
					buff.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

	}

	/**
	 * 查看进程是否运行
	 * 
	 * @Title: 
	 * @data:
	 * @author:
	 * 
	 * @return
	 */
	public static boolean findProcess(String processName) {

		BufferedReader buff = null;

		try {
			// 下面这句是列出含有processName的所有进程图形名字
			Process p = Runtime.getRuntime().exec("tasklist");
			buff = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String temp = null;
			while ((temp = buff.readLine()) != null) {
				System.out.println(temp);
				if (temp.contains(processName)) {
					return true;

				}

			}
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} finally {
			if (buff != null) {
				try {
					buff.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

	}
}

package util.db;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import entity.DatabaseBean;

/**
 * 创建数据源配置文件程
 * 
 * @author jx
 * 
 */
public class ConfigFileCreator {
	/**
	 * 数据源模板xml的占位符
	 */
	private static final String placeholder_dataSourceId = "${dataSourceId}";
	private static final String placeholder_driverClassName = "${driverClassName}";
	private static final String placeholder_url = "${url}";
	private static final String placeholder_username = "${username}";
	private static final String placeholder_password = "${password}";
	public static final String classPathCfgCatalog = "config";
	private static final String dataSourceCfgTemplatePath = classPathCfgCatalog+"/dataSourceCfgTemplate.vm";

	// private static final String defaultConfigFile
	// =classPathCfgCatalog+"/db.properties";
	private DatabaseBean database;

	public ConfigFileCreator(DatabaseBean database) {
		this.database = database;

	}

	public String create() {
		String cfgFileStr = this.getTemplateString();
		String fileName = createCfgFile(this.database, cfgFileStr);
		return fileName;
	}
	
	public static  String getNameByClassPath(String fileName){
		return "classpath:" + ConfigFileCreator.classPathCfgCatalog + "/" + fileName;

	}
	/**
	 * 读取配置文件,并替换产生数据源配置文件
	 * 
	 * @param dataSourceName
	 * @param url
	 * @param username
	 * @param password
	 */
	private String createCfgFile(DatabaseBean database, String cfgFileStr) {
		String cfgFile = cfgFileStr;
		String url = database.getUrlPrefix() + database.getHost() + ":"
				+ database.getPort() + "/" + database.getDbName()
				+ database.getUrlSuffix();
		// 替换
		cfgFile = cfgFile
				.replace(placeholder_dataSourceId,
						database.getDataSourceId())
				.replace(placeholder_url, url)
				.replace(placeholder_driverClassName,
						database.getDriverClassNameValue())
				.replace(placeholder_username, database.getUsername())
				.replace(placeholder_password, database.getPwd());

		String cfgStorePath = ConfigFileCreator.class.getClassLoader()
				.getResource(classPathCfgCatalog).getPath();
		
		String fileName = database.getDataSourceId() + ".xml";
		String path = cfgStorePath+ File.separator+fileName;
		System.out.println("path:" + path);
		// 将替换好的串生成xml文件
		try {
			FileOutputStream outputStream = new FileOutputStream(path);

			OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
					outputStream, "utf-8");

			BufferedWriter bufferedWriter = new BufferedWriter(
					outputStreamWriter);

			bufferedWriter.write(cfgFile);

			bufferedWriter.flush();

			bufferedWriter.close();
			return fileName;

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	private String getTemplateString() {

		InputStream in = ConfigFileCreator.class.getClassLoader()
				.getResourceAsStream(dataSourceCfgTemplatePath);
		InputStreamReader reader = null;
		try {
			reader = new InputStreamReader(in, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(reader);
			String line = null;
			// 行分隔符
			String separator = System.getProperty("line.separator");
			StringBuffer sb = new StringBuffer();
			while ((line = bufferedReader.readLine()) != null) {
				sb.append(line + separator);
			}
			bufferedReader.close();
			return sb.toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

}

package util.db;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;


/**
 * 读取配置文件config/db.properties
 * @author 
 *
 */
public class ConfigFileReader {
	

	private String targetConfigFile ;
	
	public ConfigFileReader(String targetConfigFile) {
		this.targetConfigFile = targetConfigFile;
	}

	public  Properties reader() {
		InputStream in = ConfigFileReader.class.getClassLoader().getResourceAsStream(targetConfigFile);
		Properties p = new Properties();   
		try {    
		   p.load(in);    
		} catch (IOException e1) {    
		   e1.printStackTrace();    
		}    
		return p;
	}
	
}


package util.db;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.springframework.orm.hibernate4.HibernateTemplate;

public class DataSourceContextHolder {

	private static final ThreadLocal contextHolder = new ThreadLocal();

	public static void setDataSourceType(String dataSourceName) {
		contextHolder.set(dataSourceName);
	}

	public static String getDataSourceName() {
		return (String) contextHolder.get();
	}

	/**
	 * 主库
	 * @param hibernateTemplate
	 * @return
	 */
	public synchronized static Session getSystemDB(HibernateTemplate hibernateTemplate) {
		contextHolder.set("defaultDataSource");
		return hibernateTemplate.getSessionFactory().openSession();
	}
	/**
	 * 从库
	 * @param hibernateTemplate
	 * @param projectId
	 * @return
	 */
	public synchronized static Session getProjectDB( HibernateTemplate hibernateTemplate,String projectId) {
		if(!StringUtils.isBlank(projectId)){
			contextHolder.set("ds_" + projectId);
			return hibernateTemplate.getSessionFactory().openSession();
		}else{
			return null;
		}
		
	}

}

package util.db;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate4.HibernateTemplate;

import util.base.I;
import entity.DatabaseBean;
/**
 * 系统启动后,自动加载从数据库
 * @author jx
 *
 */
public final class DataSourceManager {
	static Log log = LogFactory.getLog(DataSourceManager.class);
	public static final String mainProjectId="defaultDataSource";
	public static final String mainDataSourceId="defaultDataSource";
	private static final Map<String,String> existentProjectsWithDataSource = new HashMap<String,String>();

	/**
	 * 项目启动后,数据源第一次初始化工作
	 * @param sc
	 */
	public static void init(ApplicationContext ac,ServletContext sc) {
		//项目启动后,只有主库是默认连接好的数据源
		HibernateTemplate hibernateTemplate = ac.getBean(HibernateTemplate.class);
		
		List<DatabaseBean> list = (List<DatabaseBean>) hibernateTemplate.find(" from DatabaseBean");
		//key:projectId ;value:datasourceId
		
		//首先把系统的datasource放入
		existentProjectsWithDataSource.put(DataSourceManager.mainProjectId, DataSourceManager.mainDataSourceId);
		if(list!=null){
			for(DatabaseBean db:list){
				System.out.println(db);
				if(!"off".equals(db.getStatus())){
					log.info("准备为projectId:"+db.getProjectId()+" 创建dataSource:"+db.getDataSourceId());
					new MyDataSource(db,ac).create();
					existentProjectsWithDataSource.put(db.getProjectId(), db.getDataSourceId());
					log.info("创建dataSource:"+db.getDataSourceId()+" 完毕");

				}else{
					log.info("忽略projectId:"+db.getProjectId()+" , status=off.");
				}
				
			}
		}
		
		sc.setAttribute(I.sys_existentProjectsWithDataSource, existentProjectsWithDataSource);
	}
	
	/**
	 * sys_db中存在记录但是没有数据源,就创建
	 * @param ac
	 * @param db
	 */
	public static void createNewDataSource4existentDB(ApplicationContext ac,DatabaseBean db){
		if(existentProjectsWithDataSource.get(db.getProjectId())==null){
			//初始化数据源到spring中
			new MyDataSource(db,ac).create();
			//放入map映射中
			existentProjectsWithDataSource.put(db.getProjectId(), db.getDataSourceId());
			log.info("新增数据源完成");
		}
		

	}
}

package util.db;

public class DBProperty{
	public String username;//用户名  
	public String password ;//密码  
	public String host ;//导入的目标数据库所在的主机  
	public String port ;//使用的端口号  
	public String importDatabaseName ;//导入的目标数据库的名称  
    //应该存在服务器
	public String importPath;//导入的目标文件所在的位置 
	public DBProperty(String host,String port, String username, String password, 
			String importDatabaseName, String importPath) {
		this.username = username;
		this.password = password;
		this.host = host;
		this.port = port;
		this.importDatabaseName = importDatabaseName;
		this.importPath = importPath;
	}
	public DBProperty(String host,String username, String password, 
			String importDatabaseName, String importPath) {
		this.username = username;
		this.password = password;
		this.host = host;
		this.port = "3306";
		this.importDatabaseName = importDatabaseName;
		this.importPath = importPath;
	}
	public DBProperty(String host,String importDatabaseName, String importPath) {
		this.username = "root";
		this.password = "root";
		this.host = host;
		this.port = "3306";
		this.importDatabaseName = importDatabaseName;
		this.importPath = importPath;
	}
}

package util.db;

import java.util.Map;

import org.springframework.jdbc.datasource.lookup.DataSourceLookup;


public class DynamicDataSource extends MyAbstractRoutingDataSource {

	/* 
	 *
	 */
	@Override
	public Object determineCurrentLookupKey() {
		return DataSourceContextHolder.getDataSourceName();
	}

	@Override
	public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
		super.setDataSourceLookup(dataSourceLookup);
	}

	@Override
	public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
		super.setDefaultTargetDataSource(defaultTargetDataSource);
	}

	@Override
	public void setTargetDataSources(Map targetDataSources) {
		super.setTargetDataSources(targetDataSources);
		super.afterPropertiesSet();
	}
	
}

package util.db;

import java.io.IOException;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.ChildBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * 动态加载数据源
 * 
 * @author jx
 * 
 */
public class DynamicLoadBean implements ApplicationContextAware {

	private ConfigurableApplicationContext applicationContext = null;

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {

		this.applicationContext = (ConfigurableApplicationContext) applicationContext;
	}

	public ConfigurableApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * 1.配置文件的位置固定 2.配置文件中bean的名字已确定
	 * 
	 * @param configLocationString
	 */
	public void loadBean(String fileName) {
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(
				(BeanDefinitionRegistry) getApplicationContext()
						.getBeanFactory());
		beanDefinitionReader.setResourceLoader(getApplicationContext());
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(
				getApplicationContext()));
		try {
			beanDefinitionReader.loadBeanDefinitions(getApplicationContext()
					.getResources(fileName));
		} catch (BeansException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 未知方法
	 * @param beanName
	 * @param parentName
	 */
	@Deprecated
	public void registBean(String beanName, String parentName) {
		DefaultListableBeanFactory fcy = (DefaultListableBeanFactory) applicationContext
				.getAutowireCapableBeanFactory();
		BeanDefinition beanDefinition = new ChildBeanDefinition(parentName);
		fcy.registerBeanDefinition(beanName, beanDefinition);
	}
}


package util.db;
/**
 * 该类完全复制org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource抽象类,
 * 只是增加了 addDataSource(Object,Object) 方法,不然,就要改spring的jar包了
 */
/*
 * Copyright 2002-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.AbstractDataSource;
import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.util.Assert;

/**
 * Abstract {@link javax.sql.DataSource} implementation that routes {@link #getConnection()}
 * calls to one of various target DataSources based on a lookup key. The latter is usually
 * (but not necessarily) determined through some thread-bound transaction context.
 *
 * @author Juergen Hoeller
 * @since 2.0.1
 * @see #setTargetDataSources
 * @see #setDefaultTargetDataSource
 * @see #determineCurrentLookupKey()
 */
public abstract class MyAbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {

	private Map<Object, Object> targetDataSources;

	private Object defaultTargetDataSource;

	private boolean lenientFallback = true;

	private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

	private Map<Object, DataSource> resolvedDataSources;

	private DataSource resolvedDefaultDataSource;

	/**
	 * Specify the map of target DataSources, with the lookup key as key.
	 * The mapped value can either be a corresponding {@link javax.sql.DataSource}
	 * instance or a data source name String (to be resolved via a
	 * {@link #setDataSourceLookup DataSourceLookup}).
	 * <p>The key can be of arbitrary type; this class implements the
	 * generic lookup process only. The concrete key representation will
	 * be handled by {@link #resolveSpecifiedLookupKey(Object)} and
	 * {@link #determineCurrentLookupKey()}.
	 */
	public void setTargetDataSources(Map<Object, Object> targetDataSources) {
		this.targetDataSources = targetDataSources;
	}
	
	/**@author jiangxu**/
	public void addDataSource(Object key,Object dataSource){
		
		this.targetDataSources.put(key, dataSource);
		
		setTargetDataSources(this.targetDataSources);
	}
	
	
	
	
	
	/**
	 * Specify the default target DataSource, if any.
	 * <p>The mapped value can either be a corresponding {@link javax.sql.DataSource}
	 * instance or a data source name String (to be resolved via a
	 * {@link #setDataSourceLookup DataSourceLookup}).
	 * <p>This DataSource will be used as target if none of the keyed
	 * {@link #setTargetDataSources targetDataSources} match the
	 * {@link #determineCurrentLookupKey()} current lookup key.
	 */
	public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
		this.defaultTargetDataSource = defaultTargetDataSource;
	}

	/**
	 * Specify whether to apply a lenient fallback to the default DataSource
	 * if no specific DataSource could be found for the current lookup key.
	 * <p>Default is "true", accepting lookup keys without a corresponding entry
	 * in the target DataSource map - simply falling back to the default DataSource
	 * in that case.
	 * <p>Switch this flag to "false" if you would prefer the fallback to only apply
	 * if the lookup key was <code>null</code>. Lookup keys without a DataSource
	 * entry will then lead to an IllegalStateException.
	 * @see #setTargetDataSources
	 * @see #setDefaultTargetDataSource
	 * @see #determineCurrentLookupKey()
	 */
	public void setLenientFallback(boolean lenientFallback) {
		this.lenientFallback = lenientFallback;
	}

	/**
	 * Set the DataSourceLookup implementation to use for resolving data source
	 * name Strings in the {@link #setTargetDataSources targetDataSources} map.
	 * <p>Default is a {@link JndiDataSourceLookup}, allowing the JNDI names
	 * of application server DataSources to be specified directly.
	 */
	public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
		this.dataSourceLookup = (dataSourceLookup != null ? dataSourceLookup : new JndiDataSourceLookup());
	}


	public void afterPropertiesSet() {
		if (this.targetDataSources == null) {
			throw new IllegalArgumentException("Property 'targetDataSources' is required");
		}
		this.resolvedDataSources = new HashMap<Object, DataSource>(this.targetDataSources.size());
		for (Map.Entry entry : this.targetDataSources.entrySet()) {
			Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
			DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
			this.resolvedDataSources.put(lookupKey, dataSource);
		}
		if (this.defaultTargetDataSource != null) {
			this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
		}
	}

	/**
	 * Resolve the specified data source object into a DataSource instance.
	 * <p>The default implementation handles DataSource instances and data source
	 * names (to be resolved via a {@link #setDataSourceLookup DataSourceLookup}).
	 * @param dataSource the data source value object as specified in the
	 * {@link #setTargetDataSources targetDataSources} map
	 * @return the resolved DataSource (never <code>null</code>)
	 * @throws IllegalArgumentException in case of an unsupported value type
	 */
	protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException {
		if (dataSource instanceof DataSource) {
			return (DataSource) dataSource;
		}
		else if (dataSource instanceof String) {
			return this.dataSourceLookup.getDataSource((String) dataSource);
		}
		else {
			throw new IllegalArgumentException(
					"Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource);
		}
	}


	public Connection getConnection() throws SQLException {
		return determineTargetDataSource().getConnection();
	}

	public Connection getConnection(String username, String password) throws SQLException {
		return determineTargetDataSource().getConnection(username, password);
	}

	/**
	 * Retrieve the current target DataSource. Determines the
	 * {@link #determineCurrentLookupKey() current lookup key}, performs
	 * a lookup in the {@link #setTargetDataSources targetDataSources} map,
	 * falls back to the specified
	 * {@link #setDefaultTargetDataSource default target DataSource} if necessary.
	 * @see #determineCurrentLookupKey()
	 */
	protected DataSource determineTargetDataSource() {
		Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
		Object lookupKey = determineCurrentLookupKey();
		DataSource dataSource = this.resolvedDataSources.get(lookupKey);
		if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
			dataSource = this.resolvedDefaultDataSource;
		}
		if (dataSource == null) {
			throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
		}
		return dataSource;
	}


	/**
	 * Resolve the given lookup key object, as specified in the
	 * {@link #setTargetDataSources targetDataSources} map, into
	 * the actual lookup key to be used for matching with the
	 * {@link #determineCurrentLookupKey() current lookup key}.
	 * <p>The default implementation simply returns the given key as-is.
	 * @param lookupKey the lookup key object as specified by the user
	 * @return the lookup key as needed for matching
	 */
	protected Object resolveSpecifiedLookupKey(Object lookupKey) {
		return lookupKey;
	}

	/**
	 * Determine the current lookup key. This will typically be
	 * implemented to check a thread-bound transaction context.
	 * <p>Allows for arbitrary keys. The returned key needs
	 * to match the stored lookup key type, as resolved by the
	 * {@link #resolveSpecifiedLookupKey} method.
	 */
	protected abstract Object determineCurrentLookupKey();

}


package util.db;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate4.HibernateTemplate;

import entity.DatabaseBean;

/**
 * 创建、备份数据库
 * 
 * @author jx
 * 
 */
public class MyDatabase {
	public static final String configFile = "config/config.properties";
	private String projectId;
	private String defaultDBName;
	private HibernateTemplate hibernateTemplate;
	
	/*public MyDatabase(){
		
	}*/
	public MyDatabase(HibernateTemplate hibernateTemplate, String projectId) {
		this.hibernateTemplate = hibernateTemplate;
		this.projectId = projectId;
		this.defaultDBName = "ds_"+this.projectId;
	}

	public DatabaseBean copyMaindbByDBName(String dbName) throws Exception {
		InputStream is = MyDatabase.class.getClassLoader().getResourceAsStream(
				configFile);
		Properties pro = new Properties();
		pro.load(is);
		
		// 备份主库
		int status_backup = MySqlImportAndExport.export_high(pro);
		
		if(status_backup!=0){
			throw new Exception("创建项目过程中,备份主库失败!!");
		}
		// 将新库默认库名改一下
		if(!StringUtils.isBlank(dbName)){
			pro.put("importDB.dbName", this.defaultDBName);
		}
		
		DBProperty properties = new DBProperty(pro.getProperty("importDB.host"), this.defaultDBName, pro.getProperty("importDB.importPath"));
		// 建库
		MySqlImportAndExport.importSqlBySource4CreateDB(properties);
		//导入数据
		MySqlImportAndExport.importSqlBySource4NoCreateDB(properties);
		
		//删除数据库文件
		File dbFile = new File(pro.get("backup.exportPath").toString());
		if(dbFile.exists()){
			dbFile.delete();
		}
		// 向主库插入数据源记录
		return this.insertDataSource4mainDB(pro);
//		return null;
	}
	
	public DatabaseBean insertDataSource4mainDB(Properties pro) {
		// 创建数据源记录
		// 获取建库的默认信息
		DatabaseBean db = new DatabaseBean();
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
		String id = sf.format(new Date());
		db.setId(this.projectId);
		db.setProjectId(this.projectId);
		db.setDbName(this.defaultDBName);
		db.setDataSourceId(this.defaultDBName);
		db.setDriverClassNameValue(pro.getProperty("main.driver"));
		db.setUrlPrefix(pro.getProperty("dataSourceRecord.urlPrefix"));
		db.setHost(pro.getProperty("importDB.host"));
		db.setPort(pro.getProperty("importDB.port"));
		db.setUrlSuffix(pro.getProperty("dataSourceRecord.urlSuffix"));
		db.setUsername(pro.getProperty("importDB.username"));
		db.setPwd(pro.getProperty("importDB.password"));
		db.setCreatedate(id);
		db.setStatus("on");
		
		//保存当前数据源
		String currentDataSourceId = DataSourceContextHolder.getDataSourceName();
		//切换到主库中
		DataSourceContextHolder.setDataSourceType(DataSourceManager.mainDataSourceId);

		SessionFactory factory = hibernateTemplate.getSessionFactory();
		Session session = factory.openSession();
		session.beginTransaction();
		session.save(db);
		session.getTransaction().commit();
		session.close();
		//切换到初始状态
		DataSourceContextHolder.setDataSourceType(currentDataSourceId);
		return db;
	}

	public static void main(String[] args) throws IOException, InterruptedException {
		DBProperty pro = new DBProperty("192.168.0.202", "b", "d:/a.sql");
		// 建库,导入数据
		long start = System.currentTimeMillis();
		int exitVal = MySqlImportAndExport.importSqlBySource4CreateDB(pro);

		
		long end = System.currentTimeMillis();
		System.out.println("耗时:"+(end-start)/(1000*60)+"m");
		
	}
	
}

package util.db;

import java.io.File;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.ApplicationContext;

import entity.DatabaseBean;

public class MyDataSource {
	private DatabaseBean database;
	private ApplicationContext ac;

	public MyDataSource(DatabaseBean db, ApplicationContext ac) {
		this.database = db;
		this.ac = ac;
	}

	public MyDataSource create() {
		String dataSourceId = this.database.getDataSourceId();
		
		// 动态创建数据源配置文件
//		ConfigFileCreator.createConfigFile(dataSourceName, url);
		String fileName = new ConfigFileCreator(this.database).create();
		// 加载刚刚生成的数据源配置文件
		DynamicLoadBean dynamicBeanLoad = (DynamicLoadBean) ac.getBean("dynamicLoadBean");
		dynamicBeanLoad.loadBean(ConfigFileCreator.getNameByClassPath(fileName));
		
		BasicDataSource dataSource = (BasicDataSource) ac.getBean(dataSourceId);

		//获取动态数据源
		DynamicDataSource dynamicDataSource = (DynamicDataSource) ac.getBean("dynamicDataSource");

		//将数据源放入DynamicDataSource中,统一动态切分
		dynamicDataSource.addDataSource(dataSourceId, dataSource);
		
		DataSourceContextHolder.setDataSourceType(dataSourceId);
		//删除配置文件
		String path = MyDataSource.class.getResource("/config").getPath();
		File file = new File(path+File.separator+fileName);
		if(file.exists()){
			file.delete();
		}
		return this;
	}

	public static void main(String[] args) {
		String fileName = MyDataSource.class.getResource("/config").getPath();
//		File file = new File(fileName);
		System.out.println(fileName);
		/*if(!file.exists()){
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else{
			file.delete();
		}*/
		
	}

}


package util.db;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;

/**
 * 在进行导出的时候,需要注意命令语句的运行环境,如果已经将mysql安装路径下的bin加入到
 * 系统的path变量中,那么在导出的时候可以直接使用命令语句,否则,就需要在执行命令语句的
 * 时候加上命令所在位置的路径,即mysql安装路径想的bin下的mysqldump命令
 * 
 * 目前只支持最多连续2条命令
 * @author jx
 * 
 */
public class MySqlImportAndExport {

	// 查询数据库信息
	// SELECT * FROM information_schema.SCHEMATA where SCHEMA_NAME='aa';
	// mysqldump -uusername -ppassword -hhost -Pport exportDatabaseName >
	// exportPath

	/**
	 * 根据属性文件的配置导出指定位置的指定数据库到指定位置
	 * 
	 * 这个方法在命令执行过程中无法接受返回值,故任务完成的时间无法确定, 必须通过Thread.sleep(N秒)的方式不确定睡眠的等待db备份结束
	 * 
	 * @param properties
	 * @throws IOException
	 */
	/*
	 * @Deprecated public static void export(Properties properties) throws
	 * IOException { Runtime runtime = Runtime.getRuntime(); String command =
	 * getExportCommand(properties); String ss = ""; try {
	 * runtime.exec(command);// 这里简单一点异常我就直接往上抛 //睡眠3秒,等待备份文件生成完毕 //
	 * Thread.sleep(3000); } catch (Exception e) { ss = e.toString(); } }
	 */
	/**
	 * 根据属性文件的配置导出指定位置的指定数据库到指定位置 // mysqldump -uusername -ppassword -hhost
	 * -Pport exportDatabaseName > exportPath export()的升级版,改良了无需采用不确定睡眠的等待
	 * 
	 * @param properties
	 * @throws IOException
	 * @throws InterruptedException
	 * @return int [0正常,非0不正常]
	 */
	public static int export_high(Properties properties) throws IOException,
			InterruptedException {
		Runtime runtime = Runtime.getRuntime();
		String command = getExportCommand(properties);
		Process proc = runtime.exec(command);// 这里简单一点异常我就直接往上抛
		InputStream stderr = proc.getInputStream();
		InputStreamReader isr = new InputStreamReader(stderr);
		BufferedReader br = new BufferedReader(isr);
		String line = null;
		System.out.println("<msg>----------------------------");
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		System.out.println("");
		int exitVal = proc.waitFor();
		/**
		 * exitVal==0正常,非0不正常
		 */
		System.out.println("Process exitValue[0正常,非0不正常]: " + exitVal);
		br.close();
		isr.close();
		stderr.close();
		System.out.println("----------------------------</msg>");
		return exitVal;
	}
	/**
	 * 单独执行一条命令
	 * @param command
	 * @return
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static int execOneCommand(String command) throws IOException,
			InterruptedException {
		if (StringUtils.isBlank(command)) {
			return 0;
		}
		Runtime runtime = Runtime.getRuntime();
		Process proc = runtime.exec(command);// 这里简单一点异常我就直接往上抛
		InputStream stderr = proc.getInputStream();
		InputStreamReader isr = new InputStreamReader(stderr);
		BufferedReader br = new BufferedReader(isr);
		String line = null;
		System.out.println("<msg>----------------------------");
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		int exitVal = proc.waitFor();
		/**
		 * exitVal==0正常,非0不正常
		 */
		System.out.println("Process exitValue[0正常,非0不正常]: " + exitVal);
		br.close();
		isr.close();
		stderr.close();
		System.out.println("----------------------------</msg>");
		return exitVal;
	}

	/**
	 * 利用属性文件提供的配置来拼装命令语句 在拼装命令语句的时候有一点是需要注意的:一般我们在命令窗口直接使用命令来
	 * 进行导出的时候可以简单使用“>”来表示导出到什么地方,即mysqldump -uusername -ppassword databaseName
	 * > exportPath, 但在Java中这样写是不行的,它需要你用-r明确的指出导出到什么地方,如: mysqldump -uusername
	 * -ppassword databaseName -r exportPath。
	 * 
	 * @param properties
	 * @return
	 */
	private static String getExportCommand(Properties properties) {
		StringBuffer command = new StringBuffer();
		String username = properties.getProperty("backup.username");// 用户名
		String password = properties.getProperty("backup.password");// 用户密码
		String exportDatabaseName = properties.getProperty("backup.dbName");
		String host = properties.getProperty("backup.host");// 从哪个主机导出数据库,如果没有指定这个值,则默认取localhost
		String port = properties.getProperty("backup.port");// 使用的端口号
		// 应该存在服务器
		String exportPath = properties.getProperty("backup.exportPath");// 导出路径

		// 注意哪些地方要空格,哪些不要空格
		command.append("mysqldump -u").append(username)
				.append(" -p")
				.append(password)
				// 密码是用的小p,而端口是用的大P。
				.append(" -h").append(host).append(" -P").append(port)
				.append(" ").append(exportDatabaseName).append(" -r ")
				.append(exportPath);
		return command.toString();
	}

	
	/**
	 * 将sql文件导入到存在的DB中 exitVal==0正常,非0不正常
	 * 
	 * @param properties
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static int importSqlBySource4CreateDB(DBProperty properties)
			throws IOException, InterruptedException {
		Runtime runtime = Runtime.getRuntime();
		// 因为在命令窗口进行mysql数据库的导入一般分三步走,所以所执行的命令将以字符串数组的形式出现
		String cmdarray[] = getCommond4CreateDB(properties);// 根据属性文件的配置获取数据库导入所需的命令,组成一个数组
		// runtime.exec(cmdarray);//这里也是简单的直接抛出异常
		Process process = runtime.exec(cmdarray[0]);
		// 执行了第一条命令以后已经登录到mysql了,所以之后就是利用mysql的命令窗口
		// 进程执行后面的代码
		OutputStream os = process.getOutputStream();
		OutputStreamWriter writer = new OutputStreamWriter(os);
		// 命令2和命令1的交互
		writer.write(cmdarray[1] + "\r\n");

		writer.flush();
		writer.close();
		os.close();

		InputStream stderr = process.getErrorStream();
		InputStreamReader isr = new InputStreamReader(stderr);
		BufferedReader br = new BufferedReader(isr);
		String line = null;
		System.out.println("<msg>-------importData-----start----------------");
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		int exitVal = process.waitFor();
		/**
		 * exitVal==0正常,非0不正常
		 */
		System.out.println("Process exitValue[0正常,非0不正常]: " + exitVal);
		br.close();
		isr.close();
		stderr.close();

		// long end = System.currentTimeMillis();
		System.out.println("-------importData------end---------------</msg>");
		return exitVal;
	}
	/**
	 * 建库命令
	 * @param properties
	 * @return
	 */
	private static String[] getCommond4CreateDB(DBProperty pro) {
		String username = pro.username;// 用户名
		String password = pro.password;// 密码
		String host = pro.host;// 导入的目标数据库所在的主机
		String port = pro.port;// 使用的端口号
		String importDatabaseName = pro.importDatabaseName;// 导入的目标数据库的名称
		// 应该存在服务器
//		String importPath = pro.importPath;// 导入的目标文件所在的位置
		// 第一步,获取登录命令语句
		String loginCommand = new StringBuffer().append("mysql -u")
				.append(username).append(" -p").append(password).append(" -h")
				.append(host).append(" -P").append(port).toString();
		// 第二步 建库
		String sql_createDB = "create database " + importDatabaseName + ";";
		
		// 需要返回的命令语句数组
		String[] commands = new String[] { loginCommand, sql_createDB};
		return commands;
	}
	/**
	 * 将sql文件导入到存在的DB中 exitVal==0正常,非0不正常
	 * 
	 * @param properties
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static int importSqlBySource4NoCreateDB(DBProperty properties)
			throws IOException, InterruptedException {
		Runtime runtime = Runtime.getRuntime();
		// 因为在命令窗口进行mysql数据库的导入一般分三步走,所以所执行的命令将以字符串数组的形式出现
		String cmdarray[] = getCommandByImportSqlFile(properties);// 根据属性文件的配置获取数据库导入所需的命令,组成一个数组
		// runtime.exec(cmdarray);//这里也是简单的直接抛出异常
		Process process = runtime.exec(cmdarray[0]);
		// 执行了第一条命令以后已经登录到mysql了,所以之后就是利用mysql的命令窗口
		// 进程执行后面的代码
		OutputStream os = process.getOutputStream();
		OutputStreamWriter writer = new OutputStreamWriter(os);
		// 命令2和命令1的交互
		writer.write(cmdarray[1] + "\r\n");

		writer.flush();
		writer.close();
		os.close();

		InputStream stderr = process.getErrorStream();
		InputStreamReader isr = new InputStreamReader(stderr);
		BufferedReader br = new BufferedReader(isr);
		String line = null;
		System.out.println("<msg>-------importData-----start----------------");
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		int exitVal = process.waitFor();
		/**
		 * exitVal==0正常,非0不正常
		 */
		System.out.println("Process exitValue[0正常,非0不正常]: " + exitVal);
		br.close();
		isr.close();
		stderr.close();

		// long end = System.currentTimeMillis();
		System.out.println("-------importData------end---------------</msg>");
		return exitVal;
	}

	
	/**
	 * 与getImportCommandBySource(Properties properties) 功能相同
	 * 暂时不支持中文字符(待调研source命令)
	 * 
	 * @param map
	 * @return
	 */

	private static String[] getCommandByImportSqlFile(DBProperty pro) {
		String username = pro.username;// 用户名
		String password = pro.password;// 密码
		String host = pro.host;// 导入的目标数据库所在的主机
		String port = pro.port;// 使用的端口号
		String importDatabaseName = pro.importDatabaseName;// 导入的目标数据库的名称
		// 应该存在服务器
		String importPath = pro.importPath;// 导入的目标文件所在的位置
		// 第一步,获取登录命令语句
		String loginCommand = new StringBuffer().append("mysql -u")
				.append(username).append(" -p").append(password).append(" -h")
				.append(host).append(" -P").append(port)
				.append("  --default-character-set=gbk  -D")
				.append(importDatabaseName).toString();

		// 第二步,获取导入的命令语句 (由于mysql 中source命令的规则,
		// \后边不能是. ;所以如果未见名带有点就麻烦了),故将\改为/
		String importCommand = "source " + importPath.replace("\\", "/") + ";";
		// 需要返回的命令语句数组
		String[] commands = new String[] { loginCommand, importCommand };
		return commands;
	}

}

jsp和js

project.js

/**
 * 显示项目列表
 */
function initProjectList(){
	//获取项目列表
	$.post('/multiDbDemo/project/listProjects.do',{},function(data){
		if(data&&data.total>0){
			var rows = data.rows;
			var htm = '';
			for(var i in rows){
				var projectId = rows[i].projectId;
				var projectName = rows[i].projectName;
				var userId = rows[i].userId;
				var pwd = rows[i].pwd;
				htm +='<tr id="id_'+i+'"><td>项目编号:'+projectId+'</td><td>项目名称:'+projectName+'</td><td>登录用户:'+userId+'</td><td>密码:'+pwd+'</td><td><a href="#" οnclick="deleteProject(\''+projectId+'\')">删除</a></td></tr>';
				
			}
			$('#id_adminIndex_projectList').append(htm);
		}
		
	},'json');
	
}
/**
 * 删除项目
 * @param projectId
 */
function deleteProject(projectId){

	$.post('/multiDbDemo/project/delProject.do',{projectId:projectId},function(data){
		if('success'==data){
			window.location.href='/multiDbDemo/adminIndex.jsp'
		}else{
			alert('系统异常');
		}
	});
}
/**
 * 跳转到新增项目页面
 */
function jump2Page(location,projectId){
	var page = '/multiDbDemo/login.jsp';
	if('addProject'==location){//新增项目也
		page='/multiDbDemo/addProject.jsp';

	}else if('login'==location){//退回登录页
		page='/multiDbDemo/login.jsp';

	}else if('addMsg'==location){//退回登录页
		page='/multiDbDemo/addMsg.jsp';
		if(projectId){
			page+='?projectId='+projectId;
		}

	}else if('home'==location){//退回登录页
		page='/multiDbDemo/home.jsp';
		if(projectId){
			page+='?projectId='+projectId;
		}

	}
	window.location.href=page;
}
/**
 * 新增项目
 */
function addProject(){
	var projectId = $('#id_addProject_projectId').val();
	var projectName = $('#id_addProject_projectName').val();
	var userId = $('#id_addProject_userId').val();
	var pwd = $('#id_addProject_pwd').val();
	
	
	if(!projectId||!projectName){
		alert("项目代码或项目名称不同为空");
	}
	$.post('/multiDbDemo/project/addProject.do',{projectId:projectId,projectName:projectName,userId:userId,pwd:pwd},function(data){
		if('success'==data){
			window.location.href='/multiDbDemo/adminIndex.jsp'
		}else if('isUsed'==data){
			alert('项目代码已经存在');
		}else{
			alert('系统异常');
		}
	});
	
}
/**
 * 初始化该(用户,密码)的项目列表
 * @param userId
 * @param pwd
 */
function initProjectListByUserIdAndPwd(userId,pwd){
	$.post('/multiDbDemo/project/listProjectsByUserIdAndPwd.do',{userId:userId,pwd:pwd},function(data){
		if(data&&data.total>0){
			var rows = data.rows;
			var htm = '';
			for(var i in rows){
				var projectId = rows[i].projectId;
				var projectName = rows[i].projectName;
				var userId = rows[i].userId;
				var pwd = rows[i].pwd;
				htm +='<tr><td>项目编号:'+projectId+'</td><td>项目名称:'+projectName+'</td><td>登录用户:'+userId+'</td><td>密码:'+pwd+'</td><td><a href="#" οnclick="comeInProject(\''+projectId+'\',\''+userId+'\')">进入</a></td></tr>';
				
			}
			$('#id_projectIndex_projectList').append(htm);
		}
	},'json');
}
/**
 * 进入项目
 * @param projectId
 */
function comeInProject(projectId,userId){
	window.location.href='/multiDbDemo/home.jsp?projectId='+projectId+'&userId='+userId;
}

/**
 * 初始化业务信息
 * @param projectId
 */
function initMsg(projectId){
	$.post('/multiDbDemo/project/getProject.do',{projectId:projectId},function(data){
		if(data&&data.userId){
			$('#id_home_userId').html(data.userId);
		}
		
	},'json');
	
	
	$.post('/multiDbDemo/project/listMsgByProjectId.do',{projectId:projectId},function(data){
		if(data&&data.total>0){
			var rows = data.rows;
			var htm = '';
			for(var i in rows){
				var name = rows[i].name;
				var note = rows[i].note;
				
				htm +='<tr><td>栏目:'+name+'</td><td>内容:'+note+'</td><td><a href="#" οnclick="delMsg(\''+projectId+'\',\''+name+'\')">删除</a></td></tr>';
				
			}
			$('#id_home_msgList').append(htm);
		}
	},'json');
}
/**
 * 删除具体某个项目库(从库)的栏目
 * @param projectId
 * @param name
 */
function delMsg(projectId,name){
	$.post('/multiDbDemo/project/delMsg.do',{projectId:projectId,name:name},function(data){
		if('success'==data){
			jump2Page('home', projectId);
		}else{
			alert('系统异常');
		}
	});
}

function addMsg(){
	var projectId = $('#id_addMsg_projectId').val();
	var name = $('#id_addMsg_name').val();
	var note = $('#id_addMsg_note').val();
	if(!projectId||!name){
		alert("栏目名称或所在项目不同为空");
	}
	$.post('/multiDbDemo/project/addMsg.do',{projectId:projectId,name:name,note:note},function(data){
		if('success'==data){
			jump2Page('home', projectId);
		}else if('isUsed'==data){
			alert('栏目名称已经存在');
		}else{
			alert('系统异常');
		}
	});
}

jQuery v1.11.1自己去下吧

jsp

addMsg.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/project.js"></script>
<title>Insert title here</title>
<% 
String projectId = request.getParameter("projectId");
System.out.println(projectId);
%>
</head>
<body>
	新增栏目<br /><br />
	<div id="id_addMsg">
		项目名称:<input type="text" id="id_addMsg_projectId" value="<%=projectId %>" readonly="readonly"><br />
		栏目名称:<input type="text" id="id_addMsg_name" ><br />
		栏目内容:<input type="text" id="id_addMsg_note"  /><br />
		
		<input type="button"  value="submit" οnclick="addMsg()"/>
	
	</div>
	
	<br />
	<br />
	
</body>
</html>

addProject.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/project.js"></script>
<title>Insert title here</title>
</head>
<body>
	新增项目<br /><br />
	<div id="id_form_addProject">
		项目代码:<input type="text" id="id_addProject_projectId" ><br />
		项目名称:<input type="text" id="id_addProject_projectName"  /><br />
		登录用户:<input type="text" id="id_addProject_userId"  /><br />
		密  码:<input type="text" id="id_addProject_pwd"  /><br />
		<input type="button"  value="submit" οnclick="addProject()"/>
	
	</div>
	
	<br />
	<br />
	
</body>
</html>

adminIndex.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/project.js"></script>
<title>Insert title here</title>
</head>
<body>
	项目管理<br /><br />
	<a href="#" οnclick="jump2Page('addProject')">新增</a>|<a href="#" οnclick="jump2Page('login')">退出</a><br />
	<table id="id_adminIndex_projectList"></table>
	<br />
	----------------------------------------------------

	
	<br />
	<script type="text/javascript">
	
	initProjectList();
	
	</script>
</body>
</html>

home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/project.js"></script>
<title>Insert title here</title>
<%
String projectId = request.getParameter("projectId");

System.out.println(projectId);
%>
</head>
<body>
	hello<br />
	<div>
	项目:<a id="id_home_projectId"><%=projectId %></a>
	登录用户:<a id="id_home_userId"></a>

	</div>
	
	<br />
	----------------------------------------------------
	<br />
	<br />
		<a href="#" οnclick="jump2Page('addMsg','<%=projectId %>')">新增栏目</a>|<a href="#" οnclick="jump2Page('login')">退回登录页</a><br />
	<table id="id_home_msgList"></table>
	<br />
	<script type="text/javascript">
	
	initMsg('<%=projectId %>');
	</script>
</body>
</html>

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	系统登录<br />
	<form action="/multiDbDemo/systemLogin.do" method="post">
		管理员:<input type="text" name="userId" value="admin"/><br />
		密 码:<input type="text" name="pwd"  value="admin"/>
		<input type="submit"  value="submit"/>
	
	</form>
	
	<br />
	----------------------------------------------------
	<br />
	项目登录<br />
	<form action="/multiDbDemo/projectLogin.do" method="post">
		登录用户:<input type="text" name="userId"/><br />
		密  码:<input type="text" name="pwd"/>
		<input type="submit"  value="submit"/>
	
	</form>
	
	<br />
</body>
</html>

projectIndex.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/project.js"></script>
<title>Insert title here</title>
<%
String userId = request.getParameter("userId");
String pwd = request.getParameter("pwd");
System.out.println(userId);
System.out.println(pwd);
%>
</head>
<body>
	welcome<br />
	<div>
	登录用户:<a id="id_projectIndex_userId"><%=userId %></a>
	密码:<a id="id_projectIndex_pwd"><%=pwd %></a>
	</div>
	
	<br />
	----------------------------------------------------
	<br />
	该登录用户的项目列表<br />
	<table id="id_projectIndex_projectList"></table>
	<br />
	<script type="text/javascript">
	
	initProjectListByUserIdAndPwd('<%=userId %>','<%=pwd %>');
	
	</script>
</body>
</html>

累死了,希望能帮助未来的自己^_^


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值