标题:千里冰封进 by 万里燎原
只看楼主
千里冰封
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:灌水之王
等 级:版主
威 望:155
帖 子:28477
专家分:59
注 册:2006-2-26
得分:0 
我一般都在线上,只是隐身而已,你随时可以呼我

可惜不是你,陪我到最后
2008-02-27 12:12
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
得分:0 
实在没办法,我就只好写了一个封装了数据库,并实现Map方法的类
累死我了...忙乎了一个上午..平时被Spring宠惯了,面对异常处理我还真不记得怎么办了。


程序代码:
import      java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**

 * DerByCollection类,用数据库存放高耗内存文件

 * 

 * @author vlinux

 * 

 * @param <E>

 *            只接受实现了  的类

 */
public class DerByMap<K, E extends  implements Map<K, E> {

    private String databaseName;// 数据库名
    private static long index = 0;// 编号,每创建一个DerByCollection类就自增一次,避免数据库名重复相互干扰
    private static Set<String> databaseNameSet = new HashSet<String>();// 创建过的数据库名称集合,避免数据库名重复相互干扰
    private Connection conn = null;
    private long unitSize;// blob字段的大小,单位byte

    /**
     * 创建DerByCollection集合类
     * 
     * @param databaseName
     *            集合类的数据库名
     */
    public DerByMap(String databaseName, long unitSize) {
        this.databaseName = databaseName;
        this.unitSize = unitSize;
        if (databaseNameSet.contains(databaseName)) {
            throw new RuntimeException("数据库名已存在");
        }// if检查databaseName是否已经存在

        try {
            init();
        } catch (SQLException sqle) {
            sqle.printStackTrace();
            // throw new RuntimeException("数据库初始化失败:" + sqle.getMessage());
        }// try init
    }

    /**
     * 创建DerByCollection集合类
     */
    public DerByMap(long unitSize) {
        this(("DerbyColl" + index++), unitSize);// 默认的数据库名DerbyColl加上index
    }

    /**
     * 初始化数据库
     */
    protected void init() throws SQLException {
        String databaseURL = "jdbc:derby:" + databaseName + ";create=true";// create=true表示当数据库不存在时就创建它
        try {
            conn = DriverManager.getConnection(databaseURL);
        } catch (SQLException sqle) {
            close();// 不管怎么样,一旦出现异常,首先关闭数据库再说
        }// try create conn

        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            try {
                stmt.execute("drop table t_data");// 先删除数据库表
            } catch (SQLSyntaxErrorException sqlsee) {
                // do nothing
            }// try能捕获到这个异常,说明数据库表尚未存在,故这个异常可以不理会
            stmt.execute("create table t_data (id varchar(20), data blob("
                    + unitSize + "))");// 创建表
        } finally {
            try {
                stmt.close();
            } catch (Exception e) {
                //
            }// try close stmt
        }// try stmt

    }

    /**
     * 关闭数据库
     */
    public void close() {
        try {
            conn.close();
        } catch (Exception e) {
            //
        }
    }

    public void clear() {
        Statement stmt = null;
        try {
            stmt.execute("delete from t_data");// 清空表中所有数据
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } finally {
            try {
                stmt.close();
            } catch (Exception e) {
                //
            }//try
        }//try
    }

    public boolean containsKey(Object key) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        boolean returnValue = false;
        try {
            pstmt = conn.prepareStatement("select * from t_data where id = ?");
            pstmt.setString(1, key.toString());
            rs = pstmt.executeQuery();
            returnValue = rs.next();
        } catch (SQLException sqle) {
            sqle.printStackTrace();
            returnValue = false;
        } finally {
            try {
                rs.close();
            } catch (Exception e) {
                //
            }// try close rs
            try {
                pstmt.close();
            } catch (Exception e) {
                //
            }// try close pstmt
        }
        return returnValue;
    }

    public boolean containsValue(Object value) {
        throw new RuntimeException("该方法还没被实现");
    }

    public Set<java.util.Map.Entry<K, E>> entrySet() {
        throw new RuntimeException("该方法还没被实现");
    }

    @SuppressWarnings("unchecked")
    public E get(Object key) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        ObjectInputStream ois = null;
        E returnValue = null;
        try {
            pstmt = conn.prepareStatement("select * from t_data where id = ?");
            pstmt.setString(1, key.toString());
            rs = pstmt.executeQuery();
            if( rs.next() ) {
                ois = new ObjectInputStream(rs.getBlob("data").getBinaryStream());
                returnValue = (E) ois.readObject();
            }//if
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        } finally {
            try {
                ois.close();
            } catch (Exception e) {
                //
            }// try close rs
            try {
                rs.close();
            } catch (Exception e) {
                //
            }// try close rs
            try {
                pstmt.close();
            } catch (Exception e) {
                //
            }// try close pstmt
        }
        return returnValue;
    }

    public boolean isEmpty() {
        return this.size()==0?true:false;
    }

    public Set<K> keySet() {
        throw new RuntimeException("该方法还没被实现");
    }

    public E put(K key, E value) {
        PreparedStatement pstmt = null;
        ObjectInputStream ois = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        E returnValue = null;
        try {
            pstmt = conn.prepareStatement("insert into t_data (id, data) values(?,?)");
            pstmt.setString(1, key.toString());

            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(value);
            bis = new ByteArrayInputStream(bos.toByteArray());
            
            pstmt.setBinaryStream(2, bis);
            pstmt.execute();
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            try {
                ois.close();
            } catch (Exception e) {
                //
            }// try close ois
            try {
                bos.close();
            } catch (Exception e) {
                //
            }// try close bos
            try {
                oos.close();
            } catch (Exception e) {
                //
            }// try close oos
            try {
                bis.close();
            } catch (Exception e) {
                //
            }// try close bis
            try {
                pstmt.close();
            } catch (Exception e) {
                //
            }// try close pstmt
        }
        return returnValue;
    }

    public void putAll(Map<? extends K, ? extends E> m) {
        throw new RuntimeException("该方法还没被实现");
    }

    public E remove(Object key) {
        E returnValue = get(key);
        if( null == returnValue ) {
            return null;
        }//if首先获取该数据,然后再删除...该死的remove方法...
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement("delete from t_data where id = ?");
            pstmt.setString(1, key.toString());
            pstmt.execute();
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } finally {
            try {
                pstmt.close();
            } catch (Exception e) {
                //
            }//try
        }//try
        return null;
    }

    public int size() {
        Statement stmt = null;
        ResultSet rs = null;
        int size = 0;
        try {
            stmt = conn.createStatement();
            rs = stmt.executeQuery("select count(*) from t_data");
            rs.next();
            size = rs.getInt(1);
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } finally {
            try {
                rs.close();
            } catch (Exception e) {
                //
            }//try
            try {
                stmt.close();
            } catch (Exception e) {
                //
            }//try
        }//try
        return size;
    }

    public Collection<E> values() {
        throw new RuntimeException("该方法还没被实现");
    }

    @Override
    protected void finalize() {
        close();
    }

}


