1.JdbcTemplage 概述
JdbcTemplage 位于org.springframework.jdbc.core 核心包下,最JDBC 的基本操作进行了封装,简化了JDBC 的操作流程。
2.怎样使用?
先上代码,根据代码来理解怎样使用:
(1)先注册BaseJdbc
package com.dechnic.common.core.jdbc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @description:
* @author:houqd
* @time: 2021/8/12 11:19
*/
@Component
public class BaseJdbc implements IConnection {
@Autowired
private DataSource dataSource;
@Autowired
protected JdbcTemplate jdbcTemplate;
private ThreadLocal<Connection> CONNECTION_HOLDER = new ThreadLocal<>();
@Override
public Connection getConnection() {
Connection conn = CONNECTION_HOLDER.get();
if (conn == null){
try {
conn = dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
CONNECTION_HOLDER.set(conn);
}
}
return conn;
}
@Override
public void closeConnection() {
Connection conn = CONNECTION_HOLDER.get();
if (conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
CONNECTION_HOLDER.remove();
}
}
}
}
在Spring容器里面引入dataSource,和jdbcTemplate 依赖。
(2)写测试类继承BaseJdbc
package com.dechnic.common.core.jdbc;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.*;
import org.springframework.stereotype.Component;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @description:
* @author:houqd
* @time: 2021/8/12 13:45
*/
@Component
@Scope("prototype")
public class TestJdbc extends BaseJdbc{
// 查询
public List<Map<String,Object>> getUsers(){
String sql="select * from sys_user";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
return maps;
}
//DDL 语句
public Object createTempUserTable(){
String sqlBefore = "drop table if exists AA";
String sql = "create table if not exists AA (id int(11) not null auto_increment primary key,name varchar(255) default null )";
Object o = jdbcTemplate.execute(new StatementCallback<Object>() {
@Override
public Object doInStatement(Statement stmt) throws SQLException, DataAccessException {
boolean execute1 = stmt.execute(sqlBefore);
boolean execute = stmt.execute(sql,0);
return execute;
}
});
return o;
}
// 执行insert
public void insertTempUser(){
jdbcTemplate.execute(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
String sql="insert into AA(name)value (?)";
PreparedStatement pstmt = con.prepareStatement(sql);
for (int i = 0; i < 10; i++) {
pstmt.setInt(1,i);
pstmt.addBatch();
}
return pstmt;
}
}, new PreparedStatementCallback<Object>() {
@Override
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
return ps.executeBatch();
}
});
}
// 执行 update
public void updateTempUser(){
String sql = "update AA set name = ? where id=?";
Object[] args=new Object[2];
args[0] = "test";
args[1]= 1;
int[] argTypes = {Types.VARCHAR,Types.INTEGER};
jdbcTemplate.update(sql,args,argTypes);
}
// 调用存储过程
public void invokeProc(){
// String sql = "call temp_findById (1)";
// jdbcTemplate.execute(sql);
jdbcTemplate.execute(new CallableStatementCreator() {
@Override
public CallableStatement createCallableStatement(Connection con) throws SQLException {
String proc = "{call temp_findById(?)}";
CallableStatement cs = con.prepareCall(proc);
cs.setInt(1,1);
return cs;
}
}, new CallableStatementCallback<List<TestU>>() {
@Override
public List<TestU> doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
cs.execute();
ResultSet resultSet = cs.getResultSet();
List<TestU> list = new ArrayList<>();
if (resultSet!=null){
RowMapper<TestU> rowMapper = new BeanPropertyRowMapper<TestU>(TestU.class);
int rowNum =1;
while (resultSet.next()){
list.add(rowMapper.mapRow(resultSet,rowNum++));
}
}
return list;
}
});
}
public void invokeProc2(){
jdbcTemplate.execute(new CallableStatementCreator() {
@Override
public CallableStatement createCallableStatement(Connection con) throws SQLException {
CallableStatement cs = con.prepareCall("{call temp_findById(?)}");
cs.setInt(1,1);
return cs;
}
}, new CallableStatementCallback<List<Map<String,Object>>>() {
@Override
public List<Map<String,Object>> doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
cs.execute();
ResultSet resultSet = cs.getResultSet();
List<Map<String,Object>> list = new ArrayList<>();
int rowNum =1;
if (resultSet!=null){
while (resultSet.next()){
Map<String,Object> map = new HashMap<>();
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
map.put("id",id);
map.put("name",name);
}
}
return list;
}
});
}
}
其中mysql 数据库中的存储过程为:
AA 表为:
3.总结:
JdbcTemplate主要提供以下五类方法:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法及queryForXXX方法:用于执行查询相关语句;
call方法:用于执行存储过程、函数相关语句。
JdbcTemplate类支持的回调类:
预编译语句及存储过程创建回调:用于根据JdbcTemplate提供的连接创建相应的语句;
PreparedStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的PreparedStatement;
CallableStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的CallableStatement;
预编译语句设值回调:用于给预编译语句相应参数设值;
PreparedStatementSetter:通过回调获取JdbcTemplate提供的PreparedStatement,由用户来对相应的预编译语句相应参数设值;
BatchPreparedStatementSetter:;类似于PreparedStatementSetter,但用于批处理,需要指定批处理大小;
自定义功能回调:提供给用户一个扩展点,用户可以在指定类型的扩展点执行任何数量需要的操作;
ConnectionCallback:通过回调获取JdbcTemplate提供的Connection,用户可在该Connection执行任何数量的操作;
StatementCallback:通过回调获取JdbcTemplate提供的Statement,用户可以在该Statement执行任何数量的操作;
PreparedStatementCallback:通过回调获取JdbcTemplate提供的PreparedStatement,用户可以在该PreparedStatement执行任何数量的操作;
CallableStatementCallback:通过回调获取JdbcTemplate提供的CallableStatement,用户可以在该CallableStatement执行任何数量的操作;
结果集处理回调:通过回调处理ResultSet或将ResultSet转换为需要的形式;
RowMapper:用于将结果集每行数据转换为需要的类型,用户需实现方法mapRow(ResultSet rs, int rowNum)来完成将每行数据转换为相应的类型。
RowCallbackHandler:用于处理ResultSet的每一行结果,用户需实现方法processRow(ResultSet rs)来完成处理,在该回调方法中无需执行rs.next(),该操作由JdbcTemplate来执行,用户只需按行获取数据然后处理即可。
ResultSetExtractor:用于结果集数据提取,用户需实现方法extractData(ResultSet rs)来处理结果集,用户必须处理整个结果集;