1. 程式人生 > >常用的工具類DBUtil/ServiceFactory/TransactionInvocationHandler/UUIDUtil等等

常用的工具類DBUtil/ServiceFactory/TransactionInvocationHandler/UUIDUtil等等

常用的工具類DBUtil/ServiceFactory/TransactionInvocationHandler/UUIDUtil

package com.yy.crud.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

public class DBUtil {

private DBUtil() {
}

private static Properties prop = new Properties();
// dds物件就是我們的資料庫連線池物件(資料來源物件)
private static DruidDataSource dds = null;

static {

	try {
		// db_server.properties
		prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db_server.properties"));
		dds = (DruidDataSource) DruidDataSourceFactory.createDataSource(prop);
	} catch (Exception e) {
		e.printStackTrace();
	}

}

private static ThreadLocal<Connection> t = new ThreadLocal<Connection>();

/*
 * 以下的getConn方法,有可能是建立一根連線返回,也有可能是直接返回已經有的連線
 * 
 * 在service層做呼叫的時候,是建立一根連線返回 在dao層做呼叫的時候,是直接返回已經有的連線
 * 
 */
public static Connection getConn() throws SQLException {

	Connection conn = t.get();

	if (conn == null) {
		
		//conn = DriverManager.getConnection(url, user, password);
		
		conn = dds.getConnection();
		
		t.set(conn);

	}

	return conn;

}

// 關閉相關資源
public static void myClose(Connection conn, PreparedStatement ps, ResultSet rs) throws SQLException {

	// 關閉資源的順序為 按照建立的順序 逆序關閉
	if (rs != null) {
		rs.close();
	}

	if (ps != null) {
		ps.close();
	}

	if (conn != null) {
		//將連接回收到連線池中
		conn.close();
		// 很容易忘
		t.remove();
	}

}

}


package com.wkcto.crud.util;

public class ServiceFactory {

public static Object getService(Object service){
	
	return new TransactionInvocationHandler(service).getProxy();
	
}

}


package com.wkcto.crud.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

public class TransactionInvocationHandler implements InvocationHandler{

//zs
private Object target;

public TransactionInvocationHandler(Object target){
	this.target = target;
}


/*
 * 以下的invoke方法,就是ls的送花方法
 * 
 * 既然是ls的送花方法(代理類的業務方法),由兩部分程式碼所組成
 * 
 * 一部分為使用成員變數(zs)來實現業務邏輯
 * 一部分為對於業務邏輯的增強(事務)
 * 
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	
	Connection conn = null;
	
	Object obj = null;
	
	try{
		conn = DBUtil.getConn();
		conn.setAutoCommit(false);
		
		
		//業務邏輯 使用zs來呼叫方法來實現真正的業務邏輯
		/*
		 * zs
		 * method
		 * 
		 * zs也有了,zs的方法也有了,現在我們要使用zs去呼叫方法就可以了
		 *呼叫方法的時候,args就是引數
		 * 
		 */
		obj = method.invoke(target,args);
		
		
		
		conn.commit();
	}catch(Exception e){
		conn.rollback();
		e.printStackTrace();
	}finally{
		DBUtil.myClose(conn,null,null);
	}
	
	
	return obj;
}


//取得代理類的物件 (取ls物件)
public Object getProxy(){
	
	return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
	
}

}


package com.uu.crud.util;

import java.util.UUID;

public class UUIDUtil {

public static String getUUID(){
	
	return UUID.randomUUID().toString().replaceAll("-","");
	
}

}


1.代理模式有什麼作用?*

理解

2.靜態代理一般很少使用,多數使用動態代理,你能獨立的寫出動態代理的程式碼嗎?*

3.能夠用動態代理實現事務的控制嗎?*

4.阿里巴巴的druid連線池會配置並且使用嗎?*

5.連線池的實現原理是什麼?有什麼好處?*

理解

