原文链接:http://blog.csdn.net/cai_xingyun/article/details/41482835

什么是JDBC?

Java语言访问数据库的一种规范,是一套API

JDBC (JavaDatabase Connectivity) API,即Java数据库编程接口,是一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库。比如建立数据库连接、执行SQL语句进行数据的存取操作。

JDBC规范采用接口和实现分离的思想设计了Java数据库编程的框架。接口包含在java.sql及javax.sql包中,其中java.sql属于JavaSE,javax.sql属于JavaEE。这些接口的实现类叫做数据库驱动程序,由数据库的厂商或其它的厂商或个人提供。

为了使客户端程序独立于特定的数据库驱动程序,JDBC规范建议开发者使用基于接口的编程方式,即尽量使应用仅依赖java.sql及javax.sql中的接口和类。

JDBC驱动程序:

什么是JDBC驱动程序?

这些是各个数据库厂家根据JDBC的规范制作的JDBC实现类

JDBC驱动程序的四种类型:

1.       第一种类型的驱动程序的实现是通过将JDBC的调用全部委托给其它编程接口来实现的,比如ODBC。这种类型的驱动程序需要安装本地代码库,即依赖于本地的程序,所以便携性较差。比如JDBC-ODBC桥驱动程序

2.       第二种类型的驱动程序的实现是部分基于Java语言的。即该驱动程序一部分是用Java语言编写,其它部分委托本地的数据库的客户端代码来实现。同类型1的驱动一样,该类型的驱动程序也依赖本地的程序,所以便携性较差

3.       第三种类型的驱动程序的实现是全部基于JAVA语言的。该类型的驱动程序通常由某个中间件服务器提供,这样客户端程序可以使用数据库无关的协议和中间件服务器进行通信,中间件服务器再将客户端的JDBC调用转发给数据库进行处理

4.       第四种类型的驱动程序的实现是全部基于JAVA语言的。该类型的驱动程序中包含了特定数据库的访问协议,使得客户端可以直接和数据库进行通信

JDBC类结构:

DriverManager

Driver                               Driver

Connection                         Connection

Statement                                  Statement

Resultset                                    Resultset

DriverManager:这个是一个实现类,它是一个工厂类,用来生产Driver对象的

这个类的结构设计模式为工厂方法

Driver:这是驱动程序对象的接口,它指向一个实实在在的数据库驱动程序对象,那么这个数据库驱动程序对象是从哪里来的呢?

DriverManager工厂中有个方法:getDriver(String URL),通过这个方法可以得到驱动程序对象,这个方法是在各个数据库厂商按JDBC规范设计的数据库驱动程序包里的类中静态实现的,也就是在静态块中

Connection:这个接口可以制向一个数据库连接对象,那么如何得到这个连接对象呢?

是通过DriverManager工厂中的getConnection(String URL)方法得到的

Statement:用于执行静态的SQL语句的接口,通过Connection中的createStatement方法得到的

Resultset:用于指向结果集对象的接口,结果集对象是通过Statement中的execute等方法得到的

JAVA使用JDBC访问数据库的步骤:

1.     得到数据库驱动程序

2.     创建数据库连接

3.     执行SQL语句

4.     得到结果集

5.     对结果集做相应的处理(增,删,改,查)

6.     关闭资源:这里释放的是DB中的资源

设置classpath:

1.     在java文件中起的包名一定要是工程基目录下的子目录,classpath:基目录

2.     .jar包,需要将这个.jar包的路径包括这个文件的全名添加到classpath中来

Oracle连接字符串的书写格式:

“oracle:jdbc:thin:@ip:1521: 数据库名”,”数据库用户名”,”数据库密码”

简单的例子:

  1. package moudule1.first;
  2.  
  3. import java.sql.*;
  4.  
  5. public class FirstJdbc
  6.  
  7. {
  8.  
  9. public static void main(String[] args)
  10.  
  11. {
  12.  
  13. String sql="select * from yuchen_user";
  14.  
  15. Connection con=null;
  16.  
  17. Statement st=null;
  18.  
  19. ResultSet rs=null;
  20.  
  21. try
  22.  
  23. {
  24.  
  25. Class.forName("oracle.jdbc.driver.OracleDriver");
  26.  
  27. con=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:name", "scott","tiger");
  28.  
  29. st=con.createStatement();
  30.  
  31. rs=st.executeQuery(sql);
  32.  
  33. while(rs.next())
  34.  
  35. {
  36.  
  37. System.out.println(rs.getInt("id"));
  38.  
  39. System.out.println(rs.getString("name"));
  40.  
  41. }
  42.  
  43. }catch(Exception e)
  44.  
  45. {
  46.  
  47. e.printStackTrace();
  48.  
  49. }finally
  50.  
  51. {
  52.  
  53. try
  54.  
  55. {
  56.  
  57. con.close();
  58.  
  59. }catch(Exception e)
  60.  
  61. {}
  62.  
  63. try
  64.  
  65. {
  66.  
  67. st.close();
  68.  
  69. }catch(Exception e)
  70.  
  71. {
  72.  
  73. }
  74.  
  75. try
  76.  
  77. {
  78.  
  79. rs.close();
  80.  
  81. }catch(Exception e)
  82.  
  83. {
  84.  
  85. }
  86.  
  87. }
  88.  
  89. }
  90.  
  91. }

常用数据库的驱动程序及JDBC URL:

Oracle数据库:

驱动程序包名:ojdbc14.jar

驱动类的名字:oracle.jdbc.driver.OracleDriver

JDBC URL:jdbc:oracle:thin:@dbip:port:databasename

说明:驱动程序包名有可能会变

JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部分需要根据数据库的安装情况填写。其中各个部分含义如下:

dbip –为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1。

port –为数据库的监听端口,需要看安装时的配置,缺省为1521。

databasename –为数据库的SID,通常为全局数据库的名字。

举例如果要访问本地的数据库allandb,端口1521,那么URL写法如下:

jdbc:oracle:thin:@localhost:1521:allandb 下载地址如下:

http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html

SQL Server数据库

驱动程序包名:msbase.jar mssqlserver.jar msutil.jar

驱动类的名字:com.microsoft.jdbc.sqlserver.SQLServerDriver

JDBC URL:jdbc:microsoft:sqlserver://dbip:port;DatabaseName=databasename

说明:驱动程序包名有可能会变

JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部需要根据数据库的安装情况填写。其中各个部分含义如下:

dbip –为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1。

port –为数据库的监听端口,需要看安装时的配置,缺省为1433。

databasename –数据库的名字。

举例如果要访问本地的数据库allandb,端口1433,那么URL写法如下:

jdbc: microsoft: sqlserver:@localhost:1433; DatabaseName =allandb

下载地址:http://www.microsoft.com/downloads/details.aspx

 MySQL数据库

驱动程序包名:mysql-connector-java-3.1.11-bin.jar

驱动类的名字:com.mysql.jdbc.Driver

JDBC URL:jdbc:mysql://dbip:port/databasename

说明:驱动程序包名有可能会变

JDBC URL中黑色字体部分必须原封不动的保留,为该驱动识别的URL格式。红色字体部需要根据数据库的安装情况填写。其中各个部分含义如下:

dbip –为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1。

port –为数据库的监听端口,需要看安装时的配置,缺省为3306。

databasename –数据库的名字。

举例如果要访问本地的数据库allandb,端口1433,那么URL写法如下:

jdbc:mysql://localhost:3306/allandb

下载地址:http://dev.mysql.com/downloads/connector/j/

Access数据库

驱动程序包名:该驱动程序包含在JavaSE中,不需要额外安装。

驱动类的名字:sun.jdbc.odbc.JdbcOdbcDriver

JDBC URL:jdbc:odbc:datasourcename

说明:该驱动只能工作在Windows系统中,首先需要在操作系统中建立一个可以访问Access数据库的本地数据源(ODBC),如果名字为allandb,那么URL写法如下:

jdbc:odbc:allandb

PreparedStatement接口:

预编译的sql语句对象