[[it] 本帖最后由 神vLinux飘飘 于 2008-2-27 12:18 编辑 [/it]]

淘宝杜琨
2008-02-27 12:14
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
得分:0 
稍微说明一下,这个类使用了JDK6自带的Derby数据库,如果想要调用,首先就得找到derby.jar这个包,这个包一般是在JDK6自带的Derby数据库里面,在我的机器上的路径就是

C:\Program Files\Sun\JavaDB\lib

妈妈的,这次都放到数据库中了,应该没问题了吧。

淘宝杜琨
2008-02-27 12:16
千里冰封
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:灌水之王
等 级:版主
威 望:155
帖 子:28477
专家分:59
注 册:2006-2-26
得分:0 
问题 是人家是jdk5.0,哪里自带了derby数据库?

可惜不是你,陪我到最后
2008-02-27 12:17
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
得分:0 
思想是一样的,你也可以用MySQL,再说了,Derby虽然说是6引入的,但是在6之前都可以单独作为一个包使用

淘宝杜琨
2008-02-27 12:19
千里冰封
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:灌水之王
等 级:版主
威 望:155
帖 子:28477
专家分:59
注 册:2006-2-26
得分:0 
不错,这种思路挺好的,如果能写得更通用一点就更好了,
你也可以用这种方式写一个永不溢出的List,自己重新实现List接口

可惜不是你,陪我到最后
2008-02-27 12:24
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
得分:0 
累...你自己实现吧...要让我实现,我可吃不消

淘宝杜琨
2008-02-27 12:26
千里冰封
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:灌水之王
等 级:版主
威 望:155
帖 子:28477
专家分:59
注 册:2006-2-26
得分:0 
我现在哪有空.有空再来实现吧.
呵呵,楼主自己也可以尝试实现一下啊

可惜不是你,陪我到最后
2008-02-27 12:27
万里燎原
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2008-2-26
得分:0 
多谢老大和神vLinux飘飘帮助,这个论坛比csdn好多了.
2008-02-27 14:32
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
得分:0 
能用再谢吧

淘宝杜琨
2008-02-27 15:21



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-200999-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.628374 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved