package com.dangdang.dao.impl;
import java.util.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.dangdang.tools.ObjectFactory;
public abstract class BaseDao {
private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
private final String DRIVER = ObjectFactory.pro.getProperty("DRIVER");
private final String URL = ObjectFactory.pro.getProperty("URL");
private final String DBNAME = ObjectFactory.pro.getProperty("DBNAME");
private final String DBPASS = ObjectFactory.pro.getProperty("DBPASS");
/**
* 连接数据库
* @return {@link Connection}
*/
private Connection getConn(){
Connection conn = null;
try {
Class.forName(this.DRIVER);
conn = DriverManager.getConnection(URL,DBNAME,DBPASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("找不到对应的数据库驱动");
}catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("连接数据库失败");
}
return conn;
}
private Connection getDataSourceConn(){
Connection conn = null;
Context ctx;
try {
ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/JDBC/liaoJieJie");
conn = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("连接数据库失败");
}
return conn;
}
/**
* 释放数据库资源
* @param conn
* @param pstmt
* @param rs
*/
private void closeAll(Connection conn,PreparedStatement pstmt,ResultSet rs){
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("关闭结果集对象失败");
}
try {
if(pstmt != null){
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("关闭预处理语句对象失败");
}
try {
if(conn != null&&!conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("关闭数据库连接对象失败");
}
}
/**
* 执行增删改
* @param sql
* @param param
* @return {@link Integer}
*/
public Integer executeUpdate(String sql,Object[] param){
Integer result = 0;
try {
conn = this.getConn();
pstmt = conn.prepareStatement(sql);
if(param != null){
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i+1, param[i]);
}
}
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("执行增删改语句失败"+sql);
}finally{
this.closeAll(conn, pstmt, null);
}
return result;
}
/**
* 执行查询
* @param sql
* @param param
* @return {@link List}
*/
public List<?> executeQuery(String sql,Object[] param){
List<Object> list = new ArrayList<Object>();
try {
conn = this.getConn();
pstmt = conn.prepareStatement(sql);
if(param != null){
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i+1, param[i]);
}
}
rs = pstmt.executeQuery();
Object oj = null;
while(rs.next()){
oj = this.fillDataToExecuteQuery(rs);
list.add(oj);
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("执行查询语句失败"+sql);
}finally{
this.closeAll(conn, pstmt, rs);
}
return list;
}
/**
* 将结果集中的数据封装成对象
* @param rs
* @return {@link Object}
*/
protected abstract Object fillDataToExecuteQuery(ResultSet rs) throws SQLException;
/**
* 执行查询
* @param sql
* @param param
* @return {@link List}
*/
public List<?> executeQuery(String sql,Object[] param,Class<?> beanClass){
List<Object> list = new ArrayList<Object>();
try {
conn = this.getDataSourceConn();
pstmt = conn.prepareStatement(sql);
if(param != null){
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i+1, param[i]);
}
}
rs = pstmt.executeQuery();
Object oj = null;
while(rs.next()){
oj = getJavaBean(rs,beanClass);
list.add(oj);
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("执行查询语句失败"+sql);
}finally{
this.closeAll(conn, pstmt, rs);
}
return list;
}
public static Object getJavaBean(ResultSet rs,Class<?> beanClass) {
try {
// 1、通过beanClass实例化JavaBean对象
Object obj = beanClass.newInstance();
// 2、获得所有属性,循环
Field[] fields = beanClass.getDeclaredFields();
for (Field f : fields) {
// 3、获得属性名
String fname = f.getName();
//获得属性类型名
String fTypeName = f.getType().getSimpleName();
if ("Integer".equals(fTypeName)) {
fTypeName = "Int";
}
// 4、通过属性名生成方法名
String setMethodName = "set"
+ fname.substring(0, 1).toUpperCase()
+ fname.substring(1);
f.getClass().getSimpleName();
String getMethodName = "get" + fTypeName;
// 5、通过方法名和方法参数(属性类型)获得方法对象
Method setm = beanClass.getMethod(setMethodName, f.getType());
Method getm = ResultSet.class.getMethod(getMethodName, String.class);
// 6、调用方法,将值通过setXXX方法设置到对应的属性中
setm.invoke(obj, getm.invoke(rs, f.getName()));
}
return obj;
} catch (InstantiationException e) {
e.printStackTrace();
throw new RuntimeException("无法实例化当前类的对象");
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new RuntimeException("无访问权限");
} catch (SecurityException e) {
e.printStackTrace();
throw new RuntimeException("无法通过安全认证");
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new RuntimeException("找不到方法");
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw new RuntimeException("错误的参数");
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
throw new RuntimeException("对象中没有对应方法");
}
}
}