昨天用一天的時間重複製造了一個輪子,又一個OR mapping。

又一個使用annotation的orm的實現,很是無聊的東西。java

不過實現過程當中,思考了一下,感受從select出發的orm每每是很是難用的。再簡單的系統,其select語句也會出現複雜的內外鏈接,分組等查詢邏輯。sql

可是在數據存儲部分,也就是upate ,insert,delete部分,邏輯每每是很是簡單的,使用orm會獲得比較好的效果。數據庫

而後,要反思一下DAO模式,在一般理解的DAO模式中,數據的讀取和寫入是放在同一個DAO類當中的,在實際開發中,select相關的findXXX方法好getXXXX方法很是多,可是update,insert,add,save等方法個數都比較少,我的認爲開發DAO或者說數據訪問層程序的時候,應該講DAO分爲寫入DAO和讀取DAO,同時能夠考慮在此實現讀寫分離,寫入一個庫,讀取多個庫,讀加緩衝池,寫直接寫入,利用數據庫機制表同步,以提升系統的伸縮性。app

並且根據@1哥的答案,寫入操做自己就是一個很是慢的動做,在寫入時加入反射,猶如大象身上的蝨子,相對磁盤來講,反射的消耗應該能夠忽略。dom

 而後,順便對於NutzDAO進行一下小小的批評,做爲DAO中間件,有些事情作了太多,反而不太好,好比引入所謂的whereClause的條件查詢,真實業務中的select的SQL很是複雜,用簡單的條件封裝,很難知足真實開發須要的。工具

要知道hibernate一開始也很好用,可是面臨的需求多了,邊界劃分不清,代碼就冗腫了,慢慢就無法用了。ui

下面貼一點關鍵代碼:this

insert相關類:hibernate

 

//////////////////////code

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db.generic;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
/**
 *
 * @author THiNk
 * @param <T>
 */
public class GenericInsert<T> {
    protected T t;
    protected ArrayList<GenericColumn> columns;
    protected HashMap<String, Object> data;
    protected ArrayList<Field> fields;
    protected String tableName;
    public GenericInsert(T t) {
        this.t = t;
        tableName = t.getClass().getAnnotation(TableName.class).value();
        Field[] fs = t.getClass().getDeclaredFields();
        columns = new ArrayList<>();
        for (Field field : fs) {
            FieldName fieldName = field.getAnnotation(FieldName.class);
            if (fieldName != null) {
                String fname;
                if ("".equals(fieldName.value())) {
                    fname = field.getName();
                } else {
                    fname = fieldName.value();
                }
                GenericColumn col = new GenericColumn();
                col.setName(fname);
                col.setField(field);
                if (field.getType() == int.class) {
                    col.setType(GenericType.Int);
                    col.setIntValue(GenericReflect.getInt(field, t));
                    columns.add(col);
                } else if (field.getType() == int.class) {
                    col.setType(GenericType.Double);
                    col.setDoubleValue(GenericReflect.getDouble(field, t));
                    columns.add(col);
                } else if (field.getType() == String.class) {
                    col.setType(GenericType.String);
                    col.setStrValue(GenericReflect.getString(field, t));
                    columns.add(col);
                } else if (field.getType() == long.class) {
                    col.setType(GenericType.Long);
                    col.setLongValue(GenericReflect.getLong(field, t));
                    columns.add(col);
                } else if (field.getType() == Date.class) {
                    col.setType(GenericType.Timestamp);
                    col.setTimestampValue(new Timestamp(GenericReflect.getDate(field, t).getTime()));
                    columns.add(col);
                } else if (field.getType() == boolean.class) {
                    col.setType(GenericType.Boolean);
                    col.setBooleanValue(GenericReflect.getBoolean(field, t));
                    columns.add(col);
                }
            }
        }
    }
    public String sql() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("insert into ");
        buffer.append(tableName);
        buffer.append("(  ");
        StringBuffer values = new StringBuffer();
        for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            buffer.append(column.getName());
            values.append("?");
            if (it.hasNext()) {
                buffer.append(",");
                values.append(",");
            }
        }
        buffer.append(")");
        buffer.append(" values(");
        buffer.append(values);
        buffer.append(") ");
        return buffer.toString();
    }
    public int bind(PreparedStatement ps) throws SQLException {
        if (ps == null) {
            return 0;
        }
        int i = 1;
        for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            switch (column.getType()) {
                case Int:
                    ps.setInt(i, column.getIntValue());
                    break;
                case Long:
                    ps.setLong(i, column.getLongValue());
                    break;
                case Double:
                    ps.setDouble(i, column.getDoubleValue());
                    break;
                case Boolean:
                    ps.setBoolean(i, column.getBooleanValue());
                    break;
                case Timestamp:
                    ps.setTimestamp(i, column.getTimestampValue());
                    break;
                case String:
                    ps.setString(i, column.getStrValue());
                    break;
            }
            i++;
        }
        return i;
    }
}

