개발 중에 데이터베이스에 대한 일반적인 추가, 삭제, 수정, 검색 등의 작업을 수행해야 하는 경우가 많습니다. 데이터가 적으므로 직접 운영할 수 있으나, 데이터 양이 증가할 경우 데이터베이스의 각 연결 및 해제에 일정 시간이 소요됩니다. 이때 데이터베이스 연결 풀을 이용하여 데이터베이스 링크를 유지하고 관리할 수 있습니다. 프로그램에서 데이터베이스 연결로 인한 오버헤드를 줄이고, 데이터베이스에 대한 부담을 줄일 수 있는데, 데이터베이스 연결 풀이란 무엇일까요? 이름 그대로 연못입니다. 연못에 있는 것은 물고기를 키우는 연못입니다. 직접 생선을 사거나 키울 필요가 없습니다. 데이터베이스 연결 풀은 데이터베이스에 대한 링크를 저장하는 데 사용됩니다. 모든 링크는 사용 후 직접 가져올 수 있습니다. 이 기능을 사용하면 직접 코드를 작성할 필요가 없습니다. 일부 오픈 소스 연결 풀에는 c3p0, dbcp 및 proxool이 있습니다. c3p0과 proxool은 전혀 사용하지 않았습니다. 간단하게 dbcp pool을 사용했습니다. 여기서는 dbcp 데이터베이스 연결 풀 사용 방법과 사용 시 발생할 수 있는 몇 가지 함정에 대해 설명하겠습니다.
그림 1, Connection Pool 사용 전
그림 2 Connection Pool 사용 후
그림과 같이 위의 1과 같이 Connection Pool을 사용하기 전에 데이터베이스에 매번 링크가 설정되어 있으며 언제든지 해제해야 합니다. 데이터 양이 많을 경우 데이터베이스에 연결하는 데 많은 오버헤드가 필요합니다. 데이터베이스에 대한 빈번한 액세스 및 해제도 데이터베이스에 많은 부담을 줍니다. 그림 2는 데이터베이스 연결 풀을 사용한 후 모든 링크가 해제되지 않고 풀에 배치되는 것을 보여줍니다. 풀은 데이터베이스에 대한 긴 링크를 유지합니다. 링크가 끊어지면 자동으로 다시 연결됩니다.
에는 tomcat-dbcp.jar이 포함되어 있습니다. 그게 전부이고 나머지는 기본 패키지입니다
dbname.Driver=com.mysql.jdbc.Driver dbname.Url=jdbc:mysql://<your ip>/<your dbname>?useUnicode=true&characterEncoding=UTF-8 &autoReconnect=true&failOverReadOnly=false&maxReconnects=10&autoReconnectForPools=true&zeroDateTimeBehavior=convertToNull&connectTimeout=3000 dbname.Username=<your username> dbname.Password=<your password> dbname.InitialSize=15 dbname.MinIdle=10 dbname.MaxIdle=20 dbname.MaxWait=5000 dbname.MaxActive=20 dbname.validationQuery=select 1
중에서 이러한 구성은 각각에 대해
여기서 드라이버, URL, 사용자 이름, 비밀번호는 일반적인 데이터베이스 연결 구성입니다.
InitialSize为初始化建立的连接数
minidle为数据库连接池中保持的最少的空闲的链接数
maxidle数据库连接池中保持的最大的连接数
maxwait等待数据库连接池分配连接的最长时间,超出之后报错
maxactivite最大的活动链接数,如果是多线程可以设置为超出多线程个数个链接数
위는 스레드 풀을 사용할 때 사용하는 코드입니다. DBDAO 부분은 일괄 처리, 쿼리, 업데이트 등 사용자의 필요에 따라 직접 구현해야 합니다. 이러한 기능은 개인의 필요에 따라 수정될 수 있으므로 생성한 링크가 원하는 링크인지 어떻게 판단합니까? ? 확인하는 방법은 두 가지가 있습니다
1. 빈 데이터베이스를 만들고 링크 수를 확인합니다
2. Linux
에서 링크 수를 확인하고 프로세스 ID를 가져옵니다. 🎜>
<pre name="code" class="java">validationQuery测试是否连接是有效的sql语句
public abstract class DB { private static HashMap<String, DataSource> dsTable = new HashMap<String, DataSource>();//此处记得用static private BasicDataSource ds; private PreparedStatement stmt = null; private DataSource getDataSource(String n) { if (dsTable.containsKey(n)) { return dsTable.get(n);//如果不同的数据库,多个连接池 } else { synchronized (dsTable) { ds = new BasicDataSource(); ds.setDriverClassName(DBConfig.getString("db", n.concat(".Driver")));//将<yourname>.properties的值读进来 ds.setUrl(DBConfig.getString("db", n.concat(".Url"))); ds.setUsername(DBConfig.getString("db", n.concat(".Username"))); ds.setPassword(DBConfig.getString("db", n.concat(".Password"))); ds.setInitialSize(DBConfig.getInteger("db", n.concat(".InitialSize"))); ds.setMinIdle(DBConfig.getInteger("db", n.concat(".MinIdle"))); ds.setMaxIdle(DBConfig.getInteger("db", n.concat(".MaxIdle"))); ds.setMaxWait(DBConfig.getInteger("db", n.concat(".MaxWait"))); ds.setMaxActive(DBConfig.getInteger("db", n.concat(".MaxActive"))); ds.setValidationQuery(DBConfig.getString("db", n.concat(".validationQuery"))); dsTable.put(n, ds); return ds; } } } protected Connection conn; public boolean open() throws SQLException { BasicDataSource bds=(BasicDataSource)this.getDataSource(this.getConnectionName()); System.out.println("connection_number:"+bds.getNumActive()+"dsTable:"+dsTable); this.conn = this.getDataSource(this.getConnectionName()).getConnection(); return true; } public void close() throws SQLException { if (this.conn != null) this.conn.close(); } protected abstract String getConnectionName();//此函数可以根据自己的需求,将数据库的名字传进来即可 public void prepareStatement(String sql) throws SQLException { this.stmt = this.conn.prepareStatement(sql); } public void setObject(int index, Object value, int type) throws SQLException { this.stmt.setObject(index, value, type); } public void setObject(int index, Object value) throws SQLException { this.stmt.setObject(index, value); } public int execute() throws SQLException { return this.stmt.executeUpdate(); } }