6.是否能夠理解分頁查詢嗎?*

7.能夠使用模板方法設計模式實現核心控制器StudentController嗎?*

/*BeanFactory工具類/
package com.wkcto.crm.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

/**

  • Bean工廠
  • @author Administrator

*/
public class BeanFactory {

/**
 * 將request中的資料取出賦值給javabean物件的相關屬性,使用該<br>
 * 工具的時候要注意form表單提交的引數name必須和javabean的屬性名一致。
 * @param request
 * @param clazz
 * @return
 */
public static Object getBean(HttpServletRequest request , Class clazz){
	// 建立javabean物件
	Object obj = null;
	try {
		// ...save.do?username=zhangsan&birth=2010-10-10&sex=1....
		// 獲取所有的引數name
		Enumeration<String> names = request.getParameterNames();
		obj = clazz.newInstance();
		while(names.hasMoreElements()){
			try {
				// 獲取了引數name
				String name = names.nextElement(); // customerName
				// 獲取引數value
				String value = request.getParameter(name); // 2010-10-10
				// 給obj物件的相關屬性賦值
				String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
				Method setMethod = clazz.getDeclaredMethod(methodName, String.class);
				setMethod.invoke(obj, value);
			} catch (NoSuchMethodException e) {
				// 異常可以讓程式更加健壯,出問題之後不影響程式的繼續執行。
				// 出現異常之後,提示異常資訊,但不要耽誤“生產”。
			}
		}
	} catch (InstantiationException e) {
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (SecurityException e) {
		e.printStackTrace();
	} catch (IllegalArgumentException e) {
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		e.printStackTrace();
	}
	return obj;
}

}

/常量類***/
package com.wkcto.crm.utils;

/**

  • 常量類。系統常量,所有專案中的常量都放到這個類當中。
  • @author Administrator

*/
public class Const {

/**
 * 登入成功之後,將使用者物件繫結到session域時使用的name。
 */
public static final String SESSION_USER = "user";

}

/*日期工具類/

package com.wkcto.crm.utils;

import java.text.SimpleDateFormat;
import java.util.Date;

/**

  • 日期工具類
  • @author Administrator

*/
public class DateUtil {

private DateUtil() {

}

/**
 * 獲取當前系統時間
 * @return 日期格式: yyyy-MM-dd HH:mm:ss
 */
public static String getSysTime() {
	return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}

}
/讀取excel檔案*/

package com.wkcto.crm.utils;

import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelReader {

/**
 * 讀取excel檔案,獲取List集合
 * @param excelPath
 * @param clazz
 * @return
 */
public List<T> read(String excelPath, Class clazz) {
	List<T> dataList = new ArrayList<>();
	try {
		Workbook workbook = null;
		if (excelPath.indexOf(".xlsx") > -1) {
			workbook = new XSSFWorkbook(new FileInputStream(excelPath));
		} else {
			workbook = new HSSFWorkbook(new FileInputStream(excelPath));
		}
		Sheet sheet = workbook.getSheetAt(0);
		Row row0 = sheet.getRow(0);
		int totalColumns = row0.getLastCellNum();
		String[] propertyNames = new String[totalColumns];
		for (int i = 0; i < totalColumns; i++) {
			Cell cell = row0.getCell(i);
			String cellValue = getCellValue(cell);
			propertyNames[i] = cellValue;
		}
		int totalRows = sheet.getPhysicalNumberOfRows();
		for (int i = 1; i < totalRows; i++) {
			Row row = sheet.getRow(i);
			if (row != null) {
				T obj = (T)clazz.newInstance();
				for (int j = 0; j < totalColumns; j++) {
					Cell cell = row.getCell(j);
					String cellValue = getCellValue(cell);
					String propertyName = propertyNames[j];
					String methodName = "set" + propertyName.substring(0, 1).toUpperCase()
							+ propertyName.substring(1);
					Method setMethod = clazz.getDeclaredMethod(methodName, String.class);
					setMethod.invoke(obj, cellValue);
				}
				dataList.add(obj);
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	return dataList;
}

/**
 * 根據單元格獲取單元格當中的文字
 * @param cell
 * @return
 */
private static String getCellValue(Cell cell) {
	DecimalFormat df = new DecimalFormat("#");
	if (cell == null)
		return "";
	switch (cell.getCellType()) {
	case Cell.CELL_TYPE_NUMERIC:
		if (DateUtil.isCellDateFormatted(cell)) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			return sdf.format(cell.getDateCellValue()).toString();
			// return
			// sdf.format(DateUtil.getJavaDate(cell.getNumericCellValue())).toString();
		}
		return df.format(cell.getNumericCellValue());
	case Cell.CELL_TYPE_STRING:
		// System.out.println(cell.getStringCellValue());
		return cell.getStringCellValue();
	case Cell.CELL_TYPE_FORMULA:
		return cell.getCellFormula();
	case Cell.CELL_TYPE_BLANK:
		return "";
	case Cell.CELL_TYPE_BOOLEAN:
		return cell.getBooleanCellValue() + "";
	case Cell.CELL_TYPE_ERROR:
		return cell.getErrorCellValue() + "";
	}
	return "";
}

}
/*寫入excel檔案/
package com.wkcto.crm.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelWriter {

/**
 * 根據資料返回workbook
 * @param dataList 資料
 * @param sheetName 表格名稱
 * @param clazz 型別
 * @return 工作簿
 */
public XSSFWorkbook getWorkbook(List<T> dataList , String sheetName , Class clazz) {
	XSSFWorkbook workbook = new XSSFWorkbook();
	XSSFSheet sheet = workbook.createSheet(sheetName);
	XSSFRow row0 = sheet.createRow(0);
	Field[] fields = clazz.getDeclaredFields(); 
	for (int i = 0; i < fields.length; i++) {
		Field field = fields[i];
		String fieldName = field.getName();
		XSSFCell cell = row0.createCell(i);
		cell.setCellValue(fieldName);
	}
	try {
		for (int i = 0; i < dataList.size(); i++) {
			T obj = dataList.get(i);
			XSSFRow row = sheet.createRow(i + 1);
			for (int j = 0; j < fields.length; j++) {
				String propertyName = fields[j].getName();
				String getMethodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
				Method getMethod = clazz.getDeclaredMethod(getMethodName);
				Object value = getMethod.invoke(obj);
				XSSFCell cell = row.createCell(j);
				cell.setCellValue(value == null ? "" : value.toString());
			}
		}
	} catch (NoSuchMethodException e) {
		e.printStackTrace();
	} catch (SecurityException e) {
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		e.printStackTrace();
	} catch (IllegalArgumentException e) {
		e.printStackTrace();
	} catch (InvocationTargetException e) {
		e.printStackTrace();
	}
	return workbook;
}

}
/**Md5加密/
package com.wkcto.crm.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {

/**
 * 生成32位md5碼
 * @param password
 * @return
 */
public static String get(String password) {

	try {
		// 得到一個資訊摘要器
		MessageDigest digest = MessageDigest.getInstance("md5");
		byte[] result = digest.digest(password.getBytes());
		StringBuffer buffer = new StringBuffer();
		// 把每一個byte 做一個與運算 0xff;
		for (byte b : result) {
			// 與運算
			int number = b & 0xff;// 加鹽
			String str = Integer.toHexString(number);
			if (str.length() == 1) {
				buffer.append("0");
			}
			buffer.append(str);
		}

		// 標準的md5加密後的結果
		return buffer.toString();
	} catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
		return "";
	}

}

}