作用: 解决了书写sql语句时一些特殊的字符与sql保留字符冲突的问题,非常方便

  1. /**
  2.  
  3. *知识点:
  4.  
  5. *PreparedStatement接口及方法的使用
  6.  
  7. *程序目标:
  8.  
  9. *java文件:
  10.  
  11. *PreparedInsert.java:连接数据库,插入一条数据
  12.  
  13. *JdbcUtil.java:实现一个工具类,功能:1.连接数据库 2.关闭资源
  14.  
  15. */
  16.  
  17. package moudule1.preparedstatement;
  18.  
  19. import java.sql.*;
  20.  
  21. import moudule1.com.*;
  22.  
  23. public class PreparedInsert
  24.  
  25. {
  26.  
  27. public static void main(String[] args)
  28.  
  29. {
  30.  
  31. String sql="insert into yuchen_user (id,name) values (?,?)";
  32.  
  33. System.out.println(sql);
  34.  
  35. Connection con=null;
  36.  
  37. PreparedStatement ps=null;
  38.  
  39. try{
  40.  
  41. con=JdbcUtil.getConnection();
  42.  
  43. ps=con.prepareStatement(sql);
  44.  
  45. ps.setInt(1,2);
  46.  
  47. ps.setString(2,"zhangsan");
  48.  
  49. ps.executeUpdate();
  50.  
  51. ps.setInt(1,3);
  52.  
  53. ps.setString(2,"lisi");
  54.  
  55. ps.executeUpdate();
  56.  
  57. }catch(Exception e){
  58.  
  59. e.printStackTrace();
  60.  
  61. }finally{
  62.  
  63. JdbcUtil.close(con,ps);
  64.  
  65. }
  66.  
  67. }
  68.  
  69. }
  1. package moudule1.com;
  2.  
  3. import java.sql.*;
  4.  
  5. public class JdbcUtil{
  6.  
  7. public static Connection getConnection() throws Exception{
  8.  
  9. Class.forName("oracle.jdbc.driver.OracleDriver");
  10.  
  11. return DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:name", "scott","tiger");
  12.  
  13. }
  14.  
  15. public static void close(Connection con,Statement st){
  16.  
  17. close(con);
  18.  
  19. close(st);
  20.  
  21. }
  22.  
  23. public static void close(Connection con,Statement st,ResultSet rs){
  24.  
  25. close(con,st);
  26.  
  27. close(rs);
  28.  
  29. }
  30.  
  31. public static void close(Connection con){
  32.  
  33. try{
  34.  
  35. con.close();
  36.  
  37. }catch(Exception e){
  38.  
  39. }
  40.  
  41. }
  42.  
  43. public static void close(Statement st){
  44.  
  45. try{
  46.  
  47. st.close();
  48.  
  49. }catch(Exception e){
  50.  
  51. }
  52.  
  53. }
  54.  
  55. public static void close(ResultSet rs){
  56.  
  57. try{
  58.  
  59. rs.close();
  60.  
  61. }catch(Exception e){
  62.  
  63. }
  64.  
  65. }
  66.  
  67. }

