SpringTemplate操作数据库(了解)
- 一、概述
- 二、环境准备
- 2.1 导入JAR包
- 2.2 在Spring配置文件中配置相关的bean
- 三、持久化操作
- 3.1 增删改
- 3.2 批量增删改
- 3.3 查询单行
- 3.4 查询多行
- 3.5 查询单一值
- 四、使用具名参数的JdbcTemplate
- 4.1 关于具名参数
- 4.2 通过IOC容器创建NamedParameterJdbcTemplate对象
- 4.3 具名参数在SQL语句中的格式
- 4.4 具名参数传入
- 五、使用JdbcTemplate实现Dao
一、概述
为了使JDBC更加易于使用,Spring在JDBC API上定义了一个抽象层,以此建立一个JDBC存取框架。
作为Spring JDBC框架的核心,JDBC模板的设计目的是为不同类型的JDBC操作提供模板方法,通过这种方式,可以在尽可能保留灵活性的情况下,将数据库存取的工作量降到最低
可以将Spring的JdbcTemplate看作是一个小型的轻量级持久化层框架,和我们之前使用过的DBUtils风格非常接近。
二、环境准备
2.1 导入JAR包
- IOC容器所需要的JAR包
commons-logging-1.1.1.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
- JdbcTemplate所需要的JAR包
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
- 数据库驱动和数据源
druid-1.1.9.jar
mysql-connector-java-5.1.7-bin.jar
2.2 在Spring配置文件中配置相关的bean
配置数据源对象和JdbcTemplate对象
<!-- 引入外部配置文件,注意classpath严格区分大小写 -->
<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>
<!-- Spring提供了一个类JdbcTemplate,我们用它操作数据库;
导入Spring的数据库模块
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>
三、持久化操作
3.1 增删改
JdbcTemplate.update(sql, Object...)
示例:
//将emp_id=5的记录的salary字段更新为1300.00
@Test
public void test02(){
System.out.println(jdbcTemplate);
String sql = "update employee set salary=? where emp_id=?";
int update = jdbcTemplate.update(sql, 1300.00,5);
System.out.println(update);
}
3.2 批量增删改
JdbcTemplate.batchUpdate(sql, List<Object[]>)
Object[]封装了SQL语句每一次执行时所需要的参数
List集合封装了SQL语句多次执行时的所有参数
/**
* 批量插入
*/
@Test
public void test03(){
String sql = "insert into employee(emp_name,salary) values(?,?)";
//List<Object[]>
//List的长度就是sql语句要执行的次数
//Object[]:每次执行要用的参数
List<Object[]> batchArgs = new ArrayList<Object[]>();
batchArgs.add(new Object[]{"Jack1",1241.0});
batchArgs.add(new Object[]{"Jack2",1242.0});
batchArgs.add(new Object[]{"Jack3",1243.0});
batchArgs.add(new Object[]{"Jack4",1244.0});
int[] batchUpdate = jdbcTemplate.batchUpdate(sql, batchArgs);
for(int i : batchUpdate){
System.out.println(i);
}
}
3.3 查询单行
JdbcTemplate.queryForObject(sql, RowMapper<Department>, Object...)
/**
* 实验4:查询emp_id=5的数据库记录,封装为一个Java对象返回;
* javaBean需要和数据库中字段名一致,否则无法完成封装;
*
* jdbcTemplate在方法级别进行了区分
* 查询集合:jdbcTemplate.query()
* 查询单个对象:jdbcTemplate.queryForObject()
* 如果查询没结果就报错;(无法自动赋值为null)
*
*/
@Test
public void test04(){
String sql = "select emp_id empId,emp_name empName,salary from employee where emp_id=?";
Employee queryForObject = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Employee.class),5);
System.out.println(queryForObject);
}
3.4 查询多行
JdbcTemplate.query(sql, RowMapper<Department>, Object...)
RowMapper对象依然可以使用BeanPropertyRowMapper
/**
* 实验5:查询salary>4000的数据库记录,封装为List集合返回
*/
@Test
public void test05(){
String sql2 = "select emp_id empId,emp_name empName,salary from employee where salary>?";
List<Employee> query = jdbcTemplate.query(sql2, new BeanPropertyRowMapper<>(Employee.class), 4000);
System.out.println(query);
}
3.5 查询单一值
JdbcTemplate.queryForObject(sql, Class, Object...)
如果返回值类型为jdk中已有的类,则传入class类型
/**
* 查询最大的salary
*/
@Test
public void test06(){
String sql = "select max(salary) from employee";
Double queryForObject = jdbcTemplate.queryForObject(sql,Double.class);
System.out.println(queryForObject);
}
四、使用具名参数的JdbcTemplate
4.1 关于具名参数
- 在Hibernate的HQL查询中我们体验过具名参数的使用,相对于基于位置的参数,具名参数具有更好的可维护性,在SQL语句中参数较多时可以考虑使用具名参数。
- 在Spring中可以通过NamedParameterJdbcTemplate类的对象使用带有具名参数的SQL语句。
4.2 通过IOC容器创建NamedParameterJdbcTemplate对象
<!-- 配置可以使用具名参数的JDBCTemplate类对象 -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<!-- 没有无参构造器,必须传入数据源或JdbcTemplate对象 -->
<constructor-arg ref="dataSource"/>
</bean>
4.3 具名参数在SQL语句中的格式
INSERT INTO depts (dept_name) VALUES (:deptName)
4.4 具名参数传入
- 通过Map对象传入
/**
* 实验7:使用带有具名参数的SQL语句插入一条员工记录,并以Map形式传入参数值
*
* 具名参数:(具有名字的参数,参数不是占位符了,而是一个变量名)
* 语法格式: :参数名
* Spring有一个支持具名参数功能的JdbcTemplate——NamedParameterJdbcTemplate
*
*/
@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","zhangsan");
paramMap.put("salary",309);
int update = namedParameterJdbcTemplate.update(sql, paramMap);
System.out.println(update);
}
- 通过SqlParameterSource对象传入
/**
* 使用带有具名参数的SQL语句插入一条员工记录,以SqlParameterSource形式传入参数值
*/
@Test
public void test08(){
String sql = "insert into employee(emp_name,salary) values(:empName,:salary)";
Employee employee = new Employee(null,"wangwu",999.9);
int update = namedParameterJdbcTemplate.update(sql,new BeanPropertySqlParameterSource(employee));
System.out.println(update);
}
五、使用JdbcTemplate实现Dao
- JdbcTemplate类是线程安全的,所以可以在IOC容器中声明它的单个实例,并将这个实例注入到所有的Dao实例中。
代码示例:
EmployeeDao
@Repository
public class EmployeeDao {
@Autowired
JdbcTemplate jdbcTemplate;
public void saveEmployee(Employee employee){
String sql = "INSERT INTO employee(emp_name,salary) VALUES(?,?)";
jdbcTemplate.update(sql, employee.getEmpName(),employee.getSalary());
}
}
测试:
public class SpringTest {
ApplicationContext ioc = new ClassPathXmlApplicationContext("ApplicationContext.xml");
/**
* 创建BookDao,自动装配JdbcTemplate对象
*/
@Test
public void test09(){
EmployeeDao employeeDao = ioc.getBean(EmployeeDao.class);
employeeDao.saveEmployee(new Employee(null,"xiao",2343.0));
}
}