/**響應json工具類/

package com.wkcto.crm.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**

  • 響應json工具類
  • @author Administrator

*/
public class OutJson {

private OutJson(){
	
}

/**
 * 響應json,輸出結果為:{"success" : true}或者{"success" : false}
 * @param response
 * @param success
 */
public static void print(HttpServletResponse response , boolean success){
	try {
		Map<String, Boolean> jsonMap = new HashMap<>();
		jsonMap.put("success", success);
		ObjectMapper om = new ObjectMapper();
		String json = om.writeValueAsString(jsonMap);
		response.setContentType("text/json;charset=UTF-8");
		response.getWriter().print(json);
	} catch (JsonGenerationException e) {
		e.printStackTrace();
	} catch (JsonMappingException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

/**
 * 響應json
 * @param response
 * @param jsonMap
 */
public static void print(HttpServletResponse response , Object jsonMap){
	try {
		ObjectMapper om = new ObjectMapper();
		String json = om.writeValueAsString(jsonMap);
		response.setContentType("text/json;charset=UTF-8");
		response.getWriter().print(json);
	} catch (JsonGenerationException e) {
		e.printStackTrace();
	} catch (JsonMappingException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

}

/*mybatis工具類/
package com.wkcto.crm.utils;

import java.io.IOException;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**

  • MyBatis的工具類。
  • @author Administrator

*/
public class SqlSessionUtil {

private static SqlSessionFactory factory;
private static ThreadLocal<SqlSession> local = new ThreadLocal<>();

/**
 * 類載入的時候,載入mybatis的核心配置檔案,初始化SqlSessionFactory物件。
 * 該物件只被建立一次,不能銷燬,不能重建。所以將程式碼放到靜態程式碼塊當中。
 */
static {
	try {
		factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
	} catch (IOException e) {
		e.printStackTrace();
	}
}

/**
 * 獲取當前執行緒中的SqlSession物件
 * 
 * @return
 */
public static SqlSession getCurrentSqlSession() {
	SqlSession sqlSession = local.get();
	if (sqlSession == null) {
		sqlSession = factory.openSession();
		local.set(sqlSession);
	}
	return sqlSession;
}

/**
 * 關閉資源
 * 
 * @param sqlSession
 */
public static void close(SqlSession sqlSession) {
	if (sqlSession != null) {
		sqlSession.close();
		local.remove(); // 解除當前執行緒和SqlSession物件的繫結關係。原因是:執行緒在Tomcat伺服器中可以被重複使用。(Tomcat有一個執行緒池)
	}
}

/**
 * 回滾事務
 * 
 * @param sqlSession
 */
public static void rollback(SqlSession sqlSession) {
	if (sqlSession != null) {
		sqlSession.rollback();
	}
}

}
/動態代理工具類/
package com.wkcto.crm.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.apache.ibatis.session.SqlSession;

public class TransactionHandler implements InvocationHandler {

private Object target;

public TransactionHandler(Object target) {
	this.target = target;
}

// 為什麼是成員方法
public Object getProxy() {
	return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	SqlSession sqlSession = null;
	Object retValue = null;
	try {
		sqlSession = SqlSessionUtil.getCurrentSqlSession();
		// 執行真正service方法。
		retValue = method.invoke(target, args); 
		sqlSession.commit();
	} catch (Exception e) {
		SqlSessionUtil.rollback(sqlSession);
		e.printStackTrace();
		// 繼續將異常上拋給controller
		throw e.getCause(); // 注意:一定要將原始的LoginException丟擲。(e.getCause()得根異常。)
	} finally {
		SqlSessionUtil.close(sqlSession);
	}
	return retValue;
}

}
/UUID生成器/

package com.wkcto.crm.utils;

import java.util.UUID;

/**

  • UUID生成器
  • @author Administrator

*/
public class UUIDGenerator { // 生成器Generator,比較器Comparator

private UUIDGenerator(){
	
}

/**
 * 生成uuid
 * @return
 */
public static String generate(){ // 方法名是動詞(generate)
	return UUID.randomUUID().toString().replaceAll("-", "");
}

}