数据库的增删改查的例子:

  1. /**
  2.  
  3. *知识点:
  4.  
  5. *JDBC+SQL+ORACLE
  6.  
  7. *程序目标:
  8.  
  9. *UserDao.java:实现了数据库的增删改查
  10.  
  11. *JdbcUtil.java:工具类,有连库和关闭资源的方法
  12.  
  13. */
  14.  
  15. package moudule1.idus;
  16.  
  17. import java.sql.*;
  18.  
  19. import moudule1.com.*;
  20.  
  21. public class UserDao{
  22.  
  23. private String sql;
  24.  
  25. private Connection con;
  26.  
  27. private Statement st;
  28.  
  29. private ResultSet rs;
  30.  
  31. public UserDao(){
  32.  
  33. sql=null;
  34.  
  35. con=null;
  36.  
  37. st=null;
  38.  
  39. rs=null;
  40.  
  41. }
  42.  
  43. public void insert(){
  44.  
  45. sql="insert into yuchen_user (id,name) values(";
  46.  
  47. sql+="4,'zhouwu')";
  48.  
  49. System.out.println(sql);
  50.  
  51. try{
  52.  
  53. con=JdbcUtil.getConnection();
  54.  
  55. st=con.createStatement();
  56.  
  57. st.executeUpdate(sql);
  58.  
  59. }catch(Exception e){
  60.  
  61. e.printStackTrace();
  62.  
  63. }finally{
  64.  
  65. JdbcUtil.close(con,st);
  66.  
  67. }
  68.  
  69. }
  70.  
  71. public void delete(){
  72.  
  73. sql="delete from yuchen_user where id=2";
  74.  
  75. System.out.println(sql);
  76.  
  77. try{
  78.  
  79. con=JdbcUtil.getConnection();
  80.  
  81. st=con.createStatement();
  82.  
  83. st.executeUpdate(sql);
  84.  
  85. }catch(Exception e){
  86.  
  87. e.printStackTrace();
  88.  
  89. }finally{
  90.  
  91. JdbcUtil.close(con,st);
  92.  
  93. }
  94.  
  95. }
  96.  
  97. public void update(){
  98.  
  99. sql="update yuchen_user set name='liumang' where id=1";
  100.  
  101. System.out.println(sql);
  102.  
  103. try{
  104.  
  105. con=JdbcUtil.getConnection();
  106.  
  107. st=con.createStatement();
  108.  
  109. st.executeUpdate(sql);
  110.  
  111. }catch(Exception e){
  112.  
  113. e.printStackTrace();
  114.  
  115. }finally{
  116.  
  117. JdbcUtil.close(con,st);
  118.  
  119. }
  120.  
  121. }
  122.  
  123. public void select(){
  124.  
  125. sql="select * from yuchen_user";
  126.  
  127. System.out.println(sql);
  128.  
  129. try{
  130.  
  131. con=JdbcUtil.getConnection();
  132.  
  133. st=con.createStatement();
  134.  
  135. rs=st.executeQuery(sql);
  136.  
  137. while(rs.next()){
  138.  
  139. System.out.println(rs.getInt(1));
  140.  
  141. System.out.println(rs.getString(2));
  142.  
  143. }
  144.  
  145. }catch(Exception e){
  146.  
  147. e.printStackTrace();
  148.  
  149. }finally{
  150.  
  151. JdbcUtil.close(con,st,rs);
  152.  
  153. }
  154.  
  155. }
  156.  
  157. public static void main(String[] args){
  158.  
  159. UserDao ud=new UserDao();
  160.  
  161. ud.select();
  162.  
  163. ud.insert();
  164.  
  165. ud.select();
  166.  
  167. ud.update();
  168.  
  169. ud.select();
  170.  
  171. ud.delete();
  172.  
  173. ud.select();
  174.  
  175. }
  176.  
  177. }

一些常用的方法:

  1. /**
  2.  
  3. *知识点:
  4.  
  5. *execute方法,getResultSet(),getUpdateCount()
  6.  
  7. *程序目标:
  8.  
  9. *JdbcUtil.java:工具类,连接数据库,关闭资源
  10.  
  11. *sqlExecutor.java:命令行参数输入sql语句,并执行该语句
  12.  
  13. */
  14.  
  15. package moudule1.fangfa;
  16.  
  17. import java.sql.*;
  18.  
  19. import moudule1.com.*;
  20.  
  21. public class sqlExecutor{
  22.  
  23. public static void main(String[] args){
  24.  
  25. Connection con=null;
  26.  
  27. Statement st=null;
  28.  
  29. try{
  30.  
  31. con=JdbcUtil.getConnection();
  32.  
  33. st=con.createStatement();
  34.  
  35. boolean str=st.execute(args[0]);
  36.  
  37. if(str){
  38.  
  39. ResultSet rs=st.getResultSet();
  40.  
  41. while(rs.next()){
  42.  
  43. System.out.println(rs.getInt("id")+":"+rs.getString("name"));
  44.  
  45. }
  46.  
  47. rs.close();
  48.  
  49. }else{
  50.  
  51. int row=st.getUpdateCount();
  52.  
  53. System.out.println(row);
  54.  
  55. }
  56.  
  57. }catch(Exception e){
  58.  
  59. e.printStackTrace();
  60.  
  61. }finally{
  62.  
  63. JdbcUtil.close(con,st);
  64.  
  65. }
  66.  
  67. }
  68.  
  69. }

2. 补充
  JDBC连接MySQL

加载及注册JDBC驱动程序

Class.forName("com.mysql.jdbc.Driver");

Class.forName("com.mysql.jdbc.Driver").newInstance();

JDBC URL 定义驱动程序与数据源之间的连接

标准语法:

<protocol(主要通讯协议)>:<subprotocol(次要通讯协议,即驱动程序名称)>:<data source identifier(数据源)>

MySQL的JDBC URL格式:

jdbc:mysql//[hostname][:port]/[dbname][?param1=value1][&param2=value2]….

示例:jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password

常见参数:

user                       用户名

password                  密码

autoReconnect                  联机失败,是否重新联机(true/false)

maxReconnect              尝试重新联机次数

