Connection (建立連線)
在於資料庫互動的時候, 第一件事是和資料來源(Data Source)也就是資料庫建立連線(Connection). 可以從這兩個類從資料來源取得連線:
DriverManager: 在 java.sql 包中, 連線時必須要指定 URL 去連線, 在 JDBC4.0 之前都要顯式地去載入驅動類, JDBC4.0後自動載入 CLASSPATH 中的驅動.
DataSource: 在 javax.sql 包中, 與 Driver Manager 不同的是, 一個資料庫驅動是一個DataSource. DataSource 可以提供連線池功能, 在 EE 中使用較為頻繁.
下面以 JAVADB 和 MySQL 為例, 在 JAVA DB 中有以下表:
CREATE TABLE tags
(
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
name VARCHAR(32) NOT NULL,
CONSTRAINT primary_key PRIMARY KEY (id)
);
表結構如下:
ij> describe tags;
COLUMN_NAME |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
------------------------------------------------------------------------------
ID |INTEGER |0 |10 |10 |AUTOINCRE&|NULL |NO
NAME |VARCHAR |NULL|NULL|32 |NULL |64 |NO
(Note: JAVA DB 有兩種執行模式, 一種是 Embedded 模式, 一種是 Client-Server 模式. 前者的url是jdbc:derby:dbName
, Embedded模式只能由執行時的Java程式訪問; 後者url是jdbc:derby://host:port/dbName
, 可以由Java程式和ij
工具同時訪問. 在這裡,我們適用後者).
在 MySQL 中有以下表:
CREATE TABLE posts
(
id INTEGER NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
dt_create DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
visible BOOLEAN NOT NULL DEFAULT TRUE,
PRIMARY KEY (id)
);
表結構如下:
mysql> describe posts;
+-----------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| content | text | NO | | NULL | |
| dt_create | datetime | NO | | CURRENT_TIMESTAMP | |
| visible | tinyint(1) | NO | | 1 | |
+-----------+--------------+------+-----+-------------------+----------------+
5 rows in set (0.01 sec)
使用Driver Manager
在資料庫中建立好表後, 我們該往資料庫中寫資料了, 以下程式碼示例瞭如何從 DriverManager 新建一個連線, 並往資料庫中插入一條資料:
package self.learn.sid.basic;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class BlogDB {
private static Connection getConnection(Properties props) throws SQLException {
String url = props.getProperty("url");
String user = props.getProperty("user");
Connection conn = null;
if (user.length() == 0) {
conn = DriverManager.getConnection(url);
} else {
conn = DriverManager.getConnection(url, props);
}
String dbName = props.getProperty("dbName");
conn.setCatalog(dbName);
return conn;
}
public static void InsertNewPost() throws SQLException, IOException {
Properties dbProps = new Properties();
dbProps.load(ClassLoader.getSystemResourceAsStream("db.mysql.props"));
Connection conn = getConnection(dbProps);
Statement stmt = conn.createStatement();
String sql = "INSERT INTO posts "
+ "VALUES (NULL, \"First Post\", \"Hello!\", DEFAULT, true)";
int nRows = stmt.executeUpdate(sql);
assert(nRows == 1);
stmt.close();
conn.close();
}
public static void InsertNewTag() throws SQLException, IOException {
Properties dbProps = new Properties();
dbProps.load(ClassLoader.getSystemResourceAsStream("db.javadb.props"));
Connection conn = getConnection(dbProps);
Statement stmt = conn.createStatement();
String sql = "INSERT INTO TAGS "
+ "VALUES (DEFAULT, \'Java\')";
int nRows = stmt.executeUpdate(sql);
assert(nRows == 1);
stmt.close();
conn.close();
}
public static void main(String[] args) throws IOException, SQLException {
BlogDB.InsertNewPost();
BlogDB.InsertNewTag();
}
}
在這個例子中, 有以下兩個要點:
- DriverManager 同時管理著 Mysql 和 Derby 這兩個資料庫驅動
- 當需要一個資料庫連線的時候, 通過呼叫
DriverManager.getConnection(url)
, 根據url
的不同來獲取相應的資料庫連線.
使用 DataSource
使用 DataSource 建立連線時, 可以不用傳入 url
. 值得注意的是, 雖然 DataSource 介面相同, 但是各個廠商的完成度有差異. 而且沒有 DataSourceManager 這樣的介面, 對於 DataSource 需要我們自己管理. 下面我們修改 DriverManager 的程式碼, 從 DataSource 新建連線:
public class BlogDB {
private static final String KEY_MYSQL = "MYSQL";
private static final String KEY_DERBY = "DERBY";
private static Map<String, DataSource> dsMap = new HashMap<String, DataSource>();
private static Connection getConnection(Properties props) throws SQLException {
String url = props.getProperty("url");
String dbName = props.getProperty("dbName");
String user = props.getProperty("user");
String pswd = props.getProperty("password");
Connection conn = null;
if (url.matches("^jdbc:mysql:.*")) {
conn = getMySQLConnection(dbName, user, pswd);
} else if (url.matches("^jdbc:derby:.*")){
conn = getDerbyConnection(dbName, user, pswd);
}
return conn;
}
private static Connection getMySQLConnection(String dbName, String user, String pswd) throws SQLException {
Connection conn = null;
MysqlDataSource ds = null;
if (!dsMap.containsKey(KEY_MYSQL)) {
ds = new MysqlDataSource();
ds.setDatabaseName(dbName);
} else {
ds = (MysqlDataSource)dsMap.get(KEY_MYSQL);
}
conn = ds.getConnection(user, pswd);
if (!dsMap.containsKey(KEY_MYSQL)) {
dsMap.put(KEY_MYSQL, ds);
}
return conn;
}
private static Connection getDerbyConnection(String dbName, String user, String pswd) throws SQLException {
Connection conn = null;
ClientDataSource ds = null;
if (!dsMap.containsKey(KEY_DERBY)) {
ds = new ClientDataSource();
ds.setDatabaseName(dbName);
} else {
ds = (ClientDataSource)dsMap.get(KEY_DERBY);
}
if (user != null && user.length() > 0) {
conn = ds.getConnection(user, pswd);
} else {
conn = ds.getConnection();
}
if (!dsMap.containsKey(KEY_DERBY)) {
dsMap.put(KEY_DERBY, ds);
}
return conn;
}
public static void InsertNewPost() throws SQLException, IOException {}
public static void InsertNewTag() throws SQLException, IOException {}
public static void main(String[] args) throws IOException, SQLException {}
}
可以看出:
- 呼叫
DataSource.getConnection()
的時候, 我們不用傳入 URL. - 需要自己管理 DataSource, 我們在
getConnection(Properties props)
中解析url
只是為了解析DataSource的型別, 為不同的型別返回不同連線. 這樣可以適用和 DriverManager 例子 相同的配置檔案.
在 EE 中使用 DataSource
在 EE 中, DataSource
不需要手動去 new
出來, 一般是修改配置新增資料來源, 然後通過 JNDI 在程式中獲取對 DataSource的引用:
以 Tomcat 和 Mysql為例:
首先要在
WEB-INF/web.xml
中 新增一個資源, 型別為javax.sql.DataSource
, 並修改 JNDI 名字為jdbc/testDB
:<resource-ref> <description> Resource reference to a factory for java.sql.Connection instances that may be used for talking to a particular database that is configured in the configurartion for the web application. </description> <res-ref-name> jdbc/testDB </res-ref-name> <res-type> javax.sql.DataSource </res-type> <res-auth> Container </res-auth> </resource-ref>
其次要在
META-INF/context.xml
中新增 DataSource 相關配置:<Resource name="jdbc/testDB" auth="Container" type="javax.sql.DataSource" username="root" password="5858982Znx" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/testDB" maxActive="100" maxIdle="30" maxWait="10000" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"/>
在程式中, 我們就可以這樣獲取連線了:
public Connection getConnection() throws NamingException, SQLException { Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); DataSource ds = (DataSource) envCtx.lookup("jdbc/testDB"); Connection conn = ds.getConnection(); conn.setAutoCommit(false); return conn; }
相關文章
- .Net 8.0 下的新RPC,IceRPC之如何建立連線connectionRPC
- 06 建立MySQL連線MySql
- laravel建立軟連線Laravel
- ElasticSearch連線池建立Elasticsearch
- HTTPS建立連線HTTP
- TCP的連線建立TCP
- ubuntu建立軟連線Ubuntu
- 【JDBC】使用OracleDataSource建立連線池用於連線OracleJDBCOracle
- Mysql連線錯誤:Mysql Host is blocked because of many connection errorsMySqlBloCError
- SecureCRT連線CentOS不間斷出現“Connection was reset.”SecurecrtCentOS
- ssh連線Linux收到The remote system refused the connection報錯LinuxREM
- oracle裡的連線(connection)究竟是指什麼Oracle
- centos無法建立ssl連線CentOS
- SSH建立連線的過程
- 建立 ODBC DSN ASP 連線DSN
- 資料庫連線不能建立.資料庫
- SQLSERVER建立連線伺服器SQLServer伺服器
- win10如何建立寬頻連線_windows10建立寬頻連線的方法Win10Windows
- weblogic連線池重置(Connection reset)問題解決方案Web
- linux 建立連線命令 ln -s 軟連結Linux
- 最多能建立多少個 TCP 連線?TCP
- windows7連線hbase建立表Windows
- mysql建立ssl安全連線的配置MySql
- SSL連線建立過程分析(1)
- linux下建立迴圈連線Linux
- vncserver建立與客戶端連線VNCServer客戶端
- 不能建立sqlserver資料庫連線SQLServer資料庫
- 連線華為雲的Redis服務報錯“Error: Connection reset by peer”RedisError
- Java專案連線資料庫Mysql報錯create connection SQLExceptionJava資料庫MySqlException
- 錯誤 101 (net::ERR_CONNECTION_RESET):連線已重置
- python中socket建立客戶連線Python
- win7如何建立撥號連線?Win7
- IPSECVPN連線建立(IKE)詳解
- 如何處理WordPress網站提示“建立資料庫連線時出錯”或“Error establishing a database connection”錯誤網站資料庫ErrorDatabase
- OkHttp 原始碼剖析系列(六)——連線複用機制及連線的建立HTTP原始碼
- TCP建立連線三次握手和釋放連線四次握手TCP
- 【譯】 WebSocket 協議第七章——關閉連線(Closing the Connection)Web協議
- ibm websphere中介軟體連線池connection pool一些文件IBMWeb