反射工具類:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db.generic;
import java.lang.reflect.Field;
import java.util.Date;
/**
 *
 * @author THiNk
 */
public class GenericReflect {
    public static Object get(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : field.get(obj);
        } catch (Exception e) {
            return null;
        }
    }
    public static String getString(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : (String) field.get(obj);
        } catch (Exception e) {
            return null;
        }
    }
    public static int getInt(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : (int) field.get(obj);
        } catch (Exception e) {
            return 0;
        }
    }
    public static double getDouble(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : (double) field.get(obj);
        } catch (Exception e) {
            return 0d;
        }
    }
    public static long getLong(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : (long) field.get(obj);
        } catch (Exception e) {
            return 0l;
        }
    }
    public static Date getDate(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : (Date) field.get(obj);
        } catch (Exception e) {
            return new Date(System.currentTimeMillis());
        }
    }
       public static boolean getBoolean(Field field, Object obj) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            return null == obj ? null : (boolean) field.get(obj);
        } catch (Exception e) {
            return false;
        }
    }
    public static void set(Object obj, Field field, String value) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(obj, value);
        } catch (Exception e) {
        }
    }
    public static void set(Object obj, Field field, int value) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(obj, value);
        } catch (Exception e) {
        }
    }
    public static void set(Object obj, Field field, boolean value) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(obj, value);
        } catch (Exception e) {
        }
    }
    public static void set(Object obj, Field field, Date value) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(obj, value);
        } catch (Exception e) {
        }
    }
    public static void set(Object obj, Field field, long value) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(obj, value);
        } catch (Exception e) {
        }
    }
    public static void set(Object obj, Field field, double value) {
        try {
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(obj, value);
        } catch (Exception e) {
        }
    }
}

表格的列處理的實體對象

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db.generic;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.Date;
/**
 *
 * @author THiNk
 */
