JDBCTemplate

 

 

JDBC 

JDBC(Java DataBase Connectivity)是Java和數據庫之間的一個橋樑,是一個規範而不是一個實現,可以執行SQL語句。它由一組用Java語言編寫的類和接口組成。各類不一樣類型的數據庫都有相應的實現。java

 

JDBC規範採用接口和實現分離的思想設計了Java數據庫編程的框架。接口包含在java.sql及 javax.sql包中,其中java.sql屬於JavaSE,javax.sql屬於JavaEE。

爲了使客戶端程序獨立於特定的數據庫驅動程序,JDBC規範建議開發者使用基於接口的編程方式,即儘可能使應用僅依賴java.sql及javax.sql中的接口和類。

 

一個例子:

 1 Connection conn = null;
 2         Statement stmt = null;
 3         try {
 4             // 註冊 JDBC 驅動
 5             Class.forName("com.mysql.jdbc.Driver");
 6 
 7             // 建立連接
 8             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/push_system_new?characterEncoding=UTF-8", "root", "123456");
 9 
10             // 執行查詢
11             stmt = conn.createStatement();
12             String sql = "SELECT id, app_id, device_token FROM push_device_0";
13             ResultSet rs = stmt.executeQuery(sql);
14 
15             while (rs.next()) {
16                 // 經過字段檢索
17                 long id  = rs.getLong("id");
18                 long appId = rs.getLong("app_id");
19                 String deviceToken = rs.getString("device_token");
20 
21                 // 輸出數據
22                 System.out.print("device_id: " + id);
23                 System.out.print(", appId: " + appId);
24                 System.out.print(", device_token: " + deviceToken);
25                 System.out.print("\n");
26                 break;
27             }
28 
29             // 完成後關閉
30             rs.close();
31             stmt.close();
32             conn.close();
33 
34         } catch(SQLException se) {
35             // 處理 JDBC 錯誤
36             se.printStackTrace();
37 
38         } catch(Exception e) {
39             // 處理 Class.forName 錯誤
40             e.printStackTrace();
41 
42         } finally {
43             // 關閉資源
44             try {
45                 if (stmt != null) stmt.close();
46             } catch(SQLException se2) {
47 
48             }
49 
50             // 什麼都不作
51             try {
52                 if (conn != null) conn.close();
53             } catch(SQLException se) {
54                 se.printStackTrace();
55             }
56         }
View Code

 

JDBC主要接口:mysql

  • Driver接口
  • Connection接口,主要方法:
    • createStatement(),建立向數據庫發送sql的statement對象;
    • prepareStatement(sql),建立向數據庫發送預編譯sql的prepareStatement對象;
    • prepareCall(sql),建立執行存儲過程的callableStatement對象;
    • setAutoCommit(boolean autoCommit)
    • commit()
    • rollback()
  • Statement接口,主要方法:
    • execute(sql),運行sql,返回是否有結果集;
    • executeQuery(sql),運行select操做,返回ResultSet結果集;
    • executeUpdate(sql),運行insert/update/delete操做,返回更新的行數;
    • addBatch(sql),把多條sql語句放到一個批處理中;
    • executeBatch(sql),向數據庫發送一批sql語句執行;
  • ResultSet接口,主要方法:
    • getString(int index)、getString(String columnName),獲取varchar、char類型字段;
    • getFloat(int index)、getFloat(String columnName),獲取float類型字段;
    • getBoolean(int index)、getBoolean(String columnName),獲取bool類型字段;
    • getDate(int index)、getDate(String columnName),獲取Date類型字段;
    • next(),移動到下一行;
    • previous(),移動到上一行;
    • absolute(int row),移動到指定行;
    • beforeFirst(),移動到最前面;
    • afterLast(),移動到最後;

 

Datasource

DataSource表示一種建立Connection的工廠,在jdk 1.4引入,相對DriverManager的方式更優先推薦使用DataSource。支持三種實現類型:spring

  1. 基本實現:產生一個標準鏈接對象
  2. 鏈接池實現:將鏈接對象池化處理,由一個鏈接池管理中間件支持
  3. 分佈式事務實現:支持分佈式事務,一般也是池化的,由一個事務管理中間件支持。

