zoukankan      html  css  js  c++  java
  • Spring4 JDBC详解

    Spring4 JDBC详解

    在之前的Spring4 IOC详解 的文章中,并没有介绍使用外部属性的知识点。现在利用配置c3p0连接池的契机来一起学习。本章内容主要有两个部分:配置c3p0(重点)和 使用 Spring JDBC模版。

    准备环境

    导入spring-jdbc的jar包

            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-jdbc</artifactId>  
                <version>4.1.6.RELEASE</version>  
            </dependency>  
    

    创建数据表

    SET FOREIGN_KEY_CHECKS=0;  
    -- ----------------------------  
    -- Table structure for `itdragon`  
    -- ----------------------------  
    DROP TABLE IF EXISTS `itdragon`;  
    CREATE TABLE `itdragon` (  
      `id` int(11) NOT NULL AUTO_INCREMENT,  
      `account` varchar(255) NOT NULL,  
      `password` varchar(255) NOT NULL,  
      PRIMARY KEY (`id`)  
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
    

    配置c3p0

    c3p0的外部属性文件(可以在无需重启系统的情况下修改系统环境变量):db.properties。
    db.properties文件中,user 和 password 分别表示 mysql连接 的账号和密码。driverClass 是加载的驱动。
    jdbcUrl 是连接数据库的路径。格式是 jdbc:mysql://ip:port/数据库名(jdbc:mysql://localhost:3306/spring)
    如果ip地址是本地,port是3306 是可以简写为 jdbc:mysql:///+数据库名。
    initPoolSize 是 池内初始的数据连接个数,maxPoolSize是最大连接个数。和线程池是一样的概念。
    如果你对这个不是很了解,可以先看看jdbc操作mysql数据库

    jdbc.user=root  
    jdbc.password=root  
    jdbc.driverClass=com.mysql.jdbc.Driver  
    jdbc.jdbcUrl=jdbc:mysql:///spring  
      
    jdbc.initPoolSize=5  
    jdbc.maxPoolSize=10  
    

    核心文件applicationContext.xml ,首先要指定导入的资源context:property-placeholder , location从类路径下加载外部属性文件db.properties。
    配置一个c3p0的bean,和普通bean一样。只是赋值采用el表达式${}。再配置两个jdbc的模版bean就可以了。

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xmlns:context="http://www.springframework.org/schema/context"  
        xmlns:tx="http://www.springframework.org/schema/tx"  
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">  
          
        <!-- 导入资源文件 -->  
        <context:property-placeholder location="classpath:db.properties"/>  
          
        <!-- 配置 C3P0 数据源 -->  
        <bean id="dataSource"  
            class="com.mchange.v2.c3p0.ComboPooledDataSource">  
            <property name="user" value="${jdbc.user}"></property>  
            <property name="password" value="${jdbc.password}"></property>  
            <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>  
            <property name="driverClass" value="${jdbc.driverClass}"></property>  
      
            <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>  
            <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>  
        </bean>  
          
        <!-- 配置 Spirng 的 JdbcTemplate -->  
        <bean id="jdbcTemplate"   
            class="org.springframework.jdbc.core.JdbcTemplate">  
            <property name="dataSource" ref="dataSource"></property>  
        </bean>  
          
        <!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数 -->  
        <bean id="namedParameterJdbcTemplate"  
            class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">  
            <constructor-arg ref="dataSource"></constructor-arg>      
        </bean>  
          
    </beans>  
    

    值得注意的是,在配置JdbcTemplate是用属性注入的方式,当然也可以用构造注入。但在配置NamedParameterJdbcTemplate只能通过构造注入的方式。源码如下:

    /*      */   public JdbcTemplate(DataSource dataSource)
    /*      */   {
    /*  166 */     setDataSource(dataSource);
    /*  167 */     afterPropertiesSet();
    /*      */   }
    
    /*     */   public NamedParameterJdbcTemplate(DataSource dataSource)
    /*     */   {
    /*  89 */     Assert.notNull(dataSource, "DataSource must not be null");
    /*  90 */     this.classicJdbcTemplate = new JdbcTemplate(dataSource);
    /*     */   }
    

    Spring JDBC模版

    先温故一下Mysql的基本语法
    新增:INSERT [INTO] 表名 [(列名1, 列名2, 列名3, ...)] VALUES (值1, 值2, 值3, ...);
    修改:UPDATE 表名 SET 列名=新值 WHERE 更新条件;
    删除:DELETE FROM 表名 WHERE 删除条件;
    查询:SELECT 列名称 FROM 表名称 [查询条件];
    操作Mysql的测试方法,JdbcTemplate只是一个 JDBC的小工具。很多功能还不能实现,比如级联操作。真正的数据处理,还是交给Hibernate等ORM框架。

    import java.sql.SQLException;  
    import java.util.ArrayList;  
    import java.util.List;  
    import java.util.Map;  
    import javax.sql.DataSource;  
    import org.junit.Test;  
    import org.springframework.context.ApplicationContext;  
    import org.springframework.context.support.ClassPathXmlApplicationContext;  
    import org.springframework.jdbc.core.BeanPropertyRowMapper;  
    import org.springframework.jdbc.core.JdbcTemplate;  
    import org.springframework.jdbc.core.RowMapper;  
    import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;  
    import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;  
    import org.springframework.jdbc.core.namedparam.SqlParameterSource;  
      
    public class MyJDBCMain {  
          
        private ApplicationContext ctx = null;  
        private JdbcTemplate jdbcTemplate = null; // JdbcTemplate 只是一个 JDBC的小工具,不支持级联属性  
        private NamedParameterJdbcTemplate namedParameterJdbcTemplate = null; // 支持具名参数,提高代码的可读性。  
          
        // 构造块,在创建对象的时候调用  
        {  
            ctx = new ClassPathXmlApplicationContext("applicationContext.xml");  
            jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");  
            namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");  
        }  
      
        // 测试是否连上数据库连接池  
        @Test  
        public void connectionDataSource() {  
            System.out.println("----------- connectionDataSource ----------");  
            DataSource dataSource = (DataSource) ctx.getBean("dataSource");  
            try {  
                // 若能打印com.mchange.v2.c3p0.impl.NewProxyConnection 说明连接成功。  
                System.out.println(dataSource.getConnection());  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
            System.out.println("^^^^^^^^^^^ connectionDataSource ^^^^^^^^^^^");  
        }  
          
        /** 
         * 直接对Mysql数据进行增,删,改,查,统计的操作 
         */  
        @Test  
        public void crudMysqlOperation() {  
            System.out.println("----------- crudMysqlOperation ----------");  
            // 插入  
            String insertSql = "INSERT INTO ITDragon (account, password) VALUES (?,?)";  
            System.out.println("insert result : " + jdbcTemplate.update(insertSql, "itdragon", "pwdItdragon"));  
            // 修改  
            String updateSql = "UPDATE ITDragon SET password = ? WHERE account = ?";  
            System.out.println("update result : " + jdbcTemplate.update(updateSql, "passwordItdragon", "itdragon"));  
            // 查询  
            String querySql = "SELECT * FROM ITDragon";  
            List<Map<String, Object>> results = jdbcTemplate.queryForList(querySql);  
            System.out.println("query result : " + results);  
            // 删除  
            String deleteSql = "DELETE FROM ITDragon WHERE account = ?";  
            System.out.println("delete result : " + jdbcTemplate.update(deleteSql, "itdragon"));  
            // 统计  
            String countSql = "SELECT count(id) FROM ITDragon";  
            System.out.println("count result : " + jdbcTemplate.queryForObject(countSql, Long.class));  
            System.out.println("^^^^^^^^^^^ crudMysqlOperation ^^^^^^^^^^^");  
        }  
          
        /** 
         * 直接对Mysql数据进行批量的增,删,改的操作 
         */  
        @Test  
        public void batchCrudMysqlOperation() {  
            System.out.println("----------- batchCrudMysqlOperation ----------");  
            // 批量插入  
            String insertSql = "INSERT INTO ITDragon (account, password) VALUES (?,?)";  
            List<Object[]> insertArgs = new ArrayList<>();  
            insertArgs.add(new Object[]{"itdragon", "pwdItdragon"});  
            insertArgs.add(new Object[]{"blog", "pwdBlog"});  
            System.out.println("batch insert result : " + jdbcTemplate.batchUpdate(insertSql, insertArgs));  
            // 查询  
            String querySql = "SELECT * FROM ITDragon";  
            List<Map<String, Object>> results = jdbcTemplate.queryForList(querySql);  
            System.out.println("query result : " + results);  
            // 批量修改  
            String updateSql = "UPDATE ITDragon SET password = ? WHERE account = ?";  
            List<Object[]> updateArgs = new ArrayList<>();  
            updateArgs.add(new Object[]{"passwordItdragon", "itdragon"});  
            updateArgs.add(new Object[]{"passwordBlog", "blog"});  
            System.out.println("batch udpate result : " + jdbcTemplate.batchUpdate(updateSql, updateArgs));  
            // 批量删除  
            String deleteSql = "DELETE FROM ITDragon WHERE account = ?";  
            List<Object[]> deleteArgs = new ArrayList<>();  
            deleteArgs.add(new Object[]{"itdragon"});  
            deleteArgs.add(new Object[]{"blog"});  
            System.out.println("batch delete result : " + jdbcTemplate.batchUpdate(deleteSql, deleteArgs));  
            // 统计  
            String countSql = "SELECT count(id) FROM ITDragon";  
            System.out.println("count result : " + jdbcTemplate.queryForObject(countSql, Long.class));  
            System.out.println("^^^^^^^^^^^ batchCrudMysqlOperation ^^^^^^^^^^^");  
        }  
          
        /** 
         * 对象的增删改查,改用 NamedParameterJdbcTemplate 
         * 要求:参数名要和类的属性名一样 
         * 好处:之前的参数用?表示,不直观,代码的可读性较差,出错率较高。 
         * 缺点:多敲几个字母 
         */  
        @Test  
        public void crudObjectOperation() {  
            System.out.println("----------- crudObjectOperation ----------");  
            // 插入  
            String insertSql = "INSERT INTO ITDragon (account, password) VALUES (:account,:password)";  
            ITDragon itDragon = new ITDragon();  
            itDragon.setAccount("itdragon");  
            itDragon.setPassword("pwdItdragon");  
            SqlParameterSource paramSource = new BeanPropertySqlParameterSource(itDragon);  
            System.out.println("insert object result : " + namedParameterJdbcTemplate.update(insertSql, paramSource));  
            // 查询  
            String querySql = "SELECT * FROM ITDragon";  
            // 使用 RowMapper 指定映射结果集的行  
            RowMapper<ITDragon> rowMapper = new BeanPropertyRowMapper<>(ITDragon.class);  
            List<ITDragon> results = namedParameterJdbcTemplate.query(querySql, rowMapper);  
            System.out.println("query object result : " + results);  
            // 更新和删除 也是update方法,这里不做过多的描述   
            System.out.println("^^^^^^^^^^^ crudObjectOperation ^^^^^^^^^^^");  
        }  
      
    }  
    
    public class ITDragon {
    	
    	private Integer id;
    	private String account;
    	private String password;
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getAccount() {
    		return account;
    	}
    	public void setAccount(String account) {
    		this.account = account;
    	}
    	public String getPassword() {
    		return password;
    	}
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	@Override
    	public String toString() {
    		return "ITDragon [id=" + id + ", account=" + account + ", password="
    				+ password + "]";
    	}
    
    }
    
    ----------- connectionDataSource ----------  
    com.mchange.v2.c3p0.impl.NewProxyConnection@16ba2b8  
    ^^^^^^^^^^^ connectionDataSource ^^^^^^^^^^^  
    ----------- crudMysqlOperation ----------  
    insert result : 1  
    update result : 1  
    query result : [{id=4, account=itdragon, password=passwordItdragon}]  
    delete result : 1  
    count result : 0  
    ^^^^^^^^^^^ crudMysqlOperation ^^^^^^^^^^^  
    ----------- batchCrudMysqlOperation ----------  
    batch insert result : [I@3c9dd8  
    query result : [{id=10, account=itdragon, password=pwdItdragon}, {id=11, account=blog, password=pwdBlog}]  
    batch udpate result : [I@c094f6  
    batch delete result : [I@1917d6d  
    count result : 0  
    ^^^^^^^^^^^ batchCrudMysqlOperation ^^^^^^^^^^^  
    ----------- crudObjectOperation ----------  
    insert object result : 1  
    query object result : [ITDragon [id=12, account=itdragon, password=pwdItdragon]]  
    ^^^^^^^^^^^ crudObjectOperation ^^^^^^^^^^^  
    

    从打印的结果可以看出,如果插入,修改,删除一条数据,成功就返回1。如果是批量操作,则返回的是一个int[] 数组。
    好了!到这里,Spring4 的JDBC就讲完了。有关jdbc的事务,就放到下一章介绍。喜欢的话可以点个赞哦!

    一点点成长,一点点优秀。如果有什么建议和疑问可以留言。

  • 相关阅读:
    读书笔记——吴军《态度》
    JZYZOJ1237 教授的测试 dfs
    NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论
    [JZYZOJ 1288][洛谷 1005] NOIP2007 矩阵取数 dp 高精度
    POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数
    POJ2157 Check the difficulty of problems 概率DP
    HDU3853 LOOPS 期望DP 简单
    Codeforces 148D. Bag of mice 概率dp
    POJ3071 Football 概率DP 简单
    HDU4405 Aeroplane chess 飞行棋 期望dp 简单
  • 原文地址:https://www.cnblogs.com/itdragon/p/7717961.html
Copyright © 2011-2022 走看看