1.JdbcTemplate
Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装。
JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTemplate也是为声明式事务做准备,毕竟要对数据库中的数据进行操纵!
JdbcTemplate中并没有提供一级缓存,以及类与类之间的关联关系!就像是spring提供的一个DBUtils。
Spring对数据库的操作使用JdbcTemplate来封装JDBC,结合Spring的注入特性可以很方便的实现对数据库的访问操作。使用JdbcTemplate可以像JDBC一样来编写数据库的操作代码
2.为啥要使用Jdbc_template进行开发呢?
1).对数据源通过注入的方式统一读取,提高了读取和更改数据源的效率,
Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。
2).对连接数据库的步骤做了统一的封装,简化了操作步骤;
如果直接使用JDBC的话,需要我们加载数据库驱动、创建连接、释放连接、异常处理等一系列的动作;繁琐且代码看起来不直观。
3).数据库的数据对象映射成实体对象,方便了对于参数读取和数据库操作结果集的读取,大大提高了开发效率.
Spring提供的JdbcTempate能直接数据对象映射成实体类,不再需要获取ResultSet去获取值/赋值等操作,提高开发效率;
4).对JDBC增删查改操作进行了统一的封装,简化了数据库的操作。
5).JdbcTemplate类是线程安全的,所以可以在IOC容器中声明它的单个实例,并将这个实例注入到所有的Dao实例中。
3.使用JDBCTemplate
1)导入jar包
[1]IOC容器需要的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
[2]MySQL驱动、C3P0jar包
c3p0-0.9.1.2.jar
mysql-connector-java-5.1.37-bin.jar
[3]JdbcTemplate需要的jar包
spring-jdbc-4.0.0.RELEASE.jar spring-orm-4.0.0.RELEASE.jar spring-tx-4.0.0.RELEASE.jar
2)在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=123456 jdbc.url=jdbc:mysql://localhost:3306/test jdbc.driver=com.mysql.jdbc.Driver
在IOC容器中配置JdbcTemplate对象的bean,并将数据源对象装配到JdbcTemplate对象中.
<!-- 配置JdbcTemplate对应的bean, 并装配dataSource数据源属性-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="comboPooledDataSource"></property>
</bean>
配置好后测试一下数据源是否能连接成功
@Test public void test() throws SQLException { ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource bean = ioc.getBean(DataSource.class); System.out.println(bean.getConnection()); }
4.数据库操作
JDBCTemplate提供了五类方法:
execute方法:用于执行任何SQL语句,一般执行DDL语句;
update方法和batchupdate,执行新增,修改,删除语句
catchupdate:批量处理
query及queryForxxx :用于执行查询语句
call:用于执行存储过程及函数。
1)执行更新语句:
将emp_id=5的记录的salary字段更新为1300.00【更新操作】
public class TestDataSource { private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml"); private JdbcTemplate template=ioc.getBean(JdbcTemplate.class); @Test public void test01(){ //实验2:将emp_id=5的记录的salary字段更新为1300.00 String sql = "UPDATE employee SET salary = ? WHERE emp_id = ?"; template.update(sql, 1300,5);//第一个是sql语句,后面的按着顺序传入参数即可,这个update方法是接收的可变参数! } }
从上述实验中就可以看到,该操作不用我们自己再去获取数据库连接信息了,而是直接传递sql语句及其参数!
2)插入操作
/* *Descript:利用jdbcTemplate实现insert操作 *增删改单条数据只需要jdbcTemplate的update方法就够了 */ @Test public void testInssert(){ String sql="insert into employee VALUES(null,?,?)"; //增删改都用update就够了 int update = jdbcTemplate.update(sql,"刘德华",6000); if(update!=0){ System.out.println("插入执行成功:"+update); } else{ System.out.println("插入执行失败"); } }
3)删除操作
/* *Descript:利用jdbcTemplate执行删除数据操作 * */ @Test public void testDelete(){ String sql="DELETE from employee WHERE emp_id=?"; int update = jdbcTemplate.update(sql,8); if(update!=0){ System.out.println("删除执行成功:"+update); } else{ System.out.println("删除执行失败"); } }
4)
查询操作,将查询的数据映射成实体类输出
/*Method:testSelectById *Description:将查询数据库中的数据映射到实体类对象中 *param: */ @Test public void testSelectById(){ String sql="select emp_id as empId,emp_name empName,salary from employee where emp_id=?"; RowMapper<Employee> rowMapper=new BeanPropertyRowMapper<>(Employee.class); List<Employee> employees = jdbcTemplate.query(sql, rowMapper,10 ); for (Employee employee : employees) { System.out.println(employee); } }
5)查询单值,比如输出一个int型的数
/*Method:testSelectSingle *Description:输出结果为单值的查询方法 *param: */ @Test public void testSelectSingle(){ String sql="SELECT MAX(salary) FROM employee;"; //查询结果为输出工资中的最大值 Double MaxSalary = jdbcTemplate.queryForObject(sql, Double.class); System.out.println("最大工资值:"+MaxSalary); }
6)批量插入操作
/*Method:testBatchInsert() *Description:进行批量添加数据 *param: */ @Test public void testBatchInsert(){ String sql="insert into employee VALUES(null,?,?)"; List<Object[]> list=new ArrayList<>(); list.add(new Object[]{"黎明",4300}); list.add(new Object[]{"郭富城",6500}); jdbcTemplate.batchUpdate(sql, list); System.out.println("批量添加"); }
7)使用带有具名参数的SQL语句插入一条员工记录,并以Map形式传入参数值
需要在spring的XML文件中配置一下
<!-- 为了执行带有具名参数的SQL语句,需要配置NamedParameterJdbcTemplate -->
<!-- 该NamedParameterJdbcTemplate类没有无参构造器,需要传入JdbcTemplate对象或者数据源对象[DataSource] -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<!-- 不能使用property标签配置哦 -->
<constructor-arg ref="jdbcTemplate"></constructor-arg>
</bean>
/*Method:testNameParam *Description:基于参数名称的查询语句 *param: */ @Test public void testNameParam(){ //不再是基于占位符,而是基于名称的语句 String sql="insert into employee VALUES(null,:name,:salary)"; Map<String, Object> map=new HashMap<>(); map.put("name", "孙悟空"); map.put("salary", 1000); nameTemplate.update(sql, map); }
8)将参数封装成对象作为参数传输执行语句
/*Method:testInsertEmployee *Description:将参数封装成对象作为参数传输执行语句 *param: */ @Test public void testInsertEmployee(){ String sql="insert into employee VALUES(null,:empName,:salary)"; Employee employee=new Employee(20, "八戒", 1500); SqlParameterSource sqlParameter=new BeanPropertySqlParameterSource(employee); nameTemplate.update(sql, sqlParameter); }