Spring-JDBCTemplate

本文介绍了Spring的JDBC模板,旨在简化数据库操作。通过实验展示了如何配置数据源,使用JdbcTemplate进行增删改查,批量操作,以及使用具名参数的SQL语句。还提到了BeanPropertyRowMapper在映射数据库记录到Java对象中的应用。
摘要由CSDN通过智能技术生成

一.概述

为了使JDBC更加易于使用,Spring在JDBC API上定义了一个抽象层,以此建立一个JDBC存取框架。作为Spring JDBC框架的核心,JDBC模板的设计目的是为不同类型的JDBC操作提供模板方法,通过这种方式,可以在尽可能保留灵活性的情况下,将数据库存取的工作量降到最低。

可以将Spring的JdbcTemplate看作是一个小型的轻量级持久化层框架,和我们之前使用过的DBUtils风格非常接近。

二.实验

2.1测试数据源

在之前进行Spring IOC实验时,学习了怎么连接数据连接池,现在来复习一下:

首先将有关数据库的信息写入文件jdbc.properties中:

jdbc.user=root
jdbc.password=password
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/jdbc_template?serverTimezone=UTC
jdbc.driverClass=com.mysql.jdbc.Driver

然后在配置文件applicationContext中配置:

<!-- 引入外部配置文件 -->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<!-- 测试数据源 -->
<!-- 
     要注意:
     #{}Spring的表达式语言
     ${}取出配置文件中的值
 -->
<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>
</bean>

然后在测试类中获取Connection对象,对其进行操作。

1.现在我们要使用Spring 的JdbcTemplate类,首先在原来包(已导入Spring基础包和数据库池包和连接包)的基础上要导入三个包:

spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar

2.在配置文件applicationContext中进行配置:

<bean class="org.springframework.jdbc.core.JdbcTemplate" >
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
<!-- 有一个参数的构造器 -->
</bean>

3.测试:

package com.test.test;



import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

public class TxTest {

	ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
	JdbcTemplate jdbc=ioc.getBean(JdbcTemplate.class);
	@Test
	public void test01() throws SQLException {
		System.out.println(jdbc);
	}


}

2.2 增删改

JdbcTemplate.update(String, Object...)
	//对数据库中的信息进行更新
	public void test02(){
		String  sql="UPDATE employee SET salary=? WHERE emp_id=?";
		int update=jdbc.update(sql, 1300.00,5);
		System.out.println("更新员工"+update);
	}

2.3 批量增删改

JdbcTemplate.batchUpdate(String, List<Object[]>)

Object[]封装了SQL语句每一次执行所需要的参数。

List集合封装了SQL语句多次执行的所有参数。

/*
	 * 批量插入
	 */
	@Test
	public void test03(){
		String sql="INSERT INTO employee(emp_name,salary) VALUES(?,?)";
		//List的长度就是SQL执行的次数
		//Object[],就是每次执行要用的参数
		List<Object[]> list=new ArrayList<Object[]>();
		list.add(new Object[]{"张三",998.99});
		list.add(new Object[]{"李四",998.99});
		list.add(new Object[]{"王麻子",998.99});
		int[] is=jdbc.batchUpdate(sql,list);
		for(int i:is)
		{
			System.out.println(i);
		}
}

2.4 查询

返回值不同的查询如下所示;

  • 查询一条数据库记录(符合条件),封装为一个Java对象返回
    JdbcTemplate.queryForObject(String, RowMapper<Department>, Object...)

  • 查询多条数据库记录(符合条件),封装为List集合返回
    JdbcTemplate.query(String, RowMapper<Department>, Object...)

    RowMapper对象依然可以使用BeanPropertyRowMapper

  • 查询一条数据库数据(符合条件)
    JdbcTemplate.queryForObject(String, Class, Object...)
    
    

     

