Java SQLite连接池

Java SQLite连接池,java,android,sqlite,Java,Android,Sqlite,我希望在android中有一个连接池,因为并行线程必须同时访问数据库 Android提供了用于javax.sql连接的PooledConnection接口。由于Android中没有正式支持jdbc for SQLite,我正在考虑另一种方法,实现SQLite数据库的连接池 您对这种方法有何看法。风险是什么?我忽略了什么吗 我的代码如下: 数据库的连接包装类: public class PoolConnection { protected SQLiteDatabase sqlDb;

我希望在android中有一个连接池,因为并行线程必须同时访问数据库

Android提供了用于javax.sql连接的
PooledConnection
接口。由于Android中没有正式支持jdbc for SQLite,我正在考虑另一种方法,实现SQLite数据库的连接池

您对这种方法有何看法。风险是什么?我忽略了什么吗

我的代码如下:

数据库的连接包装类:

public class PoolConnection {

    protected SQLiteDatabase sqlDb;
    protected long openedAt;

    private static final String DB_NAME = Environment
            .getExternalStorageDirectory()
            + "/data/DBNAME.sqlite";
    private static final int DB_VERSION = 1;

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            // nothing to do here
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // no upgrade planned yet
        }
    }

    public PoolConnection(Context context) throws Exception {
        sqlDb = new DatabaseHelper(context).getWritableDatabase();
        openedAt = System.currentTimeMillis();
    }

    public boolean isAvailable() {
        if (!sqlDb.isOpen() || sqlDb.inTransaction()
                || sqlDb.isDbLockedByOtherThreads()) {
            return false;
        } else {
            return true;
        }
    }

    public void close() throws SQLException {
        sqlDb.close();
    }

    public SQLiteDatabase getConnection() throws SQLException {
        return sqlDb;
    }

    public long getOpenedAt() {
        return openedAt;
    }

}
public class ConnectionPool {

    protected List<PoolConnection> connections;

    protected long maxIdleTime = 30 * 1000;

    public ConnectionPool() {
        connections = Collections
                .synchronizedList(new ArrayList<PoolConnection>());
        new PoolCleaner(maxIdleTime).start();
    }

    public PoolConnection getConnection(Context context) throws Exception {

        synchronized (connections) {

            PoolConnection poolCon = null;

            for (PoolConnection con : connections) {
                poolCon = con;
                if (poolCon.isAvailable()) {
                    return poolCon;
                }
            }

        }

        PoolConnection con = new PoolConnection(context);

        synchronized (connections) {
            connections.add(con);
        }

        return con;

    }

    public void removeExpired() {

        synchronized (connections) {
            for (int i = (connections.size() - 1); i >= 0; i--) {
                PoolConnection con = connections.get(i);
                if (con.isAvailable()
                        && maxIdleTime < (System.currentTimeMillis() - con
                                .getOpenedAt())) {
                    try {
                        con.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    connections.remove(i);
                }
            }
        }

    }

    class PoolCleaner extends Thread {

        protected long cleaningInterval;
        protected boolean mustStop;

        public PoolCleaner(long cleaningInterval) {
            if (cleaningInterval < 0) {
                throw new IllegalArgumentException(
                        "cleaningInterval must be >= 0");
            }
            this.mustStop = false;
            this.cleaningInterval = cleaningInterval;

            setDaemon(true);
        }

        public void run() {
            while (!mustStop) {
                try {
                    sleep(cleaningInterval);
                } catch (InterruptedException ignore) {
                }

                if (mustStop) {
                    break;
                }

                removeExpired();
            }
        }

        public void halt() {
            mustStop = true;
            synchronized (this) {
                this.interrupt();
            }
        }
    }

}
和连接池类:

public class PoolConnection {

    protected SQLiteDatabase sqlDb;
    protected long openedAt;