基於DataSource產生了兩個很是經常使用的數據庫鏈接池框架:DBCP和C3P0,解決了數據庫鏈接的複用問題,極大地提升了數據庫鏈接的使用性能。sql

看一個DBCP的簡單用例,bean配置:數據庫

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/push_system_new"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="initialSize" value="5"/>
        <property name="maxActive" value="30"/>
        <property name="maxIdle" value="5"/>
        <property name="minIdle" value="2"/>
</bean>

 

pom.xml 依賴apache

<dependency>
   <groupId>commons-dbcp</groupId>
   <artifactId>commons-dbcp</artifactId>
   <version>1.4</version>
</dependency>

 

 

 

JDBCTemplate

JdbcTemplate是Spring框架自帶的對JDBC操做的封裝,目的是提供統一的模板方法使對數據庫的操做更加方便、友好,效率也不錯。可是功能仍是不夠強大(好比不支持級聯屬性),在實際應用中還須要和hibernate、mybaties等框架混合使用。

要使用JDBCTemplate對象來完成JDBC操做。一般狀況下,有三種種方式獲得JDBCTemplate對象。

  1. 咱們能夠在本身定義的DAO 實現類中注入一個DataSource 引用來完 成JdbcTemplate 的實例化。也就是它是從外部「注入」 DataSource 到DAO 中,而後 本身實例化JdbcTemplate,而後將DataSource 設置到JdbcTemplate 對象中。

  2. 在 Spring 的 IoC 容器中配置一個 JdbcTemplate 的 bean,將 DataSource 注入進來,而後再把JdbcTemplate 注入到自定義DAO 中。

  3. spring 提供了 org.springframework.jdbc.core.support.JdbcDaoSupport 類 , 這 個 類 中 定 義 了 JdbcTemplate 屬性,也定義了DataSource 屬性,當設置DataSource 屬性的時候,會創 建jdbcTemplate 的實例,因此咱們本身編寫的DAO 只須要繼承JdbcDaoSupport 類, 而後注入DataSource 便可

 
 
方法一、
public class pushDeviceDaoImpl {

    private JdbcTemplate jdbcTemplate;

    public List<DeviceInfo> query(long appId) {
        String sql = "select * from push_device_0 where app_id=? ";
        return jdbcTemplate.query(sql, new DeviceRowMapper(), appId);
    }


    @Data
    class DeviceInfo {
        long app_id;
        long id;
        String device_token;
    }

    class DeviceRowMapper implements RowMapper<DeviceInfo> {
        public DeviceInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
            DeviceInfo deviceInfo = new DeviceInfo();
            deviceInfo.setId(rs.getLong("id"));
            deviceInfo.setApp_id(rs.getLong("app_id"));
            deviceInfo.setDevice_token(rs.getString("device_token"));
            return deviceInfo;
        }
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

 

 
xml中的bean配置:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
   <property name = "dataSource" ref="dataSource"/>
</bean>

<bean id="pushDeviceDao" class="com.example.demo.pushDeviceDaoImpl">
   <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

 

 

方法二、編程

public class pushDeviceDaoImpl {

    private JdbcTemplate jdbcTemplate;

    public List<DeviceInfo> query(long appId) {
        String sql = "select * from push_device_0 where app_id=? ";
        return jdbcTemplate.query(sql, new DeviceRowMapper(), appId);
    }

    @Data
    class DeviceInfo {
        long app_id;
        long id;
        String device_token;
    }

    class DeviceRowMapper implements RowMapper<DeviceInfo> {
        public DeviceInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
            DeviceInfo deviceInfo = new DeviceInfo();
            deviceInfo.setId(rs.getLong("id"));
            deviceInfo.setApp_id(rs.getLong("app_id"));
            deviceInfo.setDevice_token(rs.getString("device_token"));
            return deviceInfo;
        }
    }

    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
}

 

