Spring组件之一 JDBC Template
JDBC Template是基于JDBC的基础上产生的,所以在讲JDBC Template之前,先聊聊 JDBC ?
什么是JDBC ?
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
简单点说,JDBC API是JAVA提供的一套统一访问数据库的接口,而这些接口的具体实现是由各个数据库厂商通过JDBC驱动(就是我们连接数据库是导入的那个jar包)这种方式提供的。
JDBC Template 简介
由于,直接基于JDBC API的编程,重复性代码量大,操作繁琐。Spring对数据库的操作在JDBC API中提供的功能上进行简单的封装,Spring IoC容器将管理数据库连接的DataSource数据源当作普通的Java Bean进行管理,然后将DataSource注入到JdbcTemplate封装类中。
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/jdbc_template?characterEncoding=utf-8"/><property name="username" value="root"/><property name="password" value="root"/>
</bean><!--配置JDBC Template组件提供的工具类对象,并注入dataSource数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/>
</bean>
Spring对JDBC API进行封装(JDBC Template)后,提供一些更为简洁方便的方法。所以在进行开发的时候,我们就直接使用JDBC Template中提供的工具类或工具方法来进行数据的操作,不再是直接基于JDBC API来进行操作了,从而简化我们操作,使我们的快发更加便捷。
那JDBC Template到底是什么?
JDBC Template 是Spring的一个组件,是Spring为简化持久化操作提供的
JDBC Template 是在JDBC API的基础上完成的,Template译为模板,通俗点说,JDBC Template 就是Spring对JDBC的封装的模板
JDBC Template 提供了统一的模板方法,在保留代码灵活性的基础上,尽量减少持久化操作中的重复性代码。
下面的两段代码,它们实现的功能是一样的,但通过JDBC Template方式明显要简便很多
谈谈JDBC Template做了什么?
从传统 JDBC 编程详解一文中,我们可以看出,JDBC每次执行操作时,都需要进行数据库连接,创建Statement对象,处理SQL语句,处理结果集,关闭数据库这些操作;甚至有时还可能出现数据库忘记关闭导致连接被占用
但在JDBC Template中,这些都无需我们考虑,Spring都已经为我们封装好了,只需在Spring配置文件中将数据源注入到JdbcTemplate封装类中,就可以通过JdbcTemplate对象调用相应的方法执行操作即可。操作数据库结束后,也无需关注数据库关闭问题
接下来,我们从功能上来了解一下JdbcTemplate提供的各类方法
数据库表结构
pom引入下面相关jar
Spring配置
- 数据源
- JdbcTemplate
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/jdbc_template?characterEncoding=utf-8"/><property name="username" value="root"/><property name="password" value="root"/>
</bean><!--配置jdbc template组件提供的工具类,并注入数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/>
</bean><!--自动扫描-->
<context:component-scan base-package="com.cd4356.jdbc_template"/>
JdbcTemplate作为一个工具类,它提供的简化持久化操作的功能是通过方法来呈现的,JdbcTemplate主要提供以下五类方法:
execute方法,可以用来执行任何sql语句,但在实际开发中,我们通常是使用它来执行DDL(数据定义语言)语句,比如通过create、drop、alter此类关键字来完成的操作。所以在实际应用中,该方法比较少用
update 和 batchUpdate方法,用来执行增删改操作
query 和 queryXXX方法,用来执行查询操作
execute方法
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;@Testpublic void testExecute(){//通过jdbcTemplate的execute方法执行DDL类型语句,创建一个user表jdbcTemplate.execute("create table user(id int,name varchar(20))");}
}
预编译SQL语句,参数采用占位符?
进行填充
以Object[]数组 或 不定项参数方式给预编译的SQL语句传值填充占位符
不定项参数,不管是在update方法中,还是在后面的query方法中,它一定是放在参数列表的最后一个位置
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;@Testpublic void testUpdate1(){String sql = "insert into student(name,sex,born) values(?,?,?)";jdbcTemplate.update(sql,new Object[]{"李钦","男", "1998-12-05"});}@Testpublic void testUpdate2(){String sql = "update student set sex=?,born=? where id=?";jdbcTemplate.update(sql,"女","1998-11-02",2);}
}
批量操作方法根据传入的参数不同,又可分为非同构批量操作 和 同构批量操作
- 非同构批量操作,传入的参数是一个String类型的数组,数组元素是不同结构的SQL语句
- 同构批量操作,传入两个参数,第一个参数是SQL语句;第二个参数是元素为Object[]数组类型的List集合
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;//非同构批量操作@Testpublic void testBatchUpdate1(){String[] sqls = {"insert into student(name,sex,born) values('赖红','男','1985-6-19')","insert into student(name,sex,born) values('宋晓青','女','1990-2-14')","update student set name='李青',sex='女' where id=1"};jdbcTemplate.batchUpdate(sqls);}//同构批量操作@Testpublic void testBatchUpdate2(){String sql = "insert into student(name,sex,born) values(?,?,?)";List list = new ArrayList<Object>();list.add(new Object[]{"张运生","男","1982-3-12"});list.add(new Object[]{"耿易","男","1987-12-04"});jdbcTemplate.batchUpdate(sql,list);}
}
在实际应用中,查询操作使用的频率是远远高于增删改的,并且查询操作又特别灵活,形式多种多样,所以JDBC Template对查询的设置是非常细致的。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;//==========================获取一个简单数据项==========================@Testpublic void testQueryForObject1(){String sql = "select count(*) from student";int count = jdbcTemplate.queryForObject(sql,Integer.class);System.out.println(count);}@Testpublic void testQueryForObject2(){String sql = "select name from student where id=? and sex=?";String name = jdbcTemplate.queryForObject(sql,new Object[]{2,"男"},String.class);System.out.println(name);}@Testpublic void testQueryForObject3(){String sql = "select name from student where id=? and sex=?";String name = jdbcTemplate.queryForObject(sql,String.class,2,"男");System.out.println(name);}//==========================获取多个简单数据项==========================@Testpublic void testQueryForList1(){String sql = "select name from student";List<Object> names = (List) jdbcTemplate.queryForList(sql,Object.class);System.out.println(names);}@Testpublic void testQueryForList2(){String sql = "select name from student where sex=? and id<?";List<Object> names = (List) jdbcTemplate.queryForList(sql,new Object[]{"女",5},Object.class);System.out.println(names);}@Testpublic void testQueryForList3(){String sql = "select name from student where sex=? and id<?";List<Object> names = (List) jdbcTemplate.queryForList(sql,Object.class,"女",5);System.out.println(names);}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;//=============================获取一个对象=============================@Testpublic void testQueryForMap(){String sql = "select * from student where id=?";Map<String, Object> map = jdbcTemplate.queryForMap(sql,2);System.out.println(map);}//=============================获取多个对象=============================@Testpublic void testQueryForList(){String sql = "select * from student";List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);System.out.println(list);}
}
在student数据库表中,每一条数据代表一个学生;而在java中,定义一个Student类,一个Student类型的对象代表一个学生。
在进行持久化操作的时候,从数据库的student表中查询出来的记录,每一条记录都转化成一个Student对象来供我们使用。而在转化的过程中,student表的各个字段和Student类的各个属性之间(字段名和属性名需一致),是怎么一一对应的,它们的映射关系是怎么实现的。
JDBC Template通过RowMapper接口实现字段和属性之间的映射
先定一个User实体类
package com.cd4356.jdbc_template.entity;import java.util.Date;public class Student {private int id;private String name;private String sex;private Date born;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBorn() {return born;}public void setBorn(Date born) {this.born = born;}@Overridepublic String toString() {return "Student{ id="+id+", name="+name+", sex="+sex+", born="+born+'}';}
}
定义一个私有内部类实现RowMapper接口,并重写mapRow方法。mapRow方法将ResultSet结果集暴露出来,我们可以直接进行访问ResultSet结果集。然后在mapRow方法中可以使用JDBC的那种方式,让字段和属性进行映射。接着在query或queryForObject方法中传入该实现了RowMapper接口的类对象(RowMapper类型对象)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;//=============================获取一个对象=============================@Testpublic void testQueryForObject(){String sql = "select*from student where id=?";Student student = jdbcTemplate.queryForObject(sql, new StudentRowMapper(),2);System.out.println(student);}//=============================获取多个对象=============================@Testpublic void testQuery(){String sql = "select*from student";/*** query方法的返回值是一个List集合,集合元素是Student对象*/List<Student> list = jdbcTemplate.query(sql, new StudentRowMapper());System.out.println(list);}//定义一个私有类实现RowMapper接口private class StudentRowMapper implements RowMapper<Student>{public Student mapRow(ResultSet resultSet, int i) throws SQLException {Student student = new Student();/*** 注意从数据库取值的时候,实体类属性名和数据库表的字段名需一一对应*/student.setId(resultSet.getInt("id"));student.setName(resultSet.getString("name"));student.setSex(resultSet.getString("sex"));student.setBorn(resultSet.getDate("born"));return student;}}
}
当然你也可以通过匿名内部类的方式,直接在query或queryForObject方法中使用该RowMapper接口对象,但这样很繁琐且不易维护
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate JdbcTemplate jdbcTemplate;//=============================获取一个对象=============================@Testpublic void testQueryForObject(){String sql = "select*from student where id=?";Student student = jdbcTemplate.queryForObject(sql, new RowMapper<Student>() {public Student mapRow(ResultSet resultSet, int i) throws SQLException {Student student = new Student();/*** 注意从数据库取值的时候,实体类属性名和数据库表的字段名需一一对应* 让属性和字段进行映射*/student.setId(resultSet.getInt("id"));student.setName(resultSet.getString("name"));student.setSex(resultSet.getString("sex"));student.setBorn(resultSet.getDate("born"));return student;}},2);System.out.println(student);}//=============================获取多个对象=============================@Testpublic void testQuery(){String sql = "select*from student";/*** query方法的返回值是一个List集合,集合元素是Student对象*/List<Student> list = jdbcTemplate.query(sql, new RowMapper<Student>() {public Student mapRow(ResultSet resultSet, int i) throws SQLException {Student student = new Student();/*** 注意从数据库取值的时候,实体类属性名和数据库表的字段名需一一对应*/student.setId(resultSet.getInt("id"));student.setName(resultSet.getString("name"));student.setSex(resultSet.getString("sex"));student.setBorn(resultSet.getDate("born"));return student;}});System.out.println(list);}
}
前面,从功能上来了解了JdbcTemplate提供的各类方法。那么在实际项目开发中,若想使用Jdbc Template来封装它的持久层,从结构上,应该怎么设置
定义实体类
package com.cd4356.jdbc_template.entity;import java.util.Date;public class Student {private int id;private String name;private String sex;private Date born;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBorn() {return born;}public void setBorn(Date born) {this.born = born;}@Overridepublic String toString() {return "Student{ id="+id+", name="+name+", sex="+sex+", born="+born+'}';}
}
定义dao接口
package com.cd4356.jdbc_template.dao;import com.cd4356.jdbc_template.entity.Student;import java.util.List;public interface StudentDao {void insert(Student student);void delete(int id);void update(Student student);Student select(int id);List<Student> selectAll();
}
实现dao接口,注入JdbcTemplate实例对象,并声明RowMapper
package com.cd4356.jdbc_template.dao;import com.cd4356.jdbc_template.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;@Repository
public class StudentDaoImpl implements StudentDao{//注入JdbcTemplate@Autowiredprivate JdbcTemplate jdbcTemplate;public void insert(Student student) {String sql = "insert into student(name,sex,born) values(?,?,?)";jdbcTemplate.update(sql,student.getName(),student.getSex(),student.getBorn());}public void delete(int id) {String sql = "delete from student where id=?";jdbcTemplate.update(sql,id);}public void update(Student student) {String sql = "update student set name=?,sex=?,born=? where id=?";jdbcTemplate.update(sql,student.getName(),student.getSex(),student.getBorn(),student.getId());}public Student select(int id) {String sql = "select*from student where id=?";return jdbcTemplate.queryForObject(sql,new StudentRowMapper(),id);}public List<Student> selectAll() {String sql = "select*from student";return jdbcTemplate.query(sql,new StudentRowMapper());}//定义一个私有内部类实现RowMapper接口private class StudentRowMapper implements RowMapper<Student> {public Student mapRow(ResultSet resultSet, int i) throws SQLException {Student student = new Student();/*** 注意从数据库取值的时候,实体类属性名和数据库表的字段名需一一对应*/student.setId(resultSet.getInt("id"));student.setName(resultSet.getString("name"));student.setSex(resultSet.getString("sex"));student.setBorn(resultSet.getDate("born"));return student;}}
}
测试代码
package com.cd4356.jdbc_template;import com.cd4356.jdbc_template.dao.StudentDao;
import com.cd4356.jdbc_template.entity.Student;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate StudentDao studentDao;@Testpublic void find(){Student student = studentDao.select(3);System.out.println(student);}
}
输出结果
优点:简单、灵活
- JDBC Template对JDBC API进行封装后,提供简洁方便的方法,简化了我们开发的代码,并且保留了它的灵活性,使我们的快发更加便捷
缺点
SQL与Java代码参杂,对开发人员要求较高,我们更提倡SQL和Java代码分离的形式,这样就可以让开发人员更加专注于自己擅长的领域
功能不够强大,比如它没有提供分页(查询大量数据的时候)、没有提供对象关联(selection关联了student,那么通过selection对象就可以访问关联的student对象,而无需使用student对象的id)、. . .等功能
总结:
JDBC Template是Spring框架对JDBC操作的封装,它简单、灵活,但不够强大。它只是在JDBC API的基础上迈出了一小步,Spring没有更大程度的去改进。当然并不是说Spring做的不好,而是Spring要留出跟多的空间给其它优秀的ORM框架。
Spring内部提供了对优秀的ORM框架的直接支持,Spring可以很轻松的集成这些框架,这些完善的ORM框架,解决了SQL与Java代码参杂、功能不够强大等问题。
所以在实际开发中,一般会与其它ORM框架(mybatis,hibernate等. . .)混合使用
SQL 语句主要可以划分为以下 3 个类别。
DDL(Data Definition Languages,数据定义语言)语句:这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create、drop、alter等。
DML(Data Manipulation Language,数据操作语言)语句:用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insert、delete、udpate 和select 等。(增添改查)
DCL(Data Control Language,数据控制语句)语句:用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 grant、revoke 等。
总结:
- DDL 是数据定义语言的缩写,简单来说,就是对数据库内部的对象进行创建、删除、修改的操作语言。它和 DML 语言的最大区别是 DML 只是对表内部数据的操作,而不涉及到表的定义、结构的修改,更不会涉及到其他对象。DDL 语句更多的被数据库管理员(DBA)所使用,一般的开发人员很少使用
https://blog.csdn.net/scbiaosdo/article/details/81561162
Spring组件之一 JDBC Template相关推荐
- Spring JDBC Template
Spring为我们提供了JDBC的模板来连接数据库,Spring JDBC Template. 使用: 第一,导入相关的jar包 第二,要连接数据库首先要加载驱动,获得连接,然后才能进行相关的数据库操 ...
- jdbc Template 介绍和 spring 链接数据源的四种方式
为什么具体讲template介绍和spring jdbc链接数据源的几种方式放在一起介绍,在于你在使用template的时候,具体配置数据源,或者在链接配置数据源的时候要是使用template,就在在 ...
- java day30【数据库连接池 、Spring JDBC : JDBC Template】
第一章 数据库连接池 1. 概念:其实就是一个容器(集合),存放数据库连接的容器. 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后 ...
- 在Spring中使用JDBC访问关系数据
在Spring中使用JDBC访问关系数据 本指南将引导您完成使用Spring访问关系数据的过程. 你会建立什么 您将构建一个使用Spring JdbcTemplate访问存储在关系数据库中的数据的应用 ...
- Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
Spring JDBC * Spring框架对JDBC的简单封装.提供了一个JDBCTemplate对象简化JDBC的开发 * 步骤: 1. 导入jar包 ...
- Spring复习日志--spring中的jdbc
Spring复习日志--spring中的jdbc xml的配置 Spring中操作数据库 jdbcTemplate的基本操作-执行简单的 执行预编译语句 执行查询的语句 模糊查询 xml的配置 < ...
- spring: 使用Spring提供的JDBC模板(使用profiles选择数据源/使用基于JDBC驱动的数据源)...
Spring提供的JDBC框架负责管理资源和异常处理,从而可以简化开发者的JDBC代码.开发者只需要编写写入和读取数据库相关的代码即可. 正如在之前的小节中论述过的,Spring将数据库访问过程中的模 ...
- Spring组件扫描context:component-scan/使用详解
1.如果不想在xml文件中配置bean,我们可以给我们的类加上spring组件注解,只需再配置下spring的扫描器就可以实现bean的自动载入. <!-- 注解注入 --> <co ...
- datastore_使用Spring Session和JDBC DataStore进行会话管理
datastore 在Web应用程序中,用户会话管理对于管理用户状态至关重要. 在本文中,我们将学习在集群环境中管理用户会话所采用的方法,以及如何使用Spring Session以更简单和可扩展的方式 ...
最新文章
- C#读取excel文件数据丢失问题
- 秒懂上线必不可少的安全测试!
- MySQL中的子查询
- LeetCode之最小路径和
- grafana mysql插件_grafana插件动态数据
- C#用户进行LDAP验证并返回员工信息
- c语言编写自动生成密码,c语言密码生成.doc
- Matlab中(),[],与{}的用法认识
- 俄罗斯互联网提供商巨头Rostelecom遭遇DDoS攻击企图
- chrome中文本框样式问题
- 未来教育计算机二级python_计算机二级题库
- 软件质量保证与测试(秦航第二版)第一章软件质量和测试的背景
- 高速PCB设计考虑的六个方面
- 五笔中比较难拆解的字
- Swift - 视频录制教程3(设置拍摄窗口大小,录制正方形视频)
- JavaScript基础第06天笔记
- 虚拟机(VMware Workstation Pro15)及系统(Windows10)安装
- python中split_python中split是什么意思
- sketch如何做设计稿交互_设计干货 | Sketch 的交互插件强势更新,再也不用为跳转的事发愁了!...
- 各种项目的源代码网站