为什么要用DataSource代替DriverManager

这个问题本来是SO上的一个问答:http://stackoverflow.com/questions/15198319/why-do-we-use-a-datasource-instead-of-a-drivermanager

大致意思是使用DataSource有更好的可扩展性并且更易于维护。
使用DataSource你不需要每次连接都要配置一大段的用户名密码端口,然后才能获得连接去使用数据库。DS方式的话只需要初始化的时候配置一次,每次使用直接拿出连接用就好了。
关于可扩展性,就是DataSource提供连接池,而DM不提供。

JDK8里的描述:

A factory for connections to the physical data source that this DataSource object represents. An alternative to the DriverManager facility, a DataSource object is the preferred means of getting a connection. An object that implements the DataSource interface will typically be registered with a naming service based on the Java™ Naming and Directory (JNDI) API.

先看下原来DM的用法(找了个实习生写的代码,顺便帮他review):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void addMonitorLog(MonitorLog ml) throws IOException, ClassNotFoundException, SQLException{
Connection conn;
Statement st;
ManipuData md = new ManipuData();

Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(md.readProp());
String sql =
"insert into MSM_MonitorLog"
+ "(db_id,msg,check_time,need_warn)values("
+ ml.getDb_id()+",'"+ml.getMsg()+"',NOW(),"
+ml.getNeed_warn()+")";

st = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
st.executeUpdate(sql);
st.close();
conn.close();
}

使用DataSource的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void addMonitorLog(MonitorLog ml) throws IOException, ClassNotFoundException, SQLException{
PreparedStatement stmt = null;
DataSource ds = null; //fake ds
Connection conn = ds.getConnection();
final String sql = "insert into MSM_MonitorLog(db_id,msg,check_time,need_warn) values(?,?,?,?)";
String[] params = {ml.getDb_id(),ml.getMsg(),NOW(),ml.getNeed_warn()};
try {
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
this.fillStatement(stmt, params);
stmt.executeUpdate();
} catch (SQLException e) {
this.rethrow(e, sql, params);
} finally {
close(stmt);
if (closeConn) {
close(conn);
}
}
}

最后推荐使用dbutil封装jdbc的用法:

1
2
3
4
5
6
public void addMonitorLog(MonitorLog ml) throws IOException, ClassNotFoundException, SQLException{
final QueryRunner qr = MySQLHelper.getQueryRunner();
final String sql = "insert into MSM_MonitorLog(db_id,msg,check_time,need_warn) values(?,?,?,?)";
final String[] params = {ml.getDb_id(),ml.getMsg(),NOW(),ml.getNeed_warn()};
qr.batch(sql,params);
}