xml中的bean配置:app

<bean id="pushDeviceDao" class="com.example.demo.pushDeviceDaoImpl">
    <property name="dataSource" ref="dataSource"/>
</bean>

 

 

 

 
方法三、
public class pushDeviceDaoImpl extends JdbcDaoSupport {
    @Data
    class DeviceInfo {
        long app_id;
        long id;
        String device_token;
    }

    public List<DeviceInfo> query(long appId) {
        String sql = "select * from push_device_0 where app_id=? ";
        return getJdbcTemplate().query(sql, new DeviceRowMapper(), appId);
    }

    public List<DeviceInfo> queryToken(long appId, String deviceToken) {
        String sql = "select * from push_device_23 where app_id=? and device_token=?";


        PreparedStatementSetter pss = new PreparedStatementSetter() {
            public void setValues(PreparedStatement preparedStatement) throws SQLException {
                preparedStatement.setLong(1, appId);
                preparedStatement.setString(2, deviceToken);
            }
        };

        ResultSetExtractor rse = new ResultSetExtractor<List<DeviceInfo>>() {
            public List<DeviceInfo> extractData(ResultSet rs) throws SQLException, DataAccessException {
                List<DeviceInfo> list = new ArrayList<>();
                while (rs.next()) {
                    DeviceInfo deviceInfo = new DeviceInfo();
                    deviceInfo.setId(rs.getLong("id"));
                    deviceInfo.setApp_id(rs.getLong("app_id"));
                    deviceInfo.setDevice_token(rs.getString("device_token"));
                    list.add(deviceInfo);
                }
                return list;
            }
        };

        return (List<DeviceInfo>) getJdbcTemplate().query(sql, pss, rse);
    }


    class DeviceRowMapper implements RowMapper<DeviceInfo> {
        public DeviceInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
            DeviceInfo deviceInfo = new DeviceInfo();
            deviceInfo.setId(rs.getLong("id"));
            deviceInfo.setApp_id(rs.getLong("app_id"));
            deviceInfo.setDevice_token(rs.getString("device_token"));
            return deviceInfo;
        }

    }
}

這裏用到了 ResultSetExtractor 接口,該接口的實現執行從ResultSet提取結果的實際工做,不須要擔憂異常處理,它調用JdbcTemplate捕獲並處理SQLExceptions。 該接口主要用於JDBC框架自己。 RowMapper一般是ResultSet處理的簡單選擇查詢,每行映射一個結果對象,而不是整個ResultSet的一個結果對象。框架

 
 
 

xml中的bean配置:分佈式

<bean id="pushDeviceDao" class="com.example.demo.pushDeviceDaoImpl">
   <property name="dataSource" ref="dataSource"/>
</bean>

 

 

JdbcTemplate主要提供下列方法:

  一、execute方法:能夠用於執行任何SQL語句,通常用於執行DDL語句;

  二、update方法及batchUpdate方法:update方法用於執行新增、修改、刪除等語句;batchUpdate方法用於執行批處理相關語句;

  三、query方法及queryForXXX方法:用於執行查詢相關語句;

  四、call方法:用於執行存儲過程、函數相關語句。

 examples :

getJdbcTemplate().update("insert into user values(?,?,?)", user.getId(), user.getUsername(), user.getPassword());
getJdbcTemplate().update("delete from user where id=?", id);
getJdbcTemplate().update("update user set username=?,password=? where id=?", user.getUsername(), user.getPassword(), user.getId());
getJdbcTemplate().queryForObject("select username from user where id=?", String.class, id);  // 簡單查詢,返回原始數據類型
getJdbcTemplate().queryForInt("select count(*) from user");  // 簡單查詢,返回原始數據類型
getJdbcTemplate().queryForObject("select * from user where id=?", new UserRowMapper(), id);  // 查詢單個對象
getJdbcTemplate().query("select * from user", new UserRowMapper());    // 查詢對象集合
相關文章
相關標籤/搜索