码迷,mamicode.com
首页 > 数据库 > 详细

JDBC 入门 - 建立连接

时间:2015-01-24 15:44:25      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:

JDBC 入门 - 建立连接

建立连接

在于数据库交互的时候, 第一件事是和数据源(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 新建一个连接, 并往数据库中插入一条数据:

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为例:

  1. 首先要在 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>

     

  2. 其次要在 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"/>

     

  3. 在程序中, 我们就可以这样获取连接了:

     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;
     }

     

JDBC 入门 - 建立连接

标签:

原文地址:http://www.cnblogs.com/pragmatic/p/4245920.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!