昨日は1日で1つのホイール、もう1つのOR mappingを繰り返し作りました.


もう一つannotationを使ったormの実現は、とてもつまらないものです.
しかし、実現の過程で、考えてみると、selectから出発するormは非常に使いにくいと感じます.どんなに簡単なシステムでも、select文には複雑な内外接続、パケットなどのクエリーロジックが表示されます.
しかし、データ記憶部、すなわちupate、insert、delete部では、論理が非常に簡単であり、ormを使用すると良い効果が得られることが多い.
そして、DAOモードについて考えてみると、通常理解されているDAOモードでは、データの読み取りと書き込みは同じDAOクラスに置かれており、実際の開発ではselect関連のfindXXXメソッドが良いgetXXXXメソッドが非常に多いのですが、update、insert、add、saveなどのメソッドの個数が少なく、個人的にはDAOやデータアクセス層プログラムを開発する場合、DAOは書き込みDAOと読み取りDAOに分けられると同時に、ここで読み書き分離を実現し、1つのライブラリに書き込み、複数のライブラリを読み取り、バッファプールを読み取り、書き込み直接書き込みを行い、データベースメカニズムテーブルの同期を利用して、システムの伸縮性を高めることを考慮することができる.
また@1兄の答えによると、書き込み操作自体は非常に遅い動作であり、書き込み時に反射を加え、象の体のダニのように、ディスクに比べて反射の消費は無視できるはずだ.
そして、ついでにNutzDAOに対して小さな批判を行い、DAOミドルウェアとして、いくつかのことをしすぎて、かえってあまりよくありません.例えば、いわゆるwhereClauseの条件検索を導入して、実際の業務の中のselectのSQLは非常に複雑で、簡単な条件でパッケージ化して、実際の開発の需要を満たすのは難しいです.
hibernateも最初は使いやすいことを知っておく必要がありますが、直面している需要が多く、境界がはっきりしていないと、コードが冗長になって、だんだん使えなくなります.
次のキーコードを貼ります.
Insert関連クラス:
 
//////////////////////
/*
 * 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はその1つにすぎません.
/*
 * 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兄さんに感謝