initialTimeout               尝试重新联机间隔

maxRows                   传回最大行数

useUnicode                 是否使用Unicode字体编码(true/false)

characterEncoding          何种编码(GB2312/UTF-8/…)

relaxAutocommit            是否自动提交(true/false)

capitalizeTypeNames        数据定义的名称以大写表示

建立连接对象

String url="jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password";

Connection con = DriverManager.getConnection(url);

建立SQL陈述式对象(Statement Object)

Statement stmt = con.createStatement();

执行SQL语句

executeQuery()

String query = "select * from test";

ResultSet rs=stmt.executeQuery(query);

结果集ResultSet

while(rs.next())

{rs.getString(1);rs.getInt(2);}

executeUpdate()

String upd="insert into test (id,name) values(1001,xuzhaori)";

int con=stmt.executeUpdate(upd);

execute()

示例:

try{
}

catch(SQLException sqle)

{

}

finally

{

}

Java类型和SQL类型 技术手册P421

PreparedStatement(预编语句)

PreparedStatement stmt = conn.prepareStatement("insert into test(id,name)values(?,?)");

stmt.setInt(1,id);

stmt.setString(2,name);

注:一旦设定语句的参数值后,就可以多次执行改语句,直到调用clearParameters()方法将他清除为止

CallableStatement(预储程序)技术手册P430

JDBC2.0使用

ResultSet对象中的光标上下自由移动

Statement stmt = con.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);

ResultSet rs=stmt.executeQuery("select * from test");

public Statement createStatement(int resultSetType,int resultSetConcuttency) throws SQLException

resultSetType

TYPE_FORWARD_ONLY            只能使用next()方法。

TYPE_SCROLL_SENSITIVE        可以上下移动,可以取得改变后的值。

TYPE_SCROLL_INSENSITIVE      可以上下移动。

resultSetConcuttency

CONCUR_READ_ONLY        只读

CONCUR_UPDATABLE        ResultSet对象可以执行数据库的新增、修改、和移除

直接使用ResultSet对象执行更新数据

新增数据

  1. Statement stmtcon.createStatementResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLE);
  2.  
  3. ResultSet uprs=stmt.executeQuery("select * from test");
  4.  
  5. uprs.moveToInsertRow();
  6.  
  7. uprs.updateInt(1,1001);
  8.  
  9. uprs.updateString(2,"许召日");
  10.  
  11. uprs.insertRow;

更新数据

  1. Statement stmtcon.createStatementResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLE);
  2.  
  3. ResultSet uprs=stmt.executeQuery("select * from test");
  4.  
  5. uprs.last();
  6.  
  7. uprs.updateString("name","xuzhaori");
  8.  
  9. uprs.updateRow;

删除数据

  1. Statement stmtcon.createStatementResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLE);
  2.  
  3. ResultSet uprs=stmt.executeQuery("select * from test");
  4.  
  5. uprs.absolute(4);
  6.  
  7. uprs.deleteRow();

批处理

con.setAutoCommit(false);  关闭自动认可模式

Statement stmt=con.createStatement();

int[] rows;

stmt.addBatch("insert into test values(1001,xuzhaori)");

stmt.addBatch("insert into test values(1002,xuyalin)");

rows=stmt.executeBatch();

con.commit();  没有任何错误,执行批处理stmt.executeBatch();

JNDI-数据源(Data Source)与连接池(Connection Pool)

Tomcat的JDBC数据源设置  技术手册P439

连接池工具-Proxool Var 0.8.3 技术手册P446

设置web.xml

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2.  
  3. <!--<?xml version="1.0" encoding="GB2312"?>-->
  4.  
  5. <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  6.  
  7. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  8.  
  9. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  10.  
  11. version="2.4">
  12.  
  13. ….
  14.  
  15. <servlet>
  16.  
  17. <servlet-name>ServletConfigurator</servlet-name>
  18.  
  19. <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
  20.  
  21. <init-param>
  22.  
  23. <param-name>propertyFile</param-name>
  24.  
  25. <param-value>WEB-INF/classes/Proxool.properties</param-value>
  26.  
  27. </init-param>
  28.  
  29. <load-on-startup>1</load-on-startup>
  30.  
  31. </servlet>