/*
	 *1. 查询符合条件的一条数据库记录,封装为一个Java对象返回
	 * JavaBean需要和数据库中的字段名一样,否则无法完成封装
	 * jdbcTemplate在方法级别进行了区分
	 * 查询集合:jdbcTemplate.query()
	 * 查询单个对象:jdbc.queryForObject
	 * 查询没结果报错
	 * 
	 * queryForObject中有一个参数RowMapper:
	 * RowMapper:用于将结果集每行数据转换为需要的类型
	 * 
	 */
	@Test
	public void Test04(){
		String sql="SELECT emp_id empId,emp_name empName,salary FROM employee WHERE emp_id=?";
		//RowMapper:每一条记录和JavaBean的属性如何映射
		Employee emplyoee=jdbc.queryForObject(sql,new BeanPropertyRowMapper<>(Employee.class) ,5);
	    System.out.println(emplyoee);
	}
	
	/*
	 *  2.查询符合条件多条数据库记录,封装为List集合返回
	 */
	
	@Test
	public void test05(){
		String sql="SELECT emp_id empId,emp_name empName,salary FROM employee WHERE salary>?";
		//封装list:集合里面的元素
		List<Employee> list=jdbc.query(sql,new BeanPropertyRowMapper<>(Employee.class),4000);
	    for(Employee emplyoee:list)
	    {
	    	System.out.println(emplyoee);
	    }
	}
	
	/*
	 * 3.查询符合条件的单条数据(查询最大salary),
	 *
	 */
	@Test
	public void test06(){
		String sql="SELECT MAX(salary) FROM employee";
		//无论是返回单个数据还是单个对象,都是调用queryForObject
		//queryForObject其实支持的是标量子查询,只能传入一个基本类型的包装类的class,并返回一个基本类型对应包装类型的对象.
		Double object=jdbc.queryForObject(sql, Double.class);
		System.out.println(object);
	}

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

具名参数具有更好的维护性,在SQl语句中参数较多的时候可以考虑具名参数。在Spring中可以通过NamedParameterJdbcTemplate类的对象使用带有具名参数的SQL语句。

通过IOC容器创建NamedParameterJdbcTemplate对象:

<!-- 配置可以使用具名参数的JDBCTemplate类对象 -->
<bean 
	id="namedTemplate" 
	class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
	<!-- 没有无参构造器,必须传入数据源或JdbcTemplate对象 -->
	<constructor-arg ref="dataSource"/>
</bean>

通过Map对象传入:

NamedParameterJdbcTemplate.update(String, Map<String, ?>)
	/*
	 * 使用带有具名参数的SQL语句插入一条记录,并以Map形式传入参数值
	 * 具名参数:(具有名字的参数,参数不是占位符了,而是一个变量名)
	 *     语法格式:  :参数名
	 * Spring有一个支持具名参数功能的JdbcTemplate
	 * 占位符参数:?的顺序千万不能乱,传入参数的时候一定要注意。
	 */
	@Test
	public void test07(){
		String sql="INSERT INTO employee(emp_name,salary) VALUES(:empName,:salary)";
	    Map<String,Object> paramMap=new HashMap<>();
	    //将所有具名参数都放在map中;
         paramMap.put("empName", "周六");
         paramMap.put("salary", 999);
		 int update=namedJdbcTemplate.update(sql, paramMap);
		 System.out.println(update);
		
		
	}

2.6 重复实验1.5,以SqlParameterSource形式传入参数值

	/*
	 * 重复实验7,以SqlParameterSource形式传入参数值
	 */
	@Test
	public void test08(){
		String sql="INSERT INTO employee(emp_name,salary) VALUES(:empName,:salary)";
		Employee em=new Employee();
		em.setEmpName("哈哈");
		em.setSalary(997.90);
		//
		int update=namedJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(em));
		System.out.println(update);
		
	}

2.7 使用JdbcTemplate实现Dao

配置文件:

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<context:component-scan base-package="com.test"></context:component-scan>
<!-- 引入外部配置文件 -->
<context:property-placeholder location="classpath:dbconfig.properties"/>

<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>
</bean>


<bean class="org.springframework.jdbc.core.JdbcTemplate" >
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
<!-- 有一个参数的构造器 -->
</bean>

<!-- 配置一个具有具名参数功能的JdbcTemplate -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<!-- 使用构造器方式注入数据源 -->
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>

</bean>

</beans>

通过IOC容器自动注入:

package com.test.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.test.bean.Employee;

@Repository
public class EmployeeDao {
	
	@Autowired
	JdbcTemplate jdbcTemplate;
	public void saveEmployee(Employee em)
	{
		String sql="INSERT INTO employee(emp_name,salary) VALUES(?,?)";
		jdbcTemplate.update(sql, em.getEmpName(),em.getSalary());
	}

}

测试:

	/*
	 * 创建Dao,自动装配JdbcTemplate对象
	 */
	@Test
	public void test09(){
	EmployeeDao bean=	ioc.getBean(EmployeeDao.class);
	Employee em=new Employee();
	em.setEmpName("哈哈");
	em.setSalary(997.90);
	bean.saveEmployee(em);
	
	
	}

三.注意

3.1 BeanPropertyRowMapper

在之前的查询实验中,发现使用了这个参数。

使用BeanPropertyRowMapper可以将数据库查询结果转化为Java类对象。常应用于使用Spring的JdbcTemplate查询数据库,获取List结果列表,数据库表字段和实体类自动对应

内部实现分析:BeanPropertyRowMapper

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值