public class GenericColumn {
    private String name;
    private GenericType type;
    private Field field;
    private Object value;
    private String strValue;
    private int intValue;
    private double doubleValue;
    private Timestamp timestampValue;
    private long longValue;
    private boolean booleanValue;
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the type
     */
    public GenericType getType() {
        return type;
    }
    /**
     * @param type the type to set
     */
    public void setType(GenericType type) {
        this.type = type;
    }
    /**
     * @return the field
     */
    public Field getField() {
        return field;
    }
    /**
     * @param field the field to set
     */
    public void setField(Field field) {
        this.field = field;
    }
    /**
     * @return the value
     */
    public Object getValue() {
        return value;
    }
    /**
     * @param value the value to set
     */
    public void setValue(Object value) {
        this.value = value;
    }
    /**
     * @return the strValue
     */
    public String getStrValue() {
        return strValue;
    }
    /**
     * @param strValue the strValue to set
     */
    public void setStrValue(String strValue) {
        this.strValue = strValue;
    }
    /**
     * @return the intValue
     */
    public int getIntValue() {
        return intValue;
    }
    /**
     * @param intValue the intValue to set
     */
    public void setIntValue(int intValue) {
        this.intValue = intValue;
    }
    /**
     * @return the doubleValue
     */
    public double getDoubleValue() {
        return doubleValue;
    }
    /**
     * @param doubleValue the doubleValue to set
     */
    public void setDoubleValue(double doubleValue) {
        this.doubleValue = doubleValue;
    }
    /**
     * @return the timestampValue
     */
    public Timestamp getTimestampValue() {
        return timestampValue;
    }
    /**
     * @param timestampValue the timestampValue to set
     */
    public void setTimestampValue(Timestamp timestampValue) {
        this.timestampValue = timestampValue;
    }
    /**
     * @return the longValue
     */
    public long getLongValue() {
        return longValue;
    }
    /**
     * @param longValue the longValue to set
     */
    public void setLongValue(long longValue) {
        this.longValue = longValue;
    }
    /**
     * @return the booleanValue
     */
    public boolean getBooleanValue() {
        return booleanValue;
    }
    /**
     * @param booleanValue the booleanValue to set
     */
    public void setBooleanValue(boolean booleanValue) {
        this.booleanValue = booleanValue;
    }
}

支持類型的枚舉

package com.kamike.db.generic;
/**
 *
 * @author THiNk
 */
public enum GenericType {
    String,
    Int,
    Long,
    Boolean,
    Double,
    Timestamp
}

下面是幾個annotation的定義

package com.kamike.db.generic;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 *
 * @author THiNk
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface Id {
 
    String value() default "id";
}
package com.kamike.db.generic;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 *
 * @author THiNk
 */
@Target(ElementType.FIELD)   
@Retention(RetentionPolicy.RUNTIME)   
public @interface FieldName {   
    String value() default ""; 
}package com.kamike.db.generic;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    String value() default "";
}

下面貼一下,修改和刪除的實現類:

 /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db.generic;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
/**
 *
 * @author THiNk
 * @param <T>
 */
