`

JDBC 基础

阅读更多

ADO.NET在Java中的对应技术是JDBC,企业库DataAccessApplicationBlock模块在Java中的对应是spring-jdbc模块,EntityFramework在Java中对应的ORM是Hibernate。关系数据库、SQL、数据库事务、分布式事务的概念都是通用的。

1.JDBC

JDBC代码和ADO.NET代码一样,除了学习时写demo来掌握核心对象外,不适合在项目中直接使用。另外Java中万年不变的学术派抽象接口给我目前看到的大多数容器和框架带来了极大的不便,如Tomcat和Spring中定义的一些抽象类型无论是属性和方法都和.NET中的很相似,但又不得不和Java中的基础接口适配。抽象不能像Java中一样只关注操作接口而不关注基础的数据结构,正确的类型的抽象比方法的抽象更重要,但Java中抽象的做法好像还有一个原则就是与众不同,而不只是关注操作。

(1)核心对象

ADO.NET中的4个核心抽象类是DbConnectionDbCommandDbParameterDbTransaction.DataAdapter和DataSet构建在核心对象之上。

JDBC的4个核心接口DataSourceConnectionStatementResultSetPreparedStatement是Statement的子类型。

虽然两者不能完全匹配,对数据库操作的核心操作是一致的,都是打开链接、发送命令和关闭连接的过程。

(2)参数处理

 参数的核心是索引和参数值。ADO.NET中提供了DbDataParameter类型用于参数的抽象。JDBC中没有提供参数的抽象类型,而是通过PreparedStatement定义的方法来设置参数,可以通过Connection对象获取该类型对象。

(3)事务处理

事务的核心操作是提交和回滚。ADO.NET中提供了DbTransaction类型用于事务的抽象,可以通过DbConnection的BeginTransaction方法开启显式事务.JDBC中没有提供事务的抽象类型,而是通过Connection定义的setAutoCommitcommitrollback方法来操作事务。隐性事务的自动提交和显性事务的手动控制方面两者是一致的。

(4)数据源

JDBC中的Connection不具备连接池等高级功能。DataSource定义了数据源接口,用于连接管理、连接池和分布式事务等高级功能,连接池的重要性不用强调了。我们可以使用Apache Commons DBCP 2或C3P0(Hibernate)等第三方DataSource实现,Spring框架也有内置的一些简单的DataSource实现,如SimpleDriverDataSource、SingleConnectionDataSource、DriverManagerDataSource等。

我们分别使用DriverManager、commons-dbcp2(参考1)、c3p0(参考2)和h2database(参考3)演示无连接池、dbcp2连接池、c3p0连接池的使用:

package test.jdbc;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class Jdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException, PropertyVetoException {
        String ddl = "create table user(id integer not null primary key,username varchar(64))";
        String dml = "insert into user (id,username) values(1,'tom')";
        String query = "select id,username from user where username=?";
        String className = "org.h2.Driver";
        String url = "jdbc:h2:mem:test";
        // Connection conn = DriverManager.getConnection(url);
        Connection conn = get_dbcp2_dataSource(className, url).getConnection();
        // Connection conn = get_c3p0_dataSource(className,//
        // url).getConnection();
        conn.setAutoCommit(false);
        conn.prepareStatement(ddl).execute();
        conn.createStatement().execute(dml);
        conn.commit();
        conn.setAutoCommit(true);
        PreparedStatement statement = conn.prepareStatement(query);
        statement.setString(1, "tom");
        ResultSet rs = statement.executeQuery();
        User user = new User();
        while (rs.next()) {
            user.setId(rs.getInt(1));
            user.setUsername("username");
            break;
        }
        conn.close();
        System.out.println(String.format("id:%d,username:%s", user.getId(), user.getUsername()));
    }

    public static Connection getConnection(String driverClassName, String url) {
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        }
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static DataSource get_dbcp2_dataSource(String clssName, String url) {

        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(clssName);
        dataSource.setUrl(url);
        return dataSource;
    }

    public static DataSource get_c3p0_dataSource(String clssName, String url) throws PropertyVetoException {

        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(clssName);
        dataSource.setJdbcUrl(url);
        return dataSource;
    }
}

 其中2dbcp、c3p0和h2database的Maven依赖如下:

<dependency>
     <groupId>com.h2database</groupId>
     <artifactId>h2</artifactId>
     <version>1.4.190</version>
</dependency>
<dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-dbcp2</artifactId>
     <version>2.1.1</version>
</dependency>
<dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
</dependency>

 

2.Spring Jdbc

JDBC和ADO.NET的API类似,都不适合我们直接使用,如果不适用ORM框架,在.NET中我们使用DataAccessApplicationBlock,在Java中我们可以使用Spring JDBC。Spring JDBC的核心类是JdbcTemplate

(1)Sprnig的委托实现

要使用Spring Jdbc的功能,首先要理解Spring中委托的使用方式,Spring定义一个包含该委托签名的接口(这些接口通常都是没有内置实现的),当需要委托参数时,使用该接口作为参数类型,利用Java中的匿名类功能,可以在内联代码中实现接口定义的委托,下面列举几个常见的委托接口:

Func<Connection,PreparedStatement>:PreparedStatement接口的createPreparedStatement方法。

public interface PreparedStatementCreator {
 
     PreparedStatement createPreparedStatement(Connection con) throws SQLException;
 
 }

 Func<PreparedStatement,T>:PreparedStatementCallback泛型接口的doInPreparedStatement方法。

 public interface PreparedStatementCallback<T> {

    T doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException;
 
 }

 Func<TransactionStatus,T>:TransactionCallback泛型接口的T doInTransaction(TransactionStatus status)方法。

 public interface TransactionCallback<T> {
 
     T doInTransaction(TransactionStatus status);
 
}

 Fcun<ResultSet,T>:ResultSetExtractor泛型方法的T extractData(ResultSet rs)方法。

 public interface ResultSetExtractor<T> {
 
     T extractData(ResultSet rs) throws SQLException, DataAccessException;
 
 }

 

(1)JdbcTemplate

 JdbcTemplate需要配合DataSource一起使用。JdbcTemplate的代码中很多都是通过IDE自动生成匿名类导致的,真正手写的代码量并不多。

public static void main(String[] args) throws ClassNotFoundException, SQLException, PropertyVetoException {
        String ddl = "create table user(id integer not null primary key,username varchar(64))";
        String dml = "insert into user (id,username) values(1,'tom')";
        String query = "select id,username from user where username=?";
        String className = "org.h2.Driver";
        String url = "jdbc:h2:mem:test";

        DataSource dataSource = get_dbcp2_dataSource(className, url);
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        PlatformTransactionManager tm = new DataSourceTransactionManager(dataSource);
        TransactionTemplate tt = new TransactionTemplate(tm);
        tt.execute(new TransactionCallback() {

            @Override
            public Object doInTransaction(TransactionStatus status) {
                jdbcTemplate.execute(ddl);
                jdbcTemplate.execute(dml);
                return status;
            }
        });

        User user = jdbcTemplate.query(query, new Object[] { "tom" }, new ResultSetExtractor<User>() {
            @Override
            public User extractData(ResultSet rs) throws SQLException, DataAccessException {
                User user = new User();
                while (rs.next()) {
                    user.setId(rs.getInt(1));
                    user.setUsername(rs.getString("username"));
                    break;
                }
                return user;
            }
        });
        System.out.println(String.format("id:%d,username:%s", user.getId(), user.getUsername()));
    }

 

(3)TransactionTemplate

在上面的代码中出现了TransactionTemplate用于事务处理,TransactionTemplate依赖PlatformTransactionManager,Spring Jdbc中定义的DataSourceTransactionManager实现类用于处理数据库事务。在Spring的orm、jsm、tx等模块中还有其他的实现。

(4)JdbcDaoSupport

JdbcDaoSupport是一个在内部使用JdbcTemplate字段并且实现了DaoSupport接口的抽象类,可供我们自定义DAO类时参考或用作基类。

class MyDao extends JdbcDaoSupport {
    public MyDao(DataSource dataSource) {
        this.setJdbcTemplate(new JdbcTemplate(dataSource));
    }

    @SuppressWarnings("unchecked")
    public void init(String ddl, String dml) {
        PlatformTransactionManager tm = new DataSourceTransactionManager(this.getDataSource());
        TransactionTemplate tt = new TransactionTemplate(tm);

        tt.execute(new TransactionCallback() {

            @Override
            public Object doInTransaction(TransactionStatus status) {
                getJdbcTemplate().execute(ddl);
                getJdbcTemplate().execute(dml);
                return status;
            }
        });
    }

    public User getUser(String query, String username) {
        return this.getJdbcTemplate().query(query, new Object[] { username }, new ResultSetExtractor<User>() {
            @Override
            public User extractData(ResultSet rs) throws SQLException, DataAccessException {
                User user = new User();
                while (rs.next()) {
                    user.setId(rs.getInt(1));
                    user.setUsername(rs.getString("username"));
                    break;
                }
                return user;
            }
        });
    }
}

 

分享到:
评论

相关推荐

    JDBC基础JDBC基础

    JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础

    jdbc基础的详解与总结

    "jdbc 基础的详解与总结" jdbc 是一套协议,由 Sun 公司定义的一组接口,由数据库厂商来实现,并规定了 Java 开发人员访问数据库所使用的方法的调用规范。jdbc 的实现是由数据库厂商提供,以驱动程序形式提供。jdbc...

    JDBC 基础实例(非常适合初学者)

    **JDBC基础实例详解** Java Database Connectivity (JDBC) 是Java平台中用于与关系数据库进行交互的一种标准接口。它是Java编程语言的一部分,允许应用程序通过Java代码执行SQL语句,实现数据的增删改查操作。对于...

    JDBC基础知识

    **JDBC基础知识** Java Database Connectivity (JDBC)是Java编程语言中用于标准地访问数据库的API。它由一组Java类和接口组成,允许Java应用程序连接到各种类型的数据库系统,包括Oracle、MySQL、SQL Server等。...

    JDBC基础.chm JDBC基础.chm

    JDBC基础.chmJDBC基础.chm

    JDBC基础.ppt

    **JDBC基础学习目标:** 1. **理解Java中的数据库连接**:了解Java如何通过JDBC API与各种类型的数据库(如关系型、面向对象关系型和面向对象数据库)建立连接。 2. **掌握JDBC API**:熟悉java.sql包中的核心类和...

    JDBC基础(入门级的)

    **JDBC基础知识详解** Java Database Connectivity (JDBC) 是Java平台上的一个标准API,用于与关系型数据库进行交互。它是Java开发者访问数据库的唯一、统一的接口,由Sun Microsystems(现已被Oracle收购)定义,...

    【Java学习笔记】JDBC基础篇

    jdbc基础篇教程md版:这份markdown格式的教程详细介绍了jdbc的基础概念、配置方法以及如何通过jdbc进行数据库的增删改查(crud)操作。教程内容涵盖了jdbc驱动的加载、数据库连接的建立、sql语句的执行以及结果集的...

    JDBC 基础知识 .ppt

    了解JDBC的概念及必要性 了解JDBC驱动程序类型 理解JDBC 程序的结构 运用JDBC进行数据库编程

    jdbc基础知识总结

    ### JDBC基础知识总结 #### 一、概述 JDBC(Java Database Connectivity)是一种标准的Java API,用于连接并操作各种类型的数据库。它从物理结构上说就是一套Java语言访问数据库的接口集合,本质上则是调用者...

    JDBC基础教程之连接.doc

    ### JDBC基础教程之连接知识点详解 #### 一、Connection对象及其作用 - **Connection对象**:在JDBC中,`Connection`对象代表了一个与数据库之间的连接。通过这个连接,应用程序可以执行SQL语句并获取结果集。 - *...

    JDBC 基础入门

    **JDBC基础入门详解** Java Database Connectivity(JDBC)是Java平台中用于与数据库交互的一组接口和类,它是Java标准API的一部分,使得Java开发者能够访问各种类型的数据库系统。本篇将详细介绍JDBC的基础知识,...

    JDBC基础教程之概述.txt

    ### JDBC基础教程之概述 #### 一、JDBC简介与概念理解 JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC的...

    JAVAJDBC基础.pdf

    【JDBC基础】 JDBC(Java Database Connectivity)是Java编程语言中用于访问数据库的标准Java API,它允许Java开发者在程序中执行SQL语句并与各种数据库进行交互。JDBC为Java程序员提供了一种统一的方式来连接和操作...

    JDBC基础.doc

    在学习JDBC基础时,主要涉及以下几个关键知识点: 1. **快速入门**: - 安装Java和JDBC:确保你拥有与JDBC兼容的JDK版本,通常JDBC会随JDK一起安装。 - 安装驱动程序:根据选择的数据库,安装相应的JDBC驱动,如...

    Java操作数据库JDBC基础demo

    Java操作数据库JDBC基础demo是Java开发者必备的技能之一,JDBC(Java Database Connectivity)是Java语言连接数据库的标准API,它允许Java程序与各种不同类型的数据库进行交互。在这个基础demo中,我们将涵盖JDBC的...

    jdbc基础------jdbc

    **JDBC基础——深入理解与实践** Java Database Connectivity(JDBC)是Java平台中用于与关系型数据库交互的标准API,它允许Java程序通过编写Java代码来执行SQL语句,进行数据查询、插入、更新和删除等操作。了解并...

    JDBC基础培训课件ppt

    **JDBC基础培训课件** Java Database Connectivity (JDBC) 是Java编程语言中用于与数据库交互的一组接口和类。它是Java平台的标准部分,由Java SE的Java Database Connectivity API提供,使得开发者能够编写数据库...

Global site tag (gtag.js) - Google Analytics