JDBC基础教程

  通过本教程学习JDBC基础知识以及事务机制和死锁,包括在Spring与Hibernate/JPA中的使用,主要是通过可运行的代码展示这些知识,你可以将代码复制到IDE中自行调试,通过动手实践学习JDBC。

设置

  学习JDBC之前,我们假设你已经会通过IDE开发一般普通的Java应用项目,掌握Maven进行项目管理的实战知识,现在我们需要准备Maven的pom.xml设置一下教程代码的环境:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <version>1.4.187</version>
</dependency>

很显然,我们需要依赖单元测试junit和H2内存数据库作为我们学习的环境。

连接到数据库

  我们在Java 7以上版本中,打开数据库连接以后就无需再手工释放,因为会自动被释放,这称为try-with-resources。

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
* @author Marco Behler
*/
public class OpenConnectionExerciseJava7 {

    private static final Integer NO_TIMEOUT = 0;

    @Test
    public void open_jdbc_connection_java_7() {
        // the closing of the connection is done automatically
        try (Connection conn = DriverManager.getConnection(
                "jdbc:h2:mem:exercise_db;DB_CLOSE_DELAY=-1")) {
            //这里我们打开的是h2数据库,不需要用户密码,如果是mysql,需要修改。

                System.out.println("Are we connected to the database? : "
                        + conn.isValid(NO_TIMEOUT));

                // 创建一个数据表
                conn.createStatement().execute("create table bids " +
                        "(id identity, user VARCHAR, time TIMESTAMP , " +
                        "amount NUMBER, currency VARCHAR) ");

                conn.createStatement().execute("create table items " +
                           "(id identity, name VARCHAR)");

                System.out.println("Yay, tables created!");

        } catch (SQLException e) {
                e.printStackTrace();
        }

        //我们不需要使用finally手工关闭打开的资源:数据库连接。如果不关闭数据库连接会造成连接耗尽。


}

}

 

  以上是打开一个数据库连接的代码,实践中我们会通过数据库连接池来打开一个数据库连接,而不是类似上面这样直接打开,因为数据库服务器一般会和我们Java服务器不在同一台机器上,之间通过网络连接,那么每次使用上面代码打开一个数据库连接,会新建一个网络连接等等,非常耗时缓慢,而数据库连接池是在Java服务器启动之时,已经建立好一定数量的数据库连接,形成一个池,我们应用使用时,只要向这个池借用一个连接即可,用完以后再还回去。

  数据库连接池由特定的Jar库包,Tomcat的服务器本身带有这样的连接池包,我们通过JNDI访问即可,Spring也提供连接池,我们可以直接使用Spring配置注释来使用其连接池。

 

JDBC DATASOURCE

  Datasource是一个接口,不同的数据库有不同的实现,通过使用JDBC数据源可以访问JNDI、连接池 、分布式事务等等。也就是说,如果我们使用数据库连接池,就需要通过Datasource进行访问。

import org.h2.jdbcx.JdbcDataSource;
import org.junit.Test;

import javax.sql.DataSource;
import java.sql.Connection;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* @author Marco Behler <marco@marcobehler.com>
*/
public class DataSourceExercise {

    private static final Integer NO_TIMEOUT = 0;

    @Test
    public void exercise() {
        DataSource ds = getDataSource();
        try (Connection connection = ds.getConnection()) {
            System.out.println("Yay, we got our connection to the " +
            "database through a datasource!");
            assertTrue(connection.isValid(NO_TIMEOUT));
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }

    // datasource is an interface and can have many different
    // implementations
    // one of the h2 implementation is the JdbcDataSource (which offers
    // no pooling or distributed transactions)
    private DataSource getDataSource() {
        JdbcDataSource ds = new JdbcDataSource();
        ds.setURL("jdbc:h2:mem:exercise_db;DB_CLOSE_DELAY=-1");
        ds.setUser("sa");
        ds.setPassword("sa");
        /* 下面是注册一个JNDI 服务,现在可以忽视
        Context ctx = new InitialContext();
        ctx.bind("jdbc/datasource", ds);*/
        return ds;
    }

}

 

DataSource — 这是JDBC 2.0引入的,优先于DriverManager,因为它能将底层数据源更多信息透明开放给应用程序。

对于driver manager,你需要知道所有数据库细节(主机host, 端口port, 用户名username, 密码password, 驱动类类型)。而使用Datasource你仅仅需要知道一个JNDI名称即可,Datasource的可扩展性要更强。

下面我们将了解数据库事务和锁的情况:

JDBC事务锁基础教程

JDBC悲观锁与乐观锁基础教程

JDBC隔离级别基础教程

 

更多参考:

SQL入门教程

数据库事务专题

Hibernate专题