/**
* 通用的 DAO
* @author Admin
*
*/
public class BaseDao {
private Class<?> cls;
private Map<String,String> map = new HashMap<>();
public BaseDao() {
Type sType = getClass().getGenericSuperclass();
Type[] generics = ((ParameterizedType) sType).getActualTypeArguments();
cls = (Class<?>) (generics[0]);
getId();
}
/**
* 通用的更新的方法
* @param sql 要执行的SQL语句
* @param parameters 占位符的参数
* @return 受影响的行数
*/
public int update(String sql,Object...parameters) {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
int i = 0;
try {
con = JDBCUtils.getConnection();
st = con.prepareStatement(sql);
setParameters(st,parameters);
i = st.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs, st, con);
}
return i;
}
/**
* 获取单个对象
* @param sql 要执行的SQL语句
* @param parameters 占位符的参数
* @return 封装成的一个对象,如果没有记录返回null
*/
public E get(String sql,Object...parameters) {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
E obj = null;
try {
con = JDBCUtils.getConnection();
st = con.prepareStatement(sql);
setParameters(st,parameters);
rs = st.executeQuery();
while(rs.next()) {
obj = oneRowToObject(rs);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs, st, con);
}
return obj;
}/**
* 获取多个对象封装成一个集合(列名<->属性名)
* @param sql 查询SQL
* @param parameters 占位符的参数
* @return 封装成的一个对象集合,如果没有记录返回一个空集合
*/
public List<E> list(String sql,Object...parameters) {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
List<E> list = new ArrayList<E>();
try {
con = JDBCUtils.getConnection();
st = con.prepareStatement(sql);
setParameters(st,parameters);
rs = st.executeQuery();
while(rs.next()) {
E obj = oneRowToObject(rs);
list.add(obj);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs, st, con);
}
return list;
}
/**
* 查找一个实体类封装成一个对象
* @param id 查询的标号
* @return 返回一个对象
* @throws IdMistakeException
*/
public E get(Object id) throws IdMistakeException{
if(getId()==null) {
throw new IdMistakeException("没有Id设置,请设置Id");
}else {
String sql = "select * from "+getTableName()+" where "+getId()+"=?";
System.out.println(sql);
return get(sql,id);
}
}
public List<E> getPropertyName() {
List<E> list = new ArrayList();
//获取所有声明的属性
Field[] fields = cls.getDeclaredFields();
for(Field field : fields) {
list.add((E) field.getName());
}
return list;
}*/
@SuppressWarnings("null")
public boolean save(Object obj) throws Exception {
Connection con = JDBCUtils.getConnection();
PreparedStatement st = null;
ResultSet rs = null;
boolean flag = false;
//获取类中所有的属性
Field[] fi = cls.getDeclaredFields();
StringBuilder sb = new StringBuilder();
sb.append("insert into ");
sb.append(getTableName());
sb.append("(");
//主键为第一列,是自增的,有默认值,不需要添加
for(int i=1;i<fi.length;i++){
//获取列名
sb.append(fi[i].getName());
//最后一列不用加逗号
if(i!=fi.length-1)
sb.append(",");
}
sb.append(") values(");
for(int i=1;i<fi.length;i++){
sb.append("?");
//最后一列不用加逗号
if(i!=fi.length-1)
sb.append(",");
}
sb.append(")");
String sql=sb.toString();
System.out.println(sql);
try {
st=con.prepareStatement(sql);
for(int i=1;i<fi.length;i++)
{
//设置可以访问的私有属性
fi[i].setAccessible(true);
//第一列为主键 不用添加(对应数组下标是0)
st.setObject(i,fi[i].get(obj));
}
int row = st.executeUpdate();
if(row>0){
flag = true;
}
} catch (Exception e1) {
e1.printStackTrace();
}finally {
JDBCUtils.close(rs, st, con);
}
return flag;
}
/**
* 删除一个对象
* @param id
* @return
* @throws IdMistakeExceptions
*/
public int delect(Object id) throws IdMistakeException{
if(getId()==null) {
throw new IdMistakeException("没有Id设置,请设置Id");
}else {
String sql = "delete from "+getTableName()+" where "+getId()+"=?";
System.out.println(sql);
int i =update(sql,id);
return i;
}
}
/**
* 获取一个实体类对应的表格
* @return 返回一个表名
*/
public String getTableName() {
//先检查实体类上有没有@Table注解
Table table = cls.getAnnotation(Table.class);
String tableName = null;
if(table != null) {
tableName = table.value();
}else {
tableName = cls.getSimpleName();
}
return tableName;
}
/**
* 获取一个声明的属性
* @return
*/
public String getId() {
//获取所有声明的属性
Field[] fields = cls.getDeclaredFields();
for(Field field:fields) {
//检查这个属性上是否有@Id
Id id = field.getDeclaredAnnotation(Id.class);
if(id != null) {
String columnName = id.value();
if(columnName.trim().equals("")) {
columnName = field.getName();
}
map.put(columnName, field.getName());
return columnName;
}
}
return null;
}
private E oneRowToObject(ResultSet rs) throws InstantiationException, IllegalAccessException,
SQLException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
E obj;
obj = (E)cls.newInstance();
//获取结果集元数据(类型和属性)
ResultSetMetaData rd = rs.getMetaData();
//列的数量
for(int i=0;i<rd.getColumnCount();i++) {
//获取列名
String columnName = rd.getColumnLabel(i+1);
String propertyName = map.get(columnName);
String methodName = "";
//组合方法
if(propertyName != null) {
//以属性名组成方法名
methodName = "set"+propertyName.substring(0, 1).toUpperCase()+propertyName.substring(1);
}else {
//以列名组合方法名
methodName = "set"+columnName.substring(0, 1).toUpperCase()+columnName.substring(1);
}
//获取列类型
int columnType = rd.getColumnType(i+1);
Method method = null;
switch(columnType) {
case java.sql.Types.VARCHAR:
case java.sql.Types.CHAR:
method = cls.getMethod(methodName, String.class);
if(method != null) {
method.invoke(obj, rs.getString(columnName));
}
break;
case java.sql.Types.INTEGER:
case java.sql.Types.SMALLINT:
method = cls.getMethod(methodName, int.class);
if(method != null) {
method.invoke(obj, rs.getInt(columnName));
}
break;
case java.sql.Types.BIGINT:
method = cls.getMethod(methodName, long.class);
if(method != null) {
method.invoke(obj, rs.getLong(columnName));
}
break;
case java.sql.Types.DATE:
case java.sql.Types.TIMESTAMP:
method = cls.getMethod(methodName, Date.class);
if(method != null) {
method.invoke(obj, rs.getTimestamp(columnName));
}
break;
case java.sql.Types.DECIMAL:
method = cls.getMethod(methodName, BigDecimal.class);
if(method != null) {
method.invoke(obj, rs.getBigDecimal(columnName));
}
break;
case java.sql.Types.DOUBLE:
case java.sql.Types.NUMERIC:
method = cls.getMethod(methodName, double.class);
if(method != null) {
method.invoke(obj, rs.getDouble(columnName));
}
break;
case java.sql.Types.BIT:
method = cls.getMethod(methodName, boolean.class);
if(method != null) {
method.invoke(obj, rs.getBoolean(columnName));
}
break;
default:
break;
}
}
return obj;
}
private void setParameters(PreparedStatement st, Object...parameters) {
if(parameters != null && parameters.length>0) {
for(int i=0;i<parameters.length;i++) {
try {
st.setObject(i+1, parameters[i]);
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}