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的事务,就放到下一章介绍。喜欢的话可以点个赞哦!

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

  • 相关阅读:
    模板实现查找算法
    指针笔试题
    【查找算法】基于比较的查找算法(顺序查找、对分查找、分块查找)
    flask动态路由
    flask对json的内置处理模块jsonify
    pyquery和etree两个模块的区别
    单元测试初试
    求数组中子数组的最大值
    C语言小程序之读取文本文件中单词的个数并打印出频率最高的10个
    电梯去哪儿
  • 原文地址:https://www.cnblogs.com/itdragon/p/7717961.html
Copyright © 2011-2022 走看看