Java Web Series: JDBC Basics



Original source: Wang Gang

The corresponding technology of ADO.NET in Java is JDBC, the corresponding technology of Enterprise Library DataAccessApplicationBlock module in Java is spring-jdbc module, and the corresponding ORM of EntityFramework in Java is Hibernate. The concepts of relational databases, SQL, database transactions, distributed transactions are all generic.

1.JDBC

JDBC code, like ADO.NET code, is not suitable for direct use in projects, except for writing demos to master core objects during learning. In addition, the academic abstract interface that remains unchanged for thousands of years in Java has brought great inconvenience to most of the containers and frameworks I have seen so far. For example, some abstract types defined in Tomcat and Spring are incompatible with .NET in terms of attributes and methods. It is very similar to the one in Java, but it has to be adapted to the basic interface in Java. Abstraction cannot focus only on operating interfaces and not on the underlying data structure like in Java. The abstraction of the correct type is more important than the abstraction of methods, but there seems to be another principle of abstraction in Java, which is to be different, not just focus on operate.

(1) Core objects

The four core abstract classes in ADO.NET are DbConnection, DbCommand, DbParameter and DbTransaction. DataAdapter and DataSet are built on top of the core objects.

JDBC's four core interfaces DataSource, Connection, Statement and ResultSet. PreparedStatement is a subtype of Statement.

Although the two do not exactly match, the core operations for database operations are the same, which are the process of opening a link, sending a command, and closing a connection.

(2) Parameter processing

The core of a parameter is the index and parameter value. ADO.NET provides the DbDataParameter type for parameter abstraction. There is no abstract type of parameter provided in JDBC, but the parameter is set through the method defined by PreparedStatement, and the object of this type can be obtained through the Connection object.

(3)

Transaction The core operations of a transaction are commit and rollback. ADO.NET provides the DbTransaction type for the abstraction of transactions. You can open an explicit transaction through the BeginTransaction method of DbConnection. JDBC does not provide an abstract type of transaction, but operates transactions through the setAutoCommit, commit and rollback methods defined by Connection. The automatic commit of implicit transactions and the manual control of explicit transactions are the same.

(4) The Connection in the data source

JDBC does not have advanced functions such as connection pooling. DataSource defines a data source interface for advanced functions such as connection management, connection pooling, and distributed transactions. The importance of connection pooling cannot be stressed. We can use third-party DataSource implementations such as Apache Commons DBCP 2 or C3P0 (Hibernate), and the Spring framework also has some built-in simple DataSource implementations, such as SimpleDriverDataSource, SingleConnectionDataSource, DriverManagerDataSource, etc.

We use DriverManager, commons-dbcp2 (reference 1), c3p0 (reference 2) and h2database (reference 3) to demonstrate the use of connectionless pools, dbcp2 connection pools, and c3p0 connection pools:




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

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依赖如下:




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


























To use the functions of Spring Jdbc, you must first understand how the delegate is used in Spring. Spring defines an interface that contains the delegate signature (these interfaces usually do not have built-in implementations). When delegate parameters are required, use this interface as the parameter type. , Using the anonymous class function in Java, the delegate of the interface definition can be implemented in the inline code. Here are several common delegate interfaces:

Func<Connection, PreparedStatement>: The createPreparedStatement method of the PreparedStatement interface.




1
2
3
4
5

public interface PreparedStatementCreator {

    PreparedStatement createPreparedStatement(Connection con) throws SQLException;

}


Func<PreparedStatement,T>: The doInPreparedStatement method of the PreparedStatementCallback generic interface.




1
2
3
4
5

public interface PreparedStatementCallback<T> {

    T doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException;

}


Func<TransactionStatus, T>: T doInTransaction(TransactionStatus status) method of the TransactionCallback generic interface.




1
2
3
4
5

public interface TransactionCallback<T> {

    T doInTransaction(TransactionStatus status);

}


Fcu<ResultSet,T>: T extractData(ResultSet rs) method of ResultSetExtractor generic method.




1
2
3
4
5

public interface ResultSetExtractor<T> {

    T extractData(ResultSet rs) throws SQLException, DataAccessException;

}


(1) JdbcTemplate

JdbcTemplate needs to be used with DataSource. Much of the code of JdbcTemplate is caused by the automatic generation of anonymous classes by the IDE, and the amount of real handwritten code is not much.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

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

In the above code, TransactionTemplate appears for transaction processing, TransactionTemplate relies on PlatformTransactionManager, and the DataSourceTransactionManager implementation class defined in Spring Jdbc is used to process database transactions. There are other implementations in Spring's orm, jsm, tx and other modules.

(4) JdbcDaoSupport

JdbcDaoSupport is an abstract class that uses the JdbcTemplate field internally and implements the DaoSupport interface, which can be used as a reference or as a base class when we customize the DAO class.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

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



参考

(1)http://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi

(2)http://sourceforge.net/projects/c3p0/

(3)http://www.h2database.com/html/cheatSheet.html

(4)http://commons.apache.org/proper/commons-dbcp/guide/jndi-howto.html
   


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326865454&siteId=291194637