• JDBCTemplate


    JDBC 

    JDBC(Java DataBase Connectivity)是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用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("
    ");
    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主要接口:

    • 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。支持三种实现类型:

    1. 基本实现:产生一个标准连接对象
    2. 连接池实现:将连接对象池化处理,由一个连接池管理中间件支持
    3. 分布式事务实现:支持分布式事务,通常也是池化的,由一个事务管理中间件支持。

    基于DataSource产生了两个非常常用的数据库连接池框架:DBCP和C3P0,解决了数据库连接的复用问题,极大地提高了数据库连接的使用性能。

    看一个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 依赖

    <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 即可

     
     
    方法1、
    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>

    方法2、

    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配置:

    <bean id="pushDeviceDao" class="com.example.demo.pushDeviceDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
     
    方法3、
    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主要提供下列方法:

      1、execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;

      2、update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;

      3、query方法及queryForXXX方法:用于执行查询相关语句;

      4、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());    // 查询对象集合
    
    

     
     
     
     
  • 相关阅读:
    面向对象串讲
    昨日回顾
    socketserver模块
    今日总结
    在centos6.5-64bit上安装wxHexEditor,以查看编译二进制文件
    spring security 关于 http.sessionManagement().maximumSessions(1);的探究
    spring boot + spring security +前后端分离【跨域】配置 + ajax的json传输数据
    window10 查看端口列表
    spring boot 解决 跨域 的两种方法 -- 前后端分离
    spring security 动态 修改当前登录用户的 权限
  • 原文地址:https://www.cnblogs.com/chenny7/p/11232803.html
Copyright © 2020-2023  润新知