package com;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.mvc.entity.Constant;
import org.apache.commons.mvc.entity.enums.Database;
import org.apache.commons.mvc.entity.enums.LineChar;
import org.apache.commons.mvc.entity.mapping.DatabaseSet;
import org.apache.commons.mvc.listener.ThreadListener;
import org.apache.commons.mvc.listener.impl.thread.SelectThread;
import org.apache.commons.mvc.thread.MoreThread;
import org.apache.commons.mvc.util.chars.DesUtil;
import org.apache.commons.mvc.util.lang.ArrayUtil;
import org.apache.commons.mvc.util.lang.EntityUtil;
import org.apache.commons.mvc.util.lang.ReflectUtil;
import org.apache.commons.mvc.util.lang.XmlUtil;
import org.apache.log4j.Logger;
import org.dom4j.Element;
import com.alibaba.druid.pool.DruidDataSource;
/**
* 工具类
*
* @version 1.0
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public final class Util {
private static final Logger log = Logger.getLogger(Util.class);
public static final String TABLE = "student";// 要操作的表
public static DatabaseSet dbset;// 数据库配置
public static DruidDataSource source;// 数据源
public static List<Element> resource;// 静态资源
static {
// 数据库连接最好写在配置文件里
String url = Database.mysql.url("localhost", "3306", "test"), user = "root", passwd = "123456";// 连接的url,用户名,密码
source = new DruidDataSource();
source.setDriverClassName(Database.mysql.driver());
source.setUrl(url);
source.setUsername(user);
source.setPassword(passwd);
source.setInitialSize(16);
source.setMinIdle(8);
source.setMaxActive(40);
source.setMaxWait(60000);
source.setValidationQuery("select now()");
dbset = new DatabaseSet(Database.mysql, url, user, DesUtil.encrypt(passwd, DesUtil.JS_KEY));// 初始化数据库配置
resource = XmlUtil.read(new File(ReflectUtil.classpath() + "/resource.xml"), LineChar.none);// 读取资源文件
}
/**
* 初始化十万数据
*/
public static void init() {
long time = System.currentTimeMillis(), total = Constant.MAX_EXPORT_NUM, batch = 10000, num = total / batch;// 当前时间,要初始化的数据总量,批处理数量,线程个数
List<ThreadListener> list = new ArrayList<ThreadListener>();// 用来收集线程
for (int i = 0; i < num; i++) {
list.add(new InsertThread(batch));// 把线程放入list
}
ExecutorService executor = Executors.newFixedThreadPool((int) num);// 准备线程池
log.info(EntityUtil.format(EntityUtil.toJson(MoreThread.run(list, executor))));// 执行完毕后打印每个线程的执行情况
// 多线程执行是无序的,但结果是有序的,按照先分再合的原理,多线程的执行时间以耗时最长的单线程为准
log.info(String.format("初始化%d万条数据耗时%d毫秒", total, System.currentTimeMillis() - time));// 打印主线程的耗时情况
}
/**
* 并行多条sql
*
* @throws Exception 捕获异常
*/
public static void select() throws Exception {
long time = System.currentTimeMillis();// 当前时间
List list = new ArrayList(), args0 = ArrayUtil.create(10);// 把查询数据的子线程放入list
list.add(new SelectThread(source.getConnection(), String.format("select * from %s limit ?", TABLE), args0));
list.add(new SelectThread(source.getConnection(), String.format("select age, count(*) as num from %s group by age", TABLE), null));
list.add(new SelectThread(source.getConnection(), String.format("select count(*) as num from %s", TABLE), null));
list.add(new SelectThread(source.getConnection(), String.format("select sum(age) as age from %s", TABLE), null));
log.info(EntityUtil.format(EntityUtil.toJson(MoreThread.run(list, null))));// 不传线程池按cpu核心数两倍计算
log.info(String.format("并行%d条SQL耗时%d毫秒", list.size(), System.currentTimeMillis() - time));// 打印主线程的耗时情况
}
}