Spring对数据库的操作使用JdbcTemplate来封装JDBC,结合Spring的注入特性可以很方便的实现对数据库的访问操作,简化JDBC的开发
步骤:
1. 导入jar包
2. 创建JdbcTemplate对象。依赖于数据源DataSource
* JdbcTemplate template = new JdbcTemplate(ds);
3. 调用JdbcTemplate的方法来完成CRUD的操作
* update():执行DML语句。增、删、改语句
* queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
注意:这个方法查询的结果集长度只能是1
* queryForList():查询结果将结果集封装为list集合
注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
* query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
* new BeanPropertyRowMapper<类型>(类型.class)
* queryForObject(sql , 返回值类型.class):查询结果,将结果封装为对象
* 一般用于聚合函数的查询
JdbcTemplate方法测试的代码实现
员工类:
package com.itheima_02.domain;
import java.util.Date;
/*
员工表
*/
public class Emp {
//成员变量
private int id;
private String ename;
private int job_id;
private int mgr;
private Date date;
private double salary;
private double bonus;
private int dept_id;
//get/set方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getJob_id() {
return job_id;
}
public void setJob_id(int job_id) {
this.job_id = job_id;
}
public int getMgr() {
return mgr;
}
public void setMgr(int mgr) {
this.mgr = mgr;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public int getDept_id() {
return dept_id;
}
public void setDept_id(int dept_id) {
this.dept_id = dept_id;
}
//toString方法
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", ename='" + ename + '\'' +
", job_id=" + job_id +
", mgr=" + mgr +
", date=" + date +
", salary=" + salary +
", bonus=" + bonus +
", dept_id=" + dept_id +
'}';
}
}
员工表:
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 员工id
ename VARCHAR(50), -- 员工姓名
job_id INT, -- 职务id
mgr INT , -- 上级领导
joindate DATE, -- 入职日期
salary DECIMAL(7,2), -- 工资
bonus DECIMAL(7,2), -- 奖金
dept_id INT, -- 所在部门编号
);
-- 添加员工
INSERT INTO
emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id)
VALUES
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
数据库:
1. 修改1号数据的 salary 为 5000
//1. 修改1号数据的 salary 为 5000
@Test
public void updateMethod(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建SQL语句
String sql = "update emp set salary = 10000 where id = 1001";
//调用update()方法,修改数据
int count = template.update(sql);
//处理结果
if(count>0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
}
结果截图:
2. 添加一条记录
//2. 添加一条记录
@Test
public void insertMethod(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建一条添加的SQL语句
String sql = "insert into emp (id,ename,dept_id)values(?,?,?)";
//调用update()方法,添加一条语句
int count = template.update(sql, 1015, "郭靖", 20);
//处理结果
if(count>0){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
}
结果截图:
3. 删除刚才添加的记录
//3. 删除刚才添加的记录
@Test
public void deleteMethod(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建一条删除语句
String sql = "delete from emp where id = 1015";
//调用update()方法,删除刚创建的语句
int count = template.update(sql);
//处理结果
if(count>0){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
}
结果截图:
4. 查询id为1的记录,将其封装为Map集合
//4. 查询id为1的记录,将其封装为Map集合
@Test
public void selectMethod(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建一条select语句
String sql = "select * from emp where id = ?";
//调用queryForMap()方法,将查询的结果封装为map集合
Map<String, Object> stringObjectMap = template.queryForMap(sql, 1001);
//打印集合
System.out.println(stringObjectMap);
}
结果截图:
5. 查询所有记录,将其封装为List
//5. 查询所有记录,将其封装为List
@Test
public void list(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建一条查询所有记录的语句
String sql = "select * from emp;";
//调用queryForList()方法,将查询到的所有记录存放到List集合中
List<Map<String, Object>> list = template.queryForList(sql);
//使用增强for遍历集合,打印输出结果集
for (Map<String, Object> stringObjectMap : list) {
System.out.println(stringObjectMap);
}
}
结果截图:
6. 查询所有记录,将其封装为Emp对象的List集合
//6. 查询所有记录,将其封装为Emp对象的List集合
@Test
public void empToList(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建一条查询所有记录的语句
String sql = "select * from emp;";
//调用query方法,将查询到的记录封装为Empty对象的List集合中
List<Emp> query = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
//增强for遍历集合,打印集合中的元素
for (Emp emp : query) {
System.out.println(emp);
}
}
结果截图:
注意:上述程序出现异常。这个时候,需要把Emp类中属性(成员变量)的基本数据类型全部改成引用类型(包装类型),把之前生成的set/get方法和toString方法删除掉,重新生成新的set/get方法和toString方法。
new BeanPropertyRowMapper<Emp>(Emp.class):此方法是通过将Emp类的字节码文件加载进内存,获取Emp类中所有(成员变量)属性名。通过获取到的(成员变量)属性名和数据库中的字段名进行匹配,如果找到属性名匹配的字段名,则将数据库中的字段名对应的值封装到Emp的成员变量中,如果(成员变量)属性名找不到匹配的字段名,则字段名使用默认值null给成员变量赋值。如果匹配不成功的成员变量是int类型的,也会将null赋值给int类型,这样一来就会产生异常,因为int类型是不能存放null值的。所以为了兼容数据库给成员变量赋值为null的这一现象,Emp类中的属性(成员变量)的数据类型要使用引用类型
运行结果截图:(这个时候程序就能正常就跑起来了)
7. 查询总记录数
//7. 查询总记录数
@Test
public void findAll(){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//创建一条查询总记录的SQL语句
String sql = "select count(id) from emp";
//调用queryForObject()方法
Long total = template.queryForObject(sql, long.class);
//打印结果
System.out.println(total);
}
结果截图:
以上是用代码演示了用JdbcTemplate中的方法完成CRUD的操作 。代码快均使用Junit单元测试,可以让方法独立执行。
总结:
(1).在使用queryForMap()方法时,其查询结果长度只能为1
(2).在使用queryForList()方法时,它是将每一条记录封装为一个Map集合,在将Map集合装在到List集合中
(3).query()方法是将查询结果封装为JavaBean对象
(4).queryForObject(sql , 返回值类型.class)方法一般用于聚合函数的查询
(5)update()方法执行DML语句(比较简单)