zoukankan      html  css  js  c++  java
  • JDBCTemplate执行增删改查(CDUR)操作

    1、JdbcTemplate简介

    (1)Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装。语法风格非常接近DBUtil。

    • JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTemplate也是为声明式事务做准备,毕竟要对数据库中的数据进行操纵!
    • JdbcTemplate中并没有提供一级缓存,以及类与类之间的关联关系!就像是spring提供的一个DBUtils。
    • Spring对数据库的操作使用JdbcTemplate来封装JDBC,结合Spring的注入特性可以很方便的实现对数据库的访问操作。使用JdbcTemplate可以像JDBC一样来编写数据库的操作代码

    (2)为啥要使用Jdbc_template进行开发呢?

    • Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。
    • Spring提供的JdbcTemplate对jdbc做了封装,大大简化了数据库的操作。

    找到Spring JdbcTemplate源码,可以看到如下方法:

    Connection con = DataSourceUtils.getConnection(getDataSource());

    如果直接使用JDBC的话,需要我们加载数据库驱动、创建连接、释放连接、异常处理等一系列的动作;繁琐且代码看起来不直观。

    此外,Spring提供的JdbcTempate能直接数据对象映射成实体类,不再需要获取ResultSet去获取值/赋值等操作,提高开发效率;

    如下:return (User) jdbcTemplate.queryForObject("select * from tb_test1 where id = 100", User.class)

    (3)配置环境

    ①导入jar包

      • commons-logging-1.1.3.jar
      • spring-aop-4.0.0.RELEASE.jar //注解会使用到的包
      • spring-beans-4.0.0.RELEASE.jar
      • spring-context-4.0.0.RELEASE.jar
      • spring-core-4.0.0.RELEASE.jar
      • spring-expression-4.0.0.RELEASE.jar

    ②在IOC容器中配置数据源

    <!-- 加载properties文件中 信息 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 配置数据源 -->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.passowrd}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
    </bean>

    其中jdbc.properties文件内容:

    • jdbc.user=root
    • jdbc.passowrd=mysql
    • jdbc.url=jdbc:mysql://localhost:3306/test
    • jdbc.driver=com.mysql.jdbc.Driver

    ③在IOC容器(applicationContext.xml)中配置JdbcTemplate对象的bean,并将数据源对象装配到JdbcTemplate对象中

    <!-- 配置JdbcTemplate对应的bean, 并装配dataSource数据源属性-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>

    2、案例演示

    (1)首先,新建数据库 jdbc_template,新建表 employee,并插入几条测试数据

    USE `jdbc_template`;
    DROP TABLE IF EXISTS `employee`;
    CREATE TABLE `employee` (
      `emp_id` int(11) NOT NULL AUTO_INCREMENT,
      `emp_name` char(100) DEFAULT NULL,
      `salary` double DEFAULT NULL,
      PRIMARY KEY (`emp_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=gb2312;

    将数据库连接信息改为:jdbc.url=jdbc:mysql://localhost:3306/jdbc_template

    (2)在bean包下新建 Employee.java

     1 public class Employee {
     2     private Integer emp_id;
     3     private String emp_name;
     4     private Double salary;
     5     public Employee() {
     6         super();
     7     }
     8     public Employee(Integer emp_id, String emp_name, double salary) {
     9         super();
    10         this.emp_id = emp_id;
    11         this.emp_name = emp_name;
    12         this.salary = salary;
    13     }
    14     public int getEmp_id() {
    15         return emp_id;
    16     }
    17     public void setEmp_id(int emp_id) {
    18         this.emp_id = emp_id;
    19     }
    20     public String getEmp_name() {
    21         return emp_name;
    22     }
    23     public void setEmp_name(String emp_name) {
    24         this.emp_name = emp_name;
    25     }
    26     public double getSalary() {
    27         return salary;
    28     }
    29     public void setSalary(double salary) {
    30         this.salary = salary;
    31     }
    32     @Override
    33     public String toString() {
    34         return "Employee [emp_id=" + emp_id + ", emp_name=" + emp_name + ", salary=" + salary + "]";
    35     }
    36 }
    Employee.java

    (3)新建JUnit测试类进行测试 TestJdbcTemp.java

    public class TestJdbcTemp {
        //声明两个对象ioc和JdbcTemplate
        private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        private JdbcTemplate template = ioc.getBean(JdbcTemplate.class);
    }

    ① 测试数据源 DataSource 

    @Test
    public void testDataSource() {
        DataSource bean = ioc.getBean(DataSource.class);
        try {
            System.out.println(bean.getConnection());//com.mchange.v2.c3p0.impl.NewProxyConnection@223aa2f7
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    ② 将emp_id=5的记录的salary字段更新为1300.00【更新操作】

    @Test
    public void testUpdate() {
        String sql = "UPDATE employee SET salary = ? WHERE emp_id = ?";
        template.update(sql, 1300, 5);//第一个是sql语句,后面的按着顺序传入参数即可,update方法能接收的可变参数!
    }

    可以看到,该操作不用我们自己再去获取数据库连接信息了,而是直接传递sql语句及其参数就可以了!

    ③ 批量插入

    @Test
    public void testBatch() {
        String sql = "INSERT INTO employee(`emp_name`,`salary`) VALUES(?,?)";
        // 执行sql语句需要传递的参数
        List<Object[]> list = new ArrayList<Object[]>();
        list.add(new Object[] { "Tom2015", 1000 });
        list.add(new Object[] { "Tom2016", 2000 });
        list.add(new Object[] { "Tom2017", 3000 });
        template.batchUpdate(sql, list);
    }

    ④ 查询emp_id=5的数据库记录,封装为一个Java对象返回,

    分析:封装为一个对象返回的话,首先我们需要有一个与数据表对应的实体类!

    @Test
    public void testFindById(){
        //需要注意的是:sql语句中的别名要与对应实体类的属性名保持一致!ps:这里不用别名也可以
        String sql = "SELECT emp_id AS emp_id,emp_name AS emp_name,salary FROM employee WHERE emp_id=?";
        //RowMapper是一个接口,我们使用其子类,把查出来的数据封装成一个bean对象
        RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<Employee>(Employee.class);
        //最后一个参数是可变参数,用于向sql语句中依次传递参数!
        Employee employee = template.queryForObject(sql, rowMapper, 5);
        System.out.println(employee);//Employee [emp_id=5, emp_name=Kasier, salary=1300.0]
    }

    ⑤ 查询salary>4000的数据库记录,封装为List集合返回

    @Test
    public void testEmployeeList(){
        //需要注意的是:sql语句中的别名要与对应实体类的属性名保持一致!ps:这里不用别名也可以
        String sql = "SELECT emp_id AS emp_id,emp_name AS emp_name,salary FROM employee WHERE salary > ?";
        //RowMapper是一个接口,这里我们使用其子类,把查出来的数据封装成一个bean对象
        RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<Employee>(Employee.class);
        //该query方法查询出来的是一个list列表,query方法的最后一个参数是可变参数!
        List<Employee> list = template.query(sql, rowMapper, 4000);
        for (Employee employee : list) {
            System.out.println(employee);
            //Employee [emp_id=1, emp_name=Susan, salary=5000.23]
            //Employee [emp_id=2, emp_name=Julian, salary=4234.77]
            //Employee [emp_id=3, emp_name=Papu, salary=9034.51]
            //Employee [emp_id=4, emp_name=Babala, salary=8054.33]
            //Employee [emp_id=6, emp_name=Owen, salary=7714.11]
        }
    }

    查询结果是一个实体还是一个list列表是靠template对象的不同方法实现的!

    ⑥ 查询最大salary【返回单值】

    @Test
    public void testMaxSalary(){
        String sql = "SELECT MAX(salary) FROM employee";
        //需要指定返回值的类型,而且类型必须是包装类型,可带可变参数
        Double maxSalary = template.queryForObject(sql, Double.class);
        System.out.println(maxSalary);//9034.51
    }

    ⑦ 使用带有具名参数的SQL语句插入一条员工记录,并以Map形式传入参数值

    具名参数:是指基于名称的,前面我们使用的都是用?作为占位符,然后是使用基于位置的

    如果要使用具名参数的sql语句就必须在spring配置文件中配置NamedParameterJdbcTemplat这个模板类,而不能使用原来的JdbcTemplate,因为JdbcTemplate不能完成这样的任务!

    在 applicationContext.xml 中新增配置信息

    <!-- 加载properties文件中的信息 -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <!-- 配置数据源 -->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!-- 配置JdbcTemplate对应的bean, 并装配dataSource数据源属性-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
    <!-- 为了执行带有具名参数的SQL语句,需要配置NamedParameterJdbcTemplate -->
    <!-- 该NamedParameterJdbcTemplate类没有无参构造器,需要传入JdbcTemplate对象或者数据源对象[DataSource] -->
    <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <!-- 不能使用property标签配置哦 -->
        <constructor-arg ref="jdbcTemplate"></constructor-arg>
    </bean>

    测试

    @Test
    public void testParam(){
        String sql="INSERT INTO employee VALUES(null,:paramName,:paramSalary)";
        Map<String,Object> paramMap = new HashMap<String,Object>();
        paramMap.put("paramName","LiMing" );
        paramMap.put("paramSalary",1000);
        namedJdbcTemplate.update(sql, paramMap);
    }

    ⑧ 重复实验 ⑦,以 SqlParameterSource 形式传入参数值

    @Test
    public void testParameterSource(){
        String sql="INSERT INTO employee(`emp_name`,`salary`) VALUES(:emp_name,:salary)";
        //该BeanPropertySqlParameterSource类构造器需要一个对象参数,该对象参数是一个封装了sql语句参数的对象!
        //此时要求对象的属性名要和sql中的参数名保持一致!这里我们使用Employee对象来完成
        Employee employee= new Employee(null, "Danny", 1500);
        //以实体对象的形式封装具名参数和值
        SqlParameterSource source = new BeanPropertySqlParameterSource(employee);
        namedJdbcTemplate.update(sql, source);
    }

    ⑨ 创建 EmployeeDao,自动装配 JdbcTemplate 对象

    创建 EmployeeDao 类

    @Repository//加载到IOC容器
    public class EmployeeDao {
        @Autowired//注入JdbcTemplate对象
        private JdbcTemplate jdbcTemplate;
        //更新工资,加1000元
        public void updateSaraly(Integer id){
            String sql = "update employee set salary=salary+1000 where emp_id=?";
            jdbcTemplate.update(sql, id);
        }
        //查询所有员工信息
        public List<Employee> findAll(){
            String sql = "select * from employee";
            RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<Employee>(Employee.class);
            return jdbcTemplate.query(sql, rowMapper);
        }
    }

    配置spring的配置文件的配置文件 applicationContext.xml

    <!-- 配置扫描的包 -->
    <context:component-scan base-package="com.bwlu.dao"></context:component-scan>
    <!-- 加载properties文件中的信息 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 配置数据源 -->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.passowrd}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
    </bean>
    <!-- 配置JdbcTemplate对应的bean,并装配dataSource数据源属性-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>

    测试Dao

    @Test
    public void testUpdateSalary(){
        EmployeeDao employeeDao = ioc.getBean(EmployeeDao.class);
        employeeDao.updateSaraly(11);
    }
    @Test
    public void testFindAll(){
        EmployeeDao employeeDao = ioc.getBean(EmployeeDao.class);
        List<Employee> list = employeeDao.findAll();
        for (Employee employee : list) {
            System.out.println(employee);
        }
    }
  • 相关阅读:
    基于WINCE6.0+S3C2443的camera驱动
    WINCE下基于SL031的RFID功能的实现
    WINCE6.0+S3C2443下的activesync问题
    WINCE6.0+S3C2443下WatchDog学习
    错误的抉择,痛悔
    WINCE5.0下SQL server compact版本更新
    做生意和打工的区别
    WINCE基于MC8630的3G模块的控制和加载
    Xml Tips
    VB.NET and C# Comparison
  • 原文地址:https://www.cnblogs.com/lixiang1993/p/7459870.html
Copyright © 2011-2022 走看看