public class GenericUpdate<T> {
    protected T t;
    protected ArrayList<GenericColumn> columns;
    protected ArrayList<GenericColumn> ids;
    protected String tableName;
    public GenericUpdate(T t) {
        this.t = t;
        tableName = t.getClass().getAnnotation(TableName.class).value();
        Field[] fs = t.getClass().getDeclaredFields();
        columns = new ArrayList<>();
        for (Field field : fs) {
            FieldName fieldName = field.getAnnotation(FieldName.class);
            if (fieldName != null) {
                String fname;
                if ("".equals(fieldName.value())) {
                    fname = field.getName();
                } else {
                    fname = fieldName.value();
                }
                GenericColumn col = new GenericColumn();
                col.setName(fname);
                col.setField(field);
                if (field.getType() == int.class) {
                    col.setType(GenericType.Int);
                    col.setIntValue(GenericReflect.getInt(field, t));
                    columns.add(col);
                    Id id = field.getAnnotation(Id.class);
                    if (id != null) {
                        ids.add(col);
                    }
                } else if (field.getType() == int.class) {
                    col.setType(GenericType.Double);
                    col.setDoubleValue(GenericReflect.getDouble(field, t));
                    columns.add(col);
                    Id id = field.getAnnotation(Id.class);
                    if (id != null) {
                        ids.add(col);
                    }
                } else if (field.getType() == String.class) {
                    col.setType(GenericType.String);
                    col.setStrValue(GenericReflect.getString(field, t));
                    columns.add(col);
                    Id id = field.getAnnotation(Id.class);
                    if (id != null) {
                        ids.add(col);
                    }
                } else if (field.getType() == long.class) {
                    col.setType(GenericType.Long);
                    col.setLongValue(GenericReflect.getLong(field, t));
                    columns.add(col);
                    Id id = field.getAnnotation(Id.class);
                    if (id != null) {
                        ids.add(col);
                    }
                } else if (field.getType() == Date.class) {
                    col.setType(GenericType.Timestamp);
                    col.setTimestampValue(new Timestamp(GenericReflect.getDate(field, t).getTime()));
                    columns.add(col);
                    Id id = field.getAnnotation(Id.class);
                    if (id != null) {
                        ids.add(col);
                    }
                } else if (field.getType() == boolean.class) {
                    col.setType(GenericType.Boolean);
                    col.setBooleanValue(GenericReflect.getBoolean(field, t));
                    columns.add(col);
                    Id id = field.getAnnotation(Id.class);
                    if (id != null) {
                        ids.add(col);
                    }
                }
            }
        }
    }
 
 
    public String sql() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("update  ");
        buffer.append(tableName);
        buffer.append(" set ");
        for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            buffer.append(column.getName());
            buffer.append("=?");
            if (it.hasNext()) {
                buffer.append(", ");
            }
        }
        buffer.append(" where ");
       for (Iterator<GenericColumn> it = ids.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            buffer.append(column.getName());
            buffer.append("=? ");
            if (it.hasNext()) {
                buffer.append(" and ");
            }
        }
        return buffer.toString();
    }
    public String rawSql() {
       StringBuffer buffer = new StringBuffer();
        buffer.append("update  ");
        buffer.append(tableName);
        buffer.append(" set ");
        for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            buffer.append(column.getName());
            buffer.append("=?");
            if (it.hasNext()) {
                buffer.append(", ");
            }
        }
        return buffer.toString();
    }
    public int bind(PreparedStatement ps) throws SQLException {
        if (ps == null) {
            return 0;
        }
        int i = 1;
        for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            switch (column.getType()) {
                case Int:
                    ps.setInt(i, column.getIntValue());
                    break;
                case Long:
                    ps.setLong(i, column.getLongValue());
                    break;
                case Double:
                    ps.setDouble(i, column.getDoubleValue());
                    break;
                case Boolean:
                    ps.setBoolean(i, column.getBooleanValue());
                    break;
                case Timestamp:
                    ps.setTimestamp(i, column.getTimestampValue());
                    break;
                case String:
                    ps.setString(i, column.getStrValue());
                    break;
            }
            i++;
        }
        
        for (Iterator<GenericColumn> it = ids.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            switch (column.getType()) {
                case Int:
                    ps.setInt(i, column.getIntValue());
                    break;
                case Long:
                    ps.setLong(i, column.getLongValue());
                    break;
                case Double:
                    ps.setDouble(i, column.getDoubleValue());
                    break;
                case Boolean:
                    ps.setBoolean(i, column.getBooleanValue());
                    break;
                case Timestamp:
                    ps.setTimestamp(i, column.getTimestampValue());
                    break;
                case String:
                    ps.setString(i, column.getStrValue());
                    break;
            }
            i++;
        }
        return i;
    }
    public int rawBind (PreparedStatement ps) throws SQLException {
       if (ps == null) {
            return 0;
        }
        int i = 1;
        for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            switch (column.getType()) {
                case Int:
                    ps.setInt(i, column.getIntValue());
                    break;
                case Long:
                    ps.setLong(i, column.getLongValue());
                    break;
                case Double:
                    ps.setDouble(i, column.getDoubleValue());
                    break;
                case Boolean:
                    ps.setBoolean(i, column.getBooleanValue());
                    break;
                case Timestamp:
                    ps.setTimestamp(i, column.getTimestampValue());
                    break;
                case String:
                    ps.setString(i, column.getStrValue());
                    break;
            }
            i++;
        }
        return i;
    }
     
   
    
}

刪除:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db.generic;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
/**
 *
 * @author THiNk
 * @param <T>
 */
public class GenericDelete<T> {
    protected T t;
    protected ArrayList<GenericColumn> ids;
    protected String tableName;
 
