【问题标题】:Single db connection that does not get initialised per task每个任务未初始化的单个数据库连接
【发布时间】:2014-01-29 18:56:35
【问题描述】:
public class Parser {

    ExecutorService pool = Executors.newFixedThreadPool(10);

    public void update() {

        Item item = new Item(subj.getName(), dateBuilder.toString(),
                cobBuilder.toString(), interest, count);

        pool.submit(new ItemDispatcher(item));
    }



} 



public class ItemDispatcher implements Runnable {

    private Item item;

    public ItemDispatcher(Item someItem) {

        this.item = someItem;

    }


    @Override
    public void run() {

        try {
            new Database(item).writeToDb();
        } catch (SQLException e) {
            e.printStackTrace(); 

        }

    }

}


public class Database {

    private String name;
    private String date;
    private String cob;
    private String interest;
    private String count;

    private String _url;
    private String _userId;
    private String _password;
    private String _dbLib;
    private String _dbFile;
    private Connection _conn;
    private PreparedStatement _statement;

    public Database(Item item) {

        name = item.get_item();
        date = item.get_date();
        cob = item.get_cob();
        interest = item.get_interest();
        count = item.get_count();
    }


    public void writeToDb() {

        try {

            //statment.setString(); 
        }

        } catch (SQLException e) {
            e.printStackTrace();
        } 

}

我在包中有三个不同的类:ParserItemDispatcherDatabase。我正在使用一个重复使用固定数量的线程(10)的线程池。我在Parser 类的回调update() 方法中收到更新。随着更新的到来,我创建了 Item 对象,这些对象作为可运行的任务提交以供执行。从ItemDispatcher 我将item 传递给Database 类。我意识到有一个问题。我需要 Database 类来连接到数据库,但是由于线程正在为每个项目调用 Database constructor,我不想每次都创建连接,而是使用一个被初始化且永远不会再创建的连接。不知道如何做到这一点,有人可以提供一些想法和建议吗?我不想让解析器类知道数据库类。我在哪里可以添加连接和preparedStatement 代码?

【问题讨论】:

    标签: java multithreading concurrency prepared-statement


    【解决方案1】:

    创建一个单例 DAO(数据访问对象)类,并让该类初始化池。如果您不确定这两个术语,请询问,我会为您找到一些代码。

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class ItemDAO {
    
        private static ItemDAO dao;
        private Connection conn;
        private PreparedStatement prepStat;
        private static final String SQL_INSERT_ITEM = "INSERT INTO tbl_item SET id=?`, name = ?, count = ?;";
    
        private ItemDAO() {
            conn = null; /* put initialization code for the connection here */
            try {
                prepStat = conn.prepareStatement(SQL_INSERT_ITEM); // prepare a statement
            } catch (SQLException e) {
                // What do you want to do if it fails?
                e.printStackTrace();
            }
        }
    
        public static ItemDAO getInstance() {
            if (dao == null)
                dao = new ItemDAO();
            return dao;
        }
    
        public void writeItemToDB(Item item) throws SQLException {
            prepStat.setInt(1, item.getId());
            prepStat.executeUpdate();
        }
    }
    

    此代码不是线程安全的,但它将在每个线程中使用相同的连接。如果您需要线程安全(您确实需要),您可以使用提供线程安全的 ConnectionPool 并将线程数设置为 1。“BoneCP”是众所周知的连接池的名称。

    【讨论】:

    • “让这个类初始化池”。你能解释一下这是什么意思吗?
    • 表示不是“private Connection conn;”在上面的代码中,这是一个非线程安全的单个连接,您可能希望使用 BoneCP 的“私有 BoneCP 连接池;”这是一个用于连接池的第三方库,可为您提供线程安全。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 2018-04-18
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多