    private static final String DB_NAME = Environment
            .getExternalStorageDirectory()
            + "/data/DBNAME.sqlite";
    private static final int DB_VERSION = 1;

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            // nothing to do here
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // no upgrade planned yet
        }
    }

    public PoolConnection(Context context) throws Exception {
        sqlDb = new DatabaseHelper(context).getWritableDatabase();
        openedAt = System.currentTimeMillis();
    }

    public boolean isAvailable() {
        if (!sqlDb.isOpen() || sqlDb.inTransaction()
                || sqlDb.isDbLockedByOtherThreads()) {
            return false;
        } else {
            return true;
        }
    }

    public void close() throws SQLException {
        sqlDb.close();
    }

    public SQLiteDatabase getConnection() throws SQLException {
        return sqlDb;
    }

    public long getOpenedAt() {
        return openedAt;
    }

}
public class ConnectionPool {

    protected List<PoolConnection> connections;

    protected long maxIdleTime = 30 * 1000;

    public ConnectionPool() {
        connections = Collections
                .synchronizedList(new ArrayList<PoolConnection>());
        new PoolCleaner(maxIdleTime).start();
    }

    public PoolConnection getConnection(Context context) throws Exception {

        synchronized (connections) {

            PoolConnection poolCon = null;

            for (PoolConnection con : connections) {
                poolCon = con;
                if (poolCon.isAvailable()) {
                    return poolCon;
                }
            }

        }

        PoolConnection con = new PoolConnection(context);

        synchronized (connections) {
            connections.add(con);
        }

        return con;

    }

    public void removeExpired() {

        synchronized (connections) {
            for (int i = (connections.size() - 1); i >= 0; i--) {
                PoolConnection con = connections.get(i);
                if (con.isAvailable()
                        && maxIdleTime < (System.currentTimeMillis() - con
                                .getOpenedAt())) {
                    try {
                        con.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    connections.remove(i);
                }
            }
        }

    }

    class PoolCleaner extends Thread {

        protected long cleaningInterval;
        protected boolean mustStop;

        public PoolCleaner(long cleaningInterval) {
            if (cleaningInterval < 0) {
                throw new IllegalArgumentException(
                        "cleaningInterval must be >= 0");
            }
            this.mustStop = false;
            this.cleaningInterval = cleaningInterval;

            setDaemon(true);
        }

        public void run() {
            while (!mustStop) {
                try {
                    sleep(cleaningInterval);
                } catch (InterruptedException ignore) {
                }

                if (mustStop) {
                    break;
                }

                removeExpired();
            }
        }

        public void halt() {
            mustStop = true;
            synchronized (this) {
                this.interrupt();
            }
        }
    }

}
公共类连接池{
受保护的列表连接;
受保护的长最大空闲时间=30*1000;
公共连接池(){
连接=集合
.synchronizedList(新的ArrayList());
新的池清理器(maxIdleTime).start();
}
公共池连接getConnection(上下文上下文)引发异常{
已同步(连接){
PoolConnection-poolCon=null;
用于(池连接con:connections){
poolCon=con;
if(poolCon.isAvailable()){
返回poolCon;
}
}
}
PoolConnection con=新的PoolConnection(上下文);
已同步(连接){
连接。添加(con);
}
返回con;
}
public void removeExpired(){
已同步(连接){
对于(inti=(connections.size()-1);i>=0;i--){
PoolConnection con=connections.get(i);
如果(con.isAvailable()
&&maxIdleTime<(System.currentTimeMillis()-con
.getOpenedAt()){
试一试{
con.close();
}捕获(SQLE异常){
e、 printStackTrace();
}
连接。移除(i);
}
}
}
}
类PoolCleaner扩展线程{
受保护的长时间清洗间隔;
受保护的布尔值必须停止;
公共泳池清洁器(长时间清洁间隔){
如果(清洁间隔<0){
抛出新的IllegalArgumentException(
“cleaningInterval必须大于等于0”);
}
this.mustStop=false;
this.cleaningInterval=cleaningInterval;
setDaemon(true);
}
公开募捐{
而(!mustStop){
试一试{
睡眠(清洁间期);
}捕获(中断异常忽略){
}
如果(必须停止){
打破
}
removeExpired();
}
}
公众假期暂停{
mustStop=true;
已同步(此){
这个。中断();
}
}
}
}