JDBCtemplate的实际操作,解决案例
2018/8/12
今天的学习是深入学习JDBCtemplate的许多方法,对昨天的入门进行巩固,写了一些案例和案例中的问题
JDBCTemplate入门:
- Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
- 步骤:
-
导入jar包
链接:https://pan.baidu.com/s/1Zat5PRdg_Fd3fTxRp7XKPA
提取码:nnda -
创建JdbcTemplate对象。依赖于数据源DataSource
- JdbcTemplate template = new JdbcTemplate(ds);
-
调用JdbcTemplate的方法来完成CRUD的操作
-
- 步骤:
update():执行DML语句。增、删、改语句
queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
*注意:这个方法查询的结果集长度只能是1queryForList():查询结果将结果集封装为list集合
*注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
* new BeanPropertyRowMapper<类型>(类型.class)queryForObject:查询结果,将结果封装为对象
*一般用于聚合函数的查询
案例及问题:
需求:
1.修改id为1 的密码possword为zsczsc
2.添加一条记录
3.删除刚才添加的记录
4.查询id为1的记录,将其封装为map集合
5.查询所有记录,将其封装为list集合
6.查询所有记录,就其封装为studentTable1对象的list集合
7.查询记录总数
前三个方法是使用jdbctemplate的upadte方法执行DML语句
1.修改id为1 的密码possword为zsczsc
代码如下:
//Junit单元测试,可以让方法独立去执行
//前三个方法是使用jdbctemplate的upadte方法执行DML语句
/***
* 1.修改id为1 的密码possword为zsczsc
*/
//获取jdbctemplate对象(将template放在成员变量中所以不需要在每个方法中重新获取jdbctemplate对象)
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getdatasource());
@Test
public void test1(){
//1.创建修改的sql命令
String sql="update studentTable1 set possword=? where id=?";
//2.执行sql命令(调用jdbctemplat的update方法参数就是sql命令)
int i = template.update(sql,"zsc",1);
//3.打印受影响的行数
System.out.println(i);
}
这里的类为测试类使用了@Test注解,这样的方式可以使得方法直接运不需要依赖主类,可以在百度搜索Junit单元测试来详细了解。
2.添加一条记录
代码如下
/***
* * 2.添加一条只有用户名密码为空的数据
*/
@Test
public void test2(){
//1创建添加的sql命令(添加一行数据只有用户名没有密码)
String sql="insert into studentTable1(name) values (?)";
//2执行sql命令
int i = template.update(sql, "1234");
//3打印受影响的行数
System.out.println(i);
}
3.删除刚才添加的记录
代码如下
/***
* * 3.删除刚才添加的记录
*/
@Test
public void test3(){
//1.创建删除的sql命令
String sql="delete from studentTable1 where name=? ";
//2.执行sql命令
int i = template.update(sql, "1234");
//3.打印受影响的行数
System.out.println(i);
}
后四个方法是使用jdbctemplate的query方法执行DQl语句
4.查询id为1的记录,将其封装为map集合
代码如下
/***
* * 4.查询id为1的记录,将其封装为map集合
*/
@Test
public void test4(){
//1.创建查询id为1 的sql命令
String sql="select * from studentTable1 where id=?";
//2.执行sql命令,并且将结果封装成map集合,使用jdbctemplate的queryForMap方法
Map<String, Object> map1 = template.queryForMap(sql, 1);
//3.打印结果集
System.out.println(map1);
//结果为:{id=1, name=zsc1, possword=zsc}
/*注意:如果当查询语句查询两条记录时是不能封装进一个map集合的,
只能查询一条记录并且封装map集合 String sql="select * from studentTable1 where id=? or id=?";
queryForMap方法查询的结果集长度只能为1*/
}
5.查询所有记录,将其封装为list集合
代码如下
/***
* * 5.查询所有记录,将其封装为list集合
*/
@Test
public void test5(){
//1.创建sql命令查询所有的记录
String sql="select * from studentTable1";
//2.执行sql命令,调用jdbctemplate的queryForList方法,该方法先将没一条记录封装为map集合,然后将map集合封装为list集合
List<Map<String, Object>> mapList = template.queryForList(sql);
//3.遍历list集合
for (Map<String, Object> stringObjectMap : mapList) {
System.out.println(stringObjectMap);
}
}
6.1查询所有记录,就其封装为studentTable1对象的list集合
(自己实现RowMapper<数据库类>接口)
/***
* * 6.1查询所有记录,就其封装为studentTable1对象的list集合
* 自己实现RowMapper<studentTable1>接口
*/
@Test
public void test6_1(){
//1.创建sql命令,查询所有记录
String sql="select * from studentTable1";
//2.执行sql命令(自己实现RowMapper<studentTable1>接口)
List<studentTable1> list = template.query(sql, new RowMapper<studentTable1>() {
@Override
public studentTable1 mapRow(ResultSet rs, int i) throws SQLException {
//1从数据库获取数据
int id = rs.getInt("id");
String name = rs.getString("name");
String possword = rs.getString("possword");
//2创建studentTable1对象,并赋值
studentTable1 studentTable1 = new studentTable1();
studentTable1.setId(id);
studentTable1.setName(name);
studentTable1.setPossword(possword);
//3返回装载进list集合
return studentTable1;
}
});
//3.遍历list集合
for (studentTable1 studentTable1 : list) {
System.out.println(studentTable1);
}
}
此时你会发现这样的方法并不方便,没有什么简单的地方,还是要靠自己实现RowMapper<数据库类> 接口,所以为了否报jdbctemplate提供了已经实现的接口BeanPropertyRowMapper<类型>(类型.class)
6.2查询所有记录,就其封装为studentTable1对象的list集合
( 通过jdbctemplate提供的BeanPropertyRowMapper已经实现RowMapper接口 去完成操作)
代码如下
/***
* * 6.2查询所有记录,就其封装为studentTable1对象的list集合
* 通过jdbctemplate提供的BeanPropertyRowMapper已经实现RowMapper<studentTable1>接口
*/
@Test
public void test6_2(){
//1.创建sql命令,查询所有记录
String sql="select * from studentTable1";
/*2.执行sql命令(通过jdbctemplate提供的BeanPropertyRowMapper<类型>(类型.class)参数为studentTable1的字节码文件,
去实现RowMapper<studentTable1>接口,)*/
/*注意如果使用jdbctemplate提供的对象BeanPropertyRowMapper,在studentTable1类中中定义时不能使用基本数据类型如int,double等等,
要使用引用数据类型如Integer,Double等等*/
List<studentTable1> list = template.query(sql, new BeanPropertyRowMapper<studentTable1>(studentTable1.class));
//3.遍历list集合
for (studentTable1 studentTable1 : list) {
System.out.println(studentTable1);
}
}
注意:1.通过jdbctemplate提供的BeanPropertyRowMapper<类型>(类型.class)参数为studentTable1的字节码文件,
去实现RowMapper<类型>接口
2.注意如果使用jdbctemplate提供的对象BeanPropertyRowMapper,在studentTable1类中中定义时不能使用基本数据类型如int,double等等,
要使用引用数据类型如Integer,Double等等
7.查询记录总数
代码如下
/***
* * 7.查询记录总数
*/
@Test
public void test7(){
//1.创建sql命令查询总记录数
String sql="select count(id) from studentTable1";
//2.执行sql命令
Long count = template.queryForObject(sql, long.class);
//打印记录数
System.out.println(count);
}
注意在使用queryForObject(sql,记录总数类型.class)方法时,参数为sql命令执行后返回的记录总数的类型的字节码文件。
测试类的完整代码
如下:
package cn.itcat.JDBCTemplate;
import cn.itcat.datasource.utils.JDBCUtils;
import cn.itcat.templateDO.studentTable1;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
/***
* 测试类(使用JDBCtemplate对数据库的操作)使用Junit单元测试
* 需求:
* 1.修改id为1 的密码possword为zsczsc
* 2.添加一条记录
* 3.删除刚才添加的记录
* 4.查询id为1的记录,将其封装为map集合
* 5.查询所有记录,将其封装为list集合
* 6.查询所有记录,就其封装为studentTable1对象的list集合
* 7.查询记录总数
*/
public class JDBCTemplateDemo2 {
//Junit单元测试,可以让方法独立去执行
//前三个方法是使用jdbctemplate的upadte方法执行DML语句
/***
* 1.修改id为1 的密码possword为zsczsc
*/
//获取jdbctemplate对象(将template放在成员变量中所以不需要在每个方法中重新获取jdbctemplate对象)
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getdatasource());
@Test
public void test1(){
//1.创建修改的sql命令
String sql="update studentTable1 set possword=? where id=?";
//2.执行sql命令(调用jdbctemplat的update方法参数就是sql命令)
int i = template.update(sql,"zsc",1);
//3.打印受影响的行数
System.out.println(i);
}
/***
* * 2.添加一条只有用户名密码为空的数据
*/
@Test
public void test2(){
//1创建添加的sql命令(添加一行数据只有用户名没有密码)
String sql="insert into studentTable1(name) values (?)";
//2执行sql命令
int i = template.update(sql, "1234");
//3打印受影响的行数
System.out.println(i);
}
/***
* * 3.删除刚才添加的记录
*/
@Test
public void test3(){
//1.创建删除的sql命令
String sql="delete from studentTable1 where name=? ";
//2.执行sql命令
int i = template.update(sql, "1234");
//3.打印受影响的行数
System.out.println(i);
}
//后四个方法是使用jdbctemplate的query方法执行DQl语句
/***
* * 4.查询id为1的记录,将其封装为map集合
*/
@Test
public void test4(){
//1.创建查询id为1 的sql命令
String sql="select * from studentTable1 where id=?";
//2.执行sql命令,并且将结果封装成map集合,使用jdbctemplate的queryForMap方法
Map<String, Object> map1 = template.queryForMap(sql, 1);
//3.打印结果集
System.out.println(map1);
//结果为:{id=1, name=zsc1, possword=zsc}
/*注意:如果当查询语句查询两条记录时是不能封装进一个map集合的,
只能查询一条记录并且封装map集合 String sql="select * from studentTable1 where id=? or id=?";
queryForMap方法查询的结果集长度只能为1*/
}
/***
* * 5.查询所有记录,将其封装为list集合
*/
@Test
public void test5(){
//1.创建sql命令查询所有的记录
String sql="select * from studentTable1";
//2.执行sql命令,调用jdbctemplate的queryForList方法,该方法先将没一条记录封装为map集合,然后将map集合封装为list集合
List<Map<String, Object>> mapList = template.queryForList(sql);
//3.遍历list集合
for (Map<String, Object> stringObjectMap : mapList) {
System.out.println(stringObjectMap);
}
}
/***
* * 6.1查询所有记录,就其封装为studentTable1对象的list集合
* 自己实现RowMapper<studentTable1>接口
*/
@Test
public void test6_1(){
//1.创建sql命令,查询所有记录
String sql="select * from studentTable1";
//2.执行sql命令(自己实现RowMapper<studentTable1>接口)
List<studentTable1> list = template.query(sql, new RowMapper<studentTable1>() {
@Override
public studentTable1 mapRow(ResultSet rs, int i) throws SQLException {
//1从数据库获取数据
int id = rs.getInt("id");
String name = rs.getString("name");
String possword = rs.getString("possword");
//2创建studentTable1对象,并赋值
studentTable1 studentTable1 = new studentTable1();
studentTable1.setId(id);
studentTable1.setName(name);
studentTable1.setPossword(possword);
//3返回装载进list集合
return studentTable1;
}
});
//3.遍历list集合
for (studentTable1 studentTable1 : list) {
System.out.println(studentTable1);
}
}
/***
* * 6.2查询所有记录,就其封装为studentTable1对象的list集合
* 通过jdbctemplate提供的BeanPropertyRowMapper去实现RowMapper<studentTable1>接口
*/
@Test
public void test6_2(){
//1.创建sql命令,查询所有记录
String sql="select * from studentTable1";
/*2.执行sql命令(通过jdbctemplate提供的BeanPropertyRowMapper<类型>(类型.class)参数为studentTable1的字节码文件,
去实现RowMapper<studentTable1>接口,)*/
/*注意如果使用jdbctemplate提供的对象BeanPropertyRowMapper,在studentTable1类中中定义时不能使用基本数据类型如int,double等等,
要使用引用数据类型如Integer,Double等等*/
List<studentTable1> list = template.query(sql, new BeanPropertyRowMapper<studentTable1>(studentTable1.class));
//3.遍历list集合
for (studentTable1 studentTable1 : list) {
System.out.println(studentTable1);
}
}
/***
* * 7.查询记录总数
*/
@Test
public void test7(){
//1.创建sql命令查询总记录数
String sql="select count(id) from studentTable1";
//2.执行sql命令
Long count = template.queryForObject(sql, long.class);
//打印记录数
System.out.println(count);
}
}
JDBCUtils工具类
代码如下
package cn.itcat.datasource.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/***
* Druid连接池工具类
*/
//1.定义一个工具类JDBCUtils
public class JDBCUtils {
//2.创建连接池连接配置文件静态代码块
public static DataSource ds;
static {
try {
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
ds= DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//3.提供方法
/***
* 获取连接的方法
*/
public static Connection getconnection() throws SQLException {
return ds.getConnection();
}
/***
* 释放资源的方法
*/
public static void close(ResultSet rs,Statement st,Connection con){
if (rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (st!=null){
try {
st.close();
/*Statement 对象将由 Java 垃圾收集程序自动关闭。
而作为一种好的编程风格,应在不需要 Statement对象时显式地关闭它们。
这将立即释放 DBMS 资源,有助于避免潜在的内存问题。*/
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (con!=null){
try {
con.close(); //归还连接回连接池
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/***
* 获取连接池的方法
*/
public static DataSource getdatasource(){
return ds;
}
}
studentTable1数据库对象类
代码如下
package cn.itcat.templateDO;
public class studentTable1 {
private Integer id;
private String name;
private String possword;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPossword() {
return possword;
}
public void setPossword(String possword) {
this.possword = possword;
}
@Override
public String toString() {
return "studentTable1{" +
"id=" + id +
", name='" + name + '\'' +
", possword='" + possword + '\'' +
'}';
}
}
好处:
简化代码量
使用方便
不需要手动归还连接和创建连接