    public GenericDelete(T t) {
       this.t = t;
        tableName = t.getClass().getAnnotation(TableName.class).value();
        Field[] fs = t.getClass().getDeclaredFields();
        ids = new ArrayList<>();
        for (Field field : fs) {
            FieldName fieldName = field.getAnnotation(FieldName.class);
            if (fieldName != null) {
                String fname;
                if ("".equals(fieldName.value())) {
                    fname = field.getName();
                } else {
                    fname = fieldName.value();
                }
                GenericColumn col = new GenericColumn();
                col.setName(fname);
                col.setField(field);
                if (field.getType() == int.class) {
                    col.setType(GenericType.Int);
                    col.setIntValue(GenericReflect.getInt(field, t));
                    ids.add(col);
                } else if (field.getType() == int.class) {
                    col.setType(GenericType.Double);
                    col.setDoubleValue(GenericReflect.getDouble(field, t));
                    ids.add(col);
                } else if (field.getType() == String.class) {
                    col.setType(GenericType.String);
                    col.setStrValue(GenericReflect.getString(field, t));
                    ids.add(col);
                } else if (field.getType() == long.class) {
                    col.setType(GenericType.Long);
                    col.setLongValue(GenericReflect.getLong(field, t));
                    ids.add(col);
                } else if (field.getType() == Date.class) {
                    col.setType(GenericType.Timestamp);
                    col.setTimestampValue(new Timestamp(GenericReflect.getDate(field, t).getTime()));
                    ids.add(col);
                } else if (field.getType() == boolean.class) {
                    col.setType(GenericType.Boolean);
                    col.setBooleanValue(GenericReflect.getBoolean(field, t));
                    ids.add(col);
                }
            }
        }
    }
    public String sql() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("delete from ");
        buffer.append(tableName);
        buffer.append("  where ");
        for (Iterator<GenericColumn> it = ids.iterator(); it.hasNext();) {
            GenericColumn id = it.next();
            buffer.append(id.getName());
            buffer.append("=? ");
            if (it.hasNext()) {
                buffer.append(" and ");
            }
        }
        return buffer.toString();
    }
    public int bind(PreparedStatement ps) throws SQLException {
        if (ps == null) {
            return 0;
        }
        int i = 1;
        for (Iterator<GenericColumn> it = ids.iterator(); it.hasNext();) {
            GenericColumn column = it.next();
            switch (column.getType()) {
                case Int:
                    ps.setInt(i, column.getIntValue());
                    break;
                case Long:
                    ps.setLong(i, column.getLongValue());
                    break;
                case Double:
                    ps.setDouble(i, column.getDoubleValue());
                    break;
                case Boolean:
                    ps.setBoolean(i, column.getBooleanValue());
                    break;
                case Timestamp:
                    ps.setTimestamp(i, column.getTimestampValue());
                    break;
                case String:
                    ps.setString(i, column.getStrValue());
                    break;
            }
            i++;
        }
        return i;
    }
}

 最終的DAO實現:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db;