后端统计端口添加下列

  1. <servlet>
  2.  
  3. <servlet-name>Admin</servlet-name>
  4.  
  5. <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
  6.  
  7. </servlet>
  8.  
  9. <servlet-mapping>
  10.  
  11. <servlet-name>Admin</servlet-name>
  12.  
  13. <url-pattern>/Admin</url-pattern>
  14.  
  15. </servlet-mapping>
  16.  
  17. ….
  18.  
  19. </web-app>

配置Proxool.properties

  1. jdbc-0.proxool.alias=JSPBook
  2.  
  3. jdbc-0.proxool.driver-class=com.mysql.jdbc.Driver
  4.  
  5. jdbc-0.proxool.driver-url=jdbc:mysql://localhost:3306/sample_db?user=root&password=browser&useUnicode=true&characterEncoding=UTF-8
  6.  
  7. jdbc-0.proxool.maximum-connection-count=10
  8.  
  9. jdbc-0.proxool.prototype-count=4
  10.  
  11. jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE
  12.  
  13. jdbc-0.proxool.verbose=true
  14.  
  15. jdbc-0.proxool.statistics=10s,1m,1d 后端统计接口添加此行
  16.  
  17. jdbc-0.proxool.statistics-log-level=DEBUG

使用Proxool连接池

  1. Connection con = DriverManager.getConnection("proxool.JSPBook");
  2.  
  3. Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
  4.  
  5. String query = "SELECT * FROM employee";
  6.  
  7. ResultSet rs = stmt.executeQuery(query);

使用JDBC时,我们都会很自然得使用下列语句:

  1. Class.forName("com.mysql.jdbc.Driver");
  2. String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";
  3. String user = "";
  4. String psw = "";
  5. Connection con = DriverManager.getConnection(url,user,psw);
 

为什么说很自然呢,因为无论是网上还是书本教程上得例子都是这样的,而且程序也确实正常运行了,于是大家也就心安理得的找葫芦画瓢下去了。

一定要有这一句吗?不是的,我们完全可以用这样一句代替它:

 
  1. com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
  2. //or:
  3. //new com.mysql.jdbc.Driver();
  4. String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";
  5. String user = "";
  6. String psw = "";
  7. Connection con = DriverManager.getConnection(url,user,psw);

大家可能都看出个大概来了,我们只需要在调用DriverManager的getConnection方法之前,保证相应的Driver类已经被加载到jvm中,并且完成了类的初始化工作就行了,而具体是怎样实现这个功能却是没有讲究的。

谈到类的初始化,这里不得不提,在什么样的情况下类才能够初始化?

  1. 创建类的实例
  2. 访问某个类或接口的静态变量,或者对该静态变量赋值
  3. 调用类的静态方法
  4. 反射(如Class.forName("com.lang.String")
  5. 初始化一个类的子类
  6. Java虚拟机启动时被标为启动类的类

上面两种方法都可以实现这个功能,因此程序可以正常运行。注意了,如果我们进行如下操作,程序是不能正常运行的,因为这样仅仅使Driver类被装载到jvm中,却没有进行相应的初始化工作。具体关于类的加载和初始化详细,可以阅读我的这篇博文《JVM虚拟机和类加载器》

  1. com.mysql.jdbc.Driver driver = null;
  2. //or:
  3. ClassLoader cl = new ClassLoader();
  4. cl.loadClass("com.mysql.jdbc.Driver");
 

我们都知道JDBC是使用Bridge模式进行设计的,DriverManager就是其中的Abstraction,java.sql.Driver是Implementor,com.mysql.jdbc.Driver是Implementor的一个具体实现(请参考GOF的Bridge模式的描述)。大家注意了,前一个Driver是一个接口,后者却是一个类,它实现了前面的Driver接口。

Bridge模式中,Abstraction(DriverManager)是要拥有一个Implementor(Driver)的引用的,但是我们在使用过程中,并没有将Driver对象注册到DriverManager中去啊,这是怎么回事呢?jdk文档对Driver的描述中有这么一句:

When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager

哦,原来是com.mysql.jdbc.Driver在装载完后自动帮我们完成了这一步骤。源代码是这样的:

 

可以看到DriveManager里面定义了静态方法,而mysql等驱动类都是内部用静态数据块的方式来初始化,完成Driver对象注册到DriverManager中,所以只要jvm装载了这些驱动类就会将Driver对象注册到DriverManager中去(Class.forName(xxx.xx.xx) 返回的是一个类;Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段 。静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了。而且以后不会再走这段静态代码了。),后面就可以直接使用了。

JDBC详解(转)的更多相关文章

  1. Spring4 JDBC详解

    Spring4 JDBC详解 在之前的Spring4 IOC详解 的文章中,并没有介绍使用外部属性的知识点.现在利用配置c3p0连接池的契机来一起学习.本章内容主要有两个部分:配置c3p0(重点)和 ...

  2. JDBC详解系列(二)之加载驱动

    ---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)---   在JDBC详解系列(一)之流程中 ...

  3. JDBC详解系列(三)之建立连接(DriverManager.getConnection)

      在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加载Driver类,注册数据库驱动: 第二步:通过DriverManager,使用url,用户名和密码 ...

  4. JDBC详解(一)

    一.相关概念介绍 1.1.数据库驱动 这里驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道理 ...

  5. Java基础-面向接口编程-JDBC详解

    Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...

  6. JDBC详解1

    JDBC详解1 JDBC整体思维导图 JDBC入门 导jar包:驱动! 加载驱动类:Class.forName("类名"); 给出url.username.password,其中u ...

  7. JDBC详解系列(一)之流程

    ---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- JDBC概述   使用JDBC也挺长 ...

  8. jdbc详解(一)

    JDBC简介 l 数据库驱动 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC l JDBC 全称为: Java Data Base Connectivity ...

  9. JDBC 详解

    工作原理流程:装载驱动程序---->获得数据库连接---->使用Statement或PreparedStatement执行SQL语句----> 返回执行的结果---->关闭相关 ...

  10. JDBC 详解(转载)

    原文链接:http://blog.csdn.net/cai_xingyun/article/details/41482835 什么是JDBC? Java语言访问数据库的一种规范,是一套API JDBC ...

