昨天用一天的时间重复制造了一个轮子,又一个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哥的答案,写入操作本身就是一个非常慢的动作,在写入时加入反射,犹如大象身上的虱子,相对磁盘来说,反射的消耗应该可以忽略。

 然后,顺便对于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只是其中一种:

/*
 * 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哥

转载于:https://my.oschina.net/brinlike/blog/194985

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值