import com.kamike.db.generic.GenericDelete;
import com.kamike.db.generic.GenericInsert;
import com.kamike.db.generic.GenericUpdate;
import com.kamike.kami.MySQLBucketWriter;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public abstract class GenericWriter<T> {
    //Protected
    protected String tableName;
    protected Transaction ts;
    protected GenericWriter(Transaction ts, String tableName) {
        this.tableName = tableName;
        this.ts= ts;
    }
  
    public boolean add(T t) {
          if (ts == null) {
            return false;
        }
        // String uuid= UUID.randomUUID().toString();
        GenericInsert<T> insert = new GenericInsert<>(t);
        int success = 0;
        PreparedStatement ps = null;
        try {
            ps = ts.preparedStatement(insert.sql());
            insert.bind(ps);
            success = ps.executeUpdate();
        } catch (Exception e) {
            ts.rollback();
            System.out.println(this.getClass().getName() + e.toString());
            return false;
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                    ps = null;
                }
            } catch (SQLException ex) {
                Logger.getLogger(MySQLBucketWriter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return true;
    }
     
    public boolean delete(T t) {
          if (ts == null) {
            return false;
        }
        // String uuid= UUID.randomUUID().toString();
        GenericDelete<T> delete = new GenericDelete<>(t);
        int success = 0;
        PreparedStatement ps = null;
        try {
            ps = ts.preparedStatement(delete.sql());
            delete.bind(ps);
            success = ps.executeUpdate();
        } catch (Exception e) {
            ts.rollback();
            System.out.println(this.getClass().getName() + e.toString());
            return false;
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                    ps = null;
                }
            } catch (SQLException ex) {
                Logger.getLogger(MySQLBucketWriter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return true;
    }
 
    public boolean edit(T t) {
         
        if (ts == null) {
            return false;
        }
        // String uuid= UUID.randomUUID().toString();
        GenericUpdate<T> update = new GenericUpdate<>(t);
        int success = 0;
        PreparedStatement ps = null;
        try {
            ps = ts.preparedStatement(update.sql());
            update.bind(ps);
            success = ps.executeUpdate();
        } catch (Exception e) {
            ts.rollback();
            System.out.println(this.getClass().getName() + e.toString());
            return false;
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                    ps = null;
                }
            } catch (SQLException ex) {
                Logger.getLogger(MySQLBucketWriter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return true;
    }
 
}

最後補一下Transaction的實現,這裏實現方法有不少,這裏給出的Transaction只是其中一種:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kamike.db;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 *
 * @author THiNk
 */
public class Transaction {
    protected Connection con;
    protected String dbName;
    protected boolean rollback;
    protected int originalTransactionIsolationLevel;
    public Transaction(String dbName) {
        this.dbName = dbName;
      
    }
    protected void init() {
        this.rollback = false;
        try {
            con = MultiDbInst.getInstance().getDatabase(dbName).getSingleConnection();
            con.setAutoCommit(false);
        } catch (SQLException ex) {
            Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    protected void setTransactionIsolationLevel(int transactionIsolationLevel) {
        try {
            if (con != null) {
                DatabaseMetaData dbmt = con.getMetaData();
                if (dbmt.supportsTransactions()) {
                    if (dbmt.supportsTransactionIsolationLevel(transactionIsolationLevel)) {
                        originalTransactionIsolationLevel = con.getTransactionIsolation();
                        con.setTransactionIsolation(transactionIsolationLevel);
                    }
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    protected void resetTransactionIsolationLevel() {
        try {
            if (con != null) {
                DatabaseMetaData dbmt = con.getMetaData();
                if (dbmt.supportsTransactions()) {
                    if (dbmt.supportsTransactionIsolationLevel(originalTransactionIsolationLevel)) {
                        con.setTransactionIsolation(originalTransactionIsolationLevel);
                    }
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void save() {
        try {
            if (this.rollback) {
                con.rollback();
            } else {
                con.commit();
            }
        } catch (SQLException ex) {
            Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                if (con != null) {
                    con.setAutoCommit(true);
                    con.close();
                    con = null;
                }
            } catch (SQLException ex) {
                Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    /**
     * 若是忘記關閉鏈接池,那麼對象自動銷燬的時候,也須要歸還連接
     */
    public void finalize() {
        try {
            if (con != null) {
                con.close();
                con = null;
            }
        } catch (SQLException ex) {
            Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            super.finalize();
        } catch (Throwable ex) {
            Logger.getLogger(MySQLTransaction.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    /**
     * @return the ps
     */
    public PreparedStatement preparedStatement(String sql) throws SQLException {
        return con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    }
    /**
     * @param rollback the rollback to set
     */
    public void rollback() {
        this.rollback = true;
    }
}

 最後,再次感謝@1哥

相關文章
相關標籤/搜索