Java Web數據源詳解
Java Web連接數據庫一般有直接JDBC和數據源兩種方式,
1、JDBC:
在MySQL中創建數據庫:
create database login;
use login;
create table user (
username varchar ( 50 ) not null ,
password varchar ( 50 ),
primary key (username)
);
insert into user (username,password) values ("CoderDream"," 12345678 ");
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Test{
public static void main(String[]args){
try {
// A:1、2都可以
// Class.forName("org.gjt.mm.mysql.Driver"); // 1
Class.forName( " com.mysql.jdbc.Driver " ); // 2
// B:連接數據庫,用戶名為:root,密碼為空
Connectionconn = DriverManager.getConnection(
" jdbc:mysql://localhost:3306/login " , " root " , "" );
// C:創建Statement
Statementstmt = conn.createStatement();
// D:查詢數據庫中用戶CoderDream的密碼字段
Stringsql = " selectpasswordfromuserwhereusername='CoderDream' " ;
// E:得到結果集
ResultSetrs = stmt.executeQuery(sql);
// F:處理結果集,簡單的輸出password
while (rs.next()){
System.out.print(rs.getString( " password " )); // 輸出結果為 12345678
}
// G:關閉資源
rs.close();
stmt.close();
conn.close();
} catch (Exceptione){
e.printStackTrace();
}
}
}
在Struts中一般會寫一個公用類,用于連接數據庫:
A、創建數據庫:ADDRESSBOOKSAMPLE.sql
CREATE DATABASE ADDRESSBOOKSAMPLE;
USE ADDRESSBOOKSAMPLE;
CREATE TABLE ADDRESSBOOK_TABLE(ID INT ( 4 )AUTO_INCREMENT NOT NULL PRIMARY KEY ,NAME VARCHAR ( 25 ),PHONE VARCHAR ( 10 ),ADDRESS VARCHAR ( 50 ));
INSERT INTO ADDRESSBOOK_TABLE VALUES ( 1 , ' Wang ' , ' 56671234 ' , ' Beijing,Haidian ' );
INSERT INTO ADDRESSBOOK_TABLE VALUES ( 2 , ' Zhang ' , ' 45664568 ' , ' Shanghai,Pudong ' );
INSERT INTO ADDRESSBOOK_TABLE VALUES ( 3 , ' Cheng ' , ' 56643456 ' , ' Tianjing ' );
INSERT INTO ADDRESSBOOK_TABLE VALUES ( 4 , ' Zhao ' , ' 56789988 ' , ' Hainan ' );
INSERT INTO ADDRESSBOOK_TABLE VALUES ( 5 , ' Cao ' , ' 56498543 ' , ' Heibei ' );
B、公用類:DbUtil.java
import java.sql.Connection;
import java.sql.DriverManager;
/**
*<strong>DbUtil</strong>isautilityclasstocreateaconnectiontoour
*sampledatabase.
*/
public class DbUtil{
static StringdriverName = " com.mysql.jdbc.Driver " ;
static StringdbUrl = " jdbc:mysql:// " ;
public DbUtil(){
}
public static ConnectionconnectToDb(StringhostName,StringdatabaseName)
throws Exception{
Connectionconnection = null ;
StringconnName = dbUrl + hostName + " :3306 " + " / " + databaseName;
Class.forName(driverName).newInstance();
connection = DriverManager.getConnection(connName, " root " , "" );
return connection;
}
public static ConnectionconnectToDb(StringdatabaseName) throws Exception{
return (connectToDb( " localhost " ,databaseName));
}
public static ConnectionconnectToDb() throws Exception{
return (connectToDb( " localhost " , " addressbooksample " ));
}
}
C、JavaBean中調用公用類:
Connectioncon = DbUtil.connectToDb();
PreparedStatementpStmt = null ;
try {
pStmt = con.prepareStatement( " INSERTINTO " + Constants.TABLENAME
+ " (name,phone,address) " + " values(?,?,?) " );
con.setAutoCommit( false );
pStmt.setString( 1 ,name);
pStmt.setString( 2 ,phone);
pStmt.setString( 3 ,address);
pStmt.executeUpdate();
con.commit();
} catch (Exceptionex){
try {
con.rollback();
} catch (SQLExceptionsqlex){
sqlex.printStackTrace(System.out);
}
throw ex;
} finally {
try {
pStmt.close();
con.close();
} catch (Exceptione){
e.printStackTrace();
}
}
}
public static Vectorsearch(StringstrSql) throws Exception{
VectoraddressbookBeans = new Vector();
Connectioncon = DbUtil.connectToDb();
PreparedStatementpStmt = null ;
ResultSetrs = null ;
try {
pStmt = con.prepareStatement(strSql);
rs = pStmt.executeQuery();
while (rs.next()){
addressbookBeans.add( new AddressBookBean(rs.getString( " NAME " ),
rs.getString( " PHONE " ),rs.getString( " ADDRESS " )));
}
return addressbookBeans;
} finally {
try {
rs.close();
pStmt.close();
con.close();
} catch (Exceptione){
e.printStackTrace();
}
}
}
2、一般數據源配置
在struts-config.xml的<data-sources>標簽中加入:< data-sources >
< data-source type ="org.apache.commons.dbcp.BasicDataSource" >
< set-property property ="autoCommit" value ="true" />
< set-property property ="description"
value ="MySQLDataSource" />
< set-property property ="driverClassName"
value ="com.mysql.jdbc.Driver" />
< set-property property ="maxCount" value ="10" />
< set-property property ="minCount" value ="2" />
< set-property property ="username" value ="root" />
< set-property property ="password" value ="" />
< set-property property ="url"
value ="jdbc:mysql://localhost:3306/addressbooksample" />
</ data-source >
</ data-sources >
mysql-connector-java-5.1.0-bin.jar
commons-dbcp-1.2.2.jar
commons-pool-1.3.jar
注意:這里有個一個屬性“ property ="driverClassName"” 千萬要 寫成"driverClassName",而不是“driverClass”,否則會找不到!
孫衛琴的《精通Struts》就是漏掉了Name,讓我調試了一個下午。
org.apache.commons.dbcp.BasicDataSource
throws SQLException{

// LoadtheJDBCdriverclass
if (driverClassName != null ){
try {
Class.forName(driverClassName);
} catch (Throwablet){
Stringmessage = " CannotloadJDBCdriverclass' " +
driverClassName + " ' " ;
logWriter.println(message);
t.printStackTrace(logWriter);
throw new SQLNestedException(message,t);
}
}
// CreateaJDBCdriverinstance
Driverdriver = null ;
try {
driver = DriverManager.getDriver(url);
} catch (Throwablet){
Stringmessage = " CannotcreateJDBCdriverofclass' " +
(driverClassName != null ? driverClassName: "" ) +
" 'forconnectURL' " + url + " ' " ;
logWriter.println(message);
t.printStackTrace(logWriter);
throw new SQLNestedException(message,t);
}
}
atorg.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java: 1150 )
atorg.apache.commons.dbcp.BasicDataSource.setLogWriter(BasicDataSource.java: 959 )
atorg.apache.struts.action.ActionServlet.initModuleDataSources(ActionServlet.java: 778 )
atorg.apache.struts.action.ActionServlet.init(ActionServlet.java: 331 )
atjavax.servlet.GenericServlet.init(GenericServlet.java: 212 )
atorg.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java: 1139 )
atorg.apache.catalina.core.StandardWrapper.load(StandardWrapper.java: 966 )
atorg.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java: 3956 )
atorg.apache.catalina.core.StandardContext.start(StandardContext.java: 4230 )
atorg.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java: 760 )
atorg.apache.catalina.core.ContainerBase.addChild(ContainerBase.java: 740 )
atorg.apache.catalina.core.StandardHost.addChild(StandardHost.java: 544 )
atorg.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java: 920 )
atorg.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java: 883 )
atorg.apache.catalina.startup.HostConfig.deployApps(HostConfig.java: 492 )
atorg.apache.catalina.startup.HostConfig.start(HostConfig.java: 1138 )
atorg.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java: 311 )
atorg.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java: 120 )
atorg.apache.catalina.core.ContainerBase.start(ContainerBase.java: 1022 )
atorg.apache.catalina.core.StandardHost.start(StandardHost.java: 736 )
atorg.apache.catalina.core.ContainerBase.start(ContainerBase.java: 1014 )
atorg.apache.catalina.core.StandardEngine.start(StandardEngine.java: 443 )
atorg.apache.catalina.core.StandardService.start(StandardService.java: 448 )
atorg.apache.catalina.core.StandardServer.start(StandardServer.java: 700 )
atorg.apache.catalina.startup.Catalina.start(Catalina.java: 552 )
atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)
atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 39 )
atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 25 )
atjava.lang.reflect.Method.invoke(Method.java: 597 )
atorg.apache.catalina.startup.Bootstrap.start(Bootstrap.java: 295 )
atorg.apache.catalina.startup.Bootstrap.main(Bootstrap.java: 433 )
Causedby:java.sql.SQLException:Nosuitabledriver
atjava.sql.DriverManager.getDriver(DriverManager.java: 264 )
atorg.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java: 1143 )

提示class ' '不能連接URL!
數據源配置好了以后,我們就可以在Action中得到DataSource。
在InsertAction的execute()方法中:
Connectioncon = ds.getConnection();
bean.insert(con);
這樣,改寫Bean中的insert()方法和search()方法,傳入參數增加一個“Connection con”:
PreparedStatementpStmt = null ;
try {
pStmt = con.prepareStatement( " INSERTINTO " + Constants.TABLENAME
+ " (name,phone,address) " + " values(?,?,?) " );
con.setAutoCommit( false );
pStmt.setString( 1 ,name);
pStmt.setString( 2 ,phone);
pStmt.setString( 3 ,address);
pStmt.executeUpdate();
con.commit();
} catch (Exceptionex){
try {
con.rollback();
} catch (SQLExceptionsqlex){
sqlex.printStackTrace(System.out);
}
throw ex;
} finally {
try {
pStmt.close();
con.close();
} catch (Exceptione){
e.printStackTrace();
}
}
}
public static Vectorsearch(Connectioncon,StringstrSql) throws Exception{
VectoraddressbookBeans = new Vector();
PreparedStatementpStmt = null ;
ResultSetrs = null ;
try {
pStmt = con.prepareStatement(strSql);
rs = pStmt.executeQuery();
while (rs.next()){
addressbookBeans.add( new AddressBookBean(rs.getString( " NAME " ),
rs.getString( " PHONE " ),rs.getString( " ADDRESS " )));
}
return addressbookBeans;
} finally {
try {
rs.close();
pStmt.close();
con.close();
} catch (Exceptione){
e.printStackTrace();
}
}
}
這樣就不需使用數據庫工具類 DbUtil 了。
3、插件方式,任何地方都可以得到數據源。
以一般方式配置的數據源有一個局限性,就是只能在Action中得到,因為要用到HttpServletRequest作為參數來得到數據源。
解決的辦法是寫一個插件,這個插件實現了Struts的PlugIn接口。
通過這個插件,我們可以在任何類中(包括Action、JavaBean和其他類)直接得到數據源,并建立連接:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
public class Conn implements PlugIn{
private static DataSourcedataSource = null ;
private Connectionconn = null ;
private PreparedStatementpreStmt = null ;
private Statementstmt = null ;
// 得到數據源
public void init(ActionServletservlet,ModuleConfigconfig){
dataSource = (DataSource)servlet.getServletContext().getAttribute(
" org.apache.struts.action.DATA_SOURCE " );
}
public Conn() throws SQLException{
if (dataSource != null ){
conn = dataSource.getConnection();
}
}
public ResultSetexecuteQuery(Stringsql){
ResultSetrs = null ;
try {
if (stmt == null ){
stmt = conn.createStatement();
}
rs = stmt.executeQuery(sql);
} catch (SQLExceptione){
e.printStackTrace();
}
return rs;
}
public void executeUpdate(Stringsql) throws SQLException{
if (stmt == null ){
stmt = conn.createStatement();
}
stmt.executeUpdate(sql);
}
public ConnectiongetConn(){
return conn;
}
public void prepareStatement(StringsqlStr) throws SQLException{
preStmt = conn.prepareStatement(sqlStr);
}
public void setString( int index,Stringvalue) throws SQLException{
preStmt.setString(index,value);
}
public void setInt( int index, int value) throws SQLException{
preStmt.setInt(index,value);
}
public void setBoolean( int index, boolean value) throws SQLException{
preStmt.setBoolean(index,value);
}
public void setLong( int index, long value) throws SQLException{
preStmt.setLong(index,value);
}
public void setFloat( int index, float value) throws SQLException{
preStmt.setFloat(index,value);
}
public void setBytes( int index, byte []value) throws SQLException{
preStmt.setBytes(index,value);
}
public void clearPreStmt() throws SQLException{
preStmt.clearParameters();
preStmt = null ;
}
public ResultSetexecuteQuery() throws SQLException{
if (preStmt != null ){
return preStmt.executeQuery();
} else {
return null ;
}
}
public void executeUpdate() throws SQLException{
if (preStmt != null ){
preStmt.executeUpdate();
}
}
public void close(){
try {
if (stmt != null ){
stmt.close();
stmt = null ;
}
if (preStmt != null ){
preStmt.close();
preStmt = null ;
}
if (conn != null ){
conn.close();
conn = null ;
System.out.println( " ****aconnectionisclosed**** " );
}
} catch (Exceptione){
System.err.println(e.getMessage());
}
}
public void destroy(){
}
}
在struts-config.xml中配置數據源:
< data-sources >
< data-source key ="org.apache.struts.action.DATA_SOURCE"
type ="org.apache.commons.dbcp.BasicDataSource" >
< set-property property ="autoCommit" value ="true" />
< set-property property ="description"
value ="MySQLDataSource" />
< set-property property ="driverClassName"
value ="com.mysql.jdbc.Driver" />
< set-property property ="maxCount" value ="10" />
< set-property property ="minCount" value ="2" />
< set-property property ="username" value ="root" />
< set-property property ="password" value ="" />
< set-property property ="url"
value ="jdbc:mysql://localhost:3306/addressbooksample" />
</ data-source >
</ data-sources >
< plug-in className ="addressbook.plug.Conn" ></ plug-in >
這樣,我們在JavaBean和其他類中就可以直接得到數據源的Connection了:
注意:
在Struts1.3中已經取消了<data-sources>標簽,也就是說只能在1.2版中配置,因為Apache不推薦在struts-config.xml中配置數據源。
參考資料:
1、
在struts中以無參數的javabeans的方式調用struts-config.xml中配置的數據源
2、
struts數據源管理器
3、
struts 數據源問題
源代碼:
1
JDBC版:addressbookV1.zip
2
普通配置版:addressbookV2.zip
3
PlugIn版: addressbookV3.zip
PS: 可以直接將源代碼導入eclipse,然后加入Struts 1.2的所有包和另外3個包
mysql-connector-java-5.1.0-bin.jar
、
commons-dbcp-1.2.2.jar
、
commons-pool-1.3.jar
。
數據庫推薦使用BeanSoft的
MySQL綠色版
。
<!-- Google Reader shared發布代碼開始 --> <script type="text/javascript" src="http://www.google.com/reader/ui/publisher.js"></script><script type="text/javascript" src="http://www.google.com/reader/public/javascript/user/00697638153916680411/state/com.google/broadcast?n=5&callback=GRC_p(%7Bc%3A%22green%22%2Ct%3A%22%5Cu8FD9%5Cu4E9B%5Cu6587%5Cu7AE0%5Cu4E5F%5Cu503C%5Cu5F97%5Cu4E00%5Cu770B%22%2Cs%3A%22false%22%7D)%3Bnew%20GRC"></script><!-- Google Reader shared發布代碼結束 -->
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