随机推荐

  1. jsp实验一

    1.熟悉MyEclipse开发环境,熟悉菜单,修改代码的字体和显示行号. 2.动手做第一个输出hello World的实例. 3.定义一个jsp页面,在其中定义个变量,该变量随机产生,数据范围是[0- ...

  2. Java通过sessionId获取Session

    Servlet2.1之后不支持SessionContext里面getSession(String id)方法. 但是,我们可以通过HttpSessionListener监听器和全局静态map自己实现一 ...

  3. 【转】android中ListView的定位:使用setSelectionFromTop实现ListView的position的保持

    如果一个ListView太长,有时我们希望ListView在从其他界面返回的时候能够恢复上次查看的位置,这就涉及到ListView的定位问题: 解决的办法如下: 1 2 3 4 5 6 7 // 保存 ...

  4. angular $http 与form表单的select

    产品线 产品 版本 代码是联动关系 ng-model 绑定数据 设置默认值 ng-options 填充option ng-change 选项变化时的操作截图如下: html <!DOCTYPE ...

  5. MediaElement.js对不同浏览器的支持

    目前已经有很多html5播放器可以使用,使用html5播放器可以轻松的在页面中插入媒体视频,从而使我们的web页面变得更加丰富多彩,所以今天向大家推荐一款非常优秀的html5播放器MediaEleme ...

  6. Android笔记:HTTP相关

    发送HTTP请求 HttpURLConnection.HttpClient XML解析 Pull 解析.SAX 解析.DOM 解析 解析JSON 格式数据 官方提供的JSONObject.谷歌的开源库 ...

  7. iOS之tabBar随tableView的滑动而隐藏/显现

    ` @property(nonatomic,assign)CGFloat historyY; #pragma mark Delegate //设置滑动的判定范围 - (void)scrollViewW ...

  8. TFS二次开发系列:一、TFS体系结构和概念

    TFS是Team Fundation Server的简称,是微软VSTS的一部分,它是Microsoft应用程序生命周期管理(ALM)工具的核心协作平台,简单的说它是管理和开发软件项目的整个生命周期的 ...

  9. MyBatis学习(三)

    输入和输出映射 resultType 指定输出结果的类型(pojo.简单类型.hashmap等),将sql查询结果映射为java对象 . 注意:sql查询的列名要和resultType指定pojo的属 ...

  10. 算法系列:FFT 001

    转载自http://blog.csdn.net/orbit/article/details/17210461 2012年9月的时候,一个南京的大学生从电视台播放的一段记者采访360总裁周鸿祎的视频中破 ...