框架编写
package com.itheima05;
import com.itheima.utils.DataSourceUtils;
import javax.sql.DataSource;
import java.sql.*;
public class JDBCTemplate {
/// 定义参数变量(数据源,连接对象,执行者对象,结果集对象)
private DataSource dataSource;
private Connection connection;
private PreparedStatement preparedStatement;
private ResultSet resultSet;
/// 有参构造方法为数据源赋值
public JDBCTemplate(DataSource dataSource)
{
this.dataSource=dataSource;
}
/// 定义update,参数sql语句,sql语句中的参数
public int update(String sql,Object...objects)
{
///定义int类型变量,用于接收增删改后影响的行数
int result =0;
try {
connection=dataSource.getConnection();
/// 通过连接对象获取执行者对象,并对sql语句进行预编译
preparedStatement = connection.prepareStatement(sql);
/// 执行者对象获取源信息的对象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
int count = parameterMetaData.getParameterCount();
/// 判断参数数量是否一致
if(count!=objects.length)
{
throw new RuntimeException("参数个数不匹配");
}
/// 为sql语句占位符赋值
for (int i=0;i<objects.length;i++)
{
preparedStatement.setObject(i+1,objects[i]);
}
///执行sql语句
result=preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DataSourceUtils.close(connection,preparedStatement);
}
return result;
}
}
查询功能
package com.itheima05.handler;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Locale;
/*
实现类:用于将查询到的一条记录,封装为Student对象并返回
*/
public class BeanHandler<T> implements ResultSetHandler<T>{
/// 定义Class对象类型变量
private Class<T> beanClass;
/// 通过有参构造为变量赋值
public BeanHandler(Class<T> beanClass)
{
this.beanClass =beanClass;
}
//重写handler方法,用来将一条记录封装到自定义对象中
@Override
public T handler(ResultSet resultSetHandler) {
///声明自定义对象类型
T bean =null;
try {
/// 创建传递参数的对象,为自定义对象赋值
bean=beanClass.newInstance();
/// 判断结果集中是否有数据
if(resultSetHandler.next())
{
/// 通过结果集对象获取结果集源信息的对象
ResultSetMetaData metaData = resultSetHandler.getMetaData();
// 通过结果集源信息对象获取烈数
int columnCount = metaData.getColumnCount();
/// 通过循环遍历列数
for (int i=1;i<=columnCount;i++)
{
/// 通过结果集源信息对象获取列名
String columnName =metaData.getColumnName(i);
/// 通过列名获取该列的数据
Object value = resultSetHandler.getObject(columnName);
/// 创建属性描述器对象,将获取到的值通过该对象的set方法进行赋值
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName.toLowerCase(Locale.ROOT),beanClass);
///获取set方法
Method writeMethod =propertyDescriptor.getWriteMethod();
/// 执行set方法,给对应执行对象进行赋值
writeMethod.invoke(bean,value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
/// 返回封装好的对象
return bean;
}
}
package com.itheima05.handler;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/*
实现类:用于将查询到的多条记录,封装为Student对象并返回
*/
public class BeanListHandler<T> implements ResultSetHandler<T>{
/// 定义Class对象类型变量
private Class<T> beanClass;
/// 通过有参构造为变量赋值
public BeanListHandler(Class<T> beanClass)
{
this.beanClass =beanClass;
}
//重写handler方法,用来将多条记录封装到自定义对象中并添加集合返回
@Override
public List<T> handler(ResultSet resultSetHandler) {
///声明集合对象类型
List<T> list = new ArrayList<>();
try {
/// 判断结果集中是否有数据
while (resultSetHandler.next())
{
/// 创建传递参数的对象,为自定义对象赋值
T bean=beanClass.newInstance();
/// 通过结果集对象获取结果集源信息的对象
ResultSetMetaData metaData = resultSetHandler.getMetaData();
// 通过结果集源信息对象获取烈数
int columnCount = metaData.getColumnCount();
/// 通过循环遍历列数
for (int i=1;i<=columnCount;i++)
{
/// 通过结果集源信息对象获取列名
String columnName =metaData.getColumnName(i);
/// 通过列名获取该列的数据
Object value = resultSetHandler.getObject(columnName);
/// 创建属性描述器对象,将获取到的值通过该对象的set方法进行赋值
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName.toLowerCase(Locale.ROOT),beanClass);
///获取set方法
Method writeMethod =propertyDescriptor.getWriteMethod();
/// 执行set方法,给对应执行对象进行赋值
writeMethod.invoke(bean,value);
}
/// 将对象保存到集合中
list.add(bean);
}
} catch (Exception e) {
e.printStackTrace();
}
/// 返回封装好的对象
return list;
}
}
package com.itheima05.handler;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class ScalarHandler<T> implements ResultSetHandler<T>{
@Override
public Long handler(ResultSet resultSet) {
/// 定义一个long类型的变量
Long value = null;
try {
if(resultSet.next())
{
/// 获取结果集源信息的对象
ResultSetMetaData metaData = resultSet.getMetaData();
/// 获取第一列的列名
String columnName= metaData.getColumnName(1);
value = resultSet.getLong(columnName);
}
} catch (SQLException e) {
e.printStackTrace();
}
return value;
}
}
核心代码
package com.itheima05;
import com.itheima.utils.DataSourceUtils;
import com.itheima05.handler.ResultSetHandler;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class JDBCTemplate {
/// 定义参数变量(数据源,连接对象,执行者对象,结果集对象)
private DataSource dataSource;
private Connection connection;
private PreparedStatement preparedStatement;
private ResultSet resultSet;
/// 有参构造方法为数据源赋值
public JDBCTemplate(DataSource dataSource)
{
this.dataSource=dataSource;
}
/*
查询方法 用于将聚合函数进行返回
*/
public Long queryForScalar(String sql, ResultSetHandler<Long> resultSetHandler, Object...objects)
{
///定义int类型变量,用于接收增删改后影响的行数
Long value =null;
try {
connection=dataSource.getConnection();
/// 通过连接对象获取执行者对象,并对sql语句进行预编译
preparedStatement = connection.prepareStatement(sql);
/// 执行者对象获取源信息的对象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
int count = parameterMetaData.getParameterCount();
/// 判断参数数量是否一致
if(count!=objects.length)
{
throw new RuntimeException("参数个数不匹配");
}
/// 为sql语句占位符赋值
for (int i=0;i<objects.length;i++)
{
preparedStatement.setObject(i+1,objects[i]);
}
///执行sql语句
resultSet= preparedStatement.executeQuery();
/// 通过ScalarHandler方式对结果进行处理
value = resultSetHandler.handler(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DataSourceUtils.close(connection,preparedStatement,resultSet);
}
return value;
}
/*
查询方法 用于将多条记录封装成自定义对象并返回
*/
public <T> List<T> queryForList(String sql, ResultSetHandler<T> resultSetHandler, Object...objects)
{
///定义int类型变量,用于接收增删改后影响的行数
List<T> list= new ArrayList<>();
try {
connection=dataSource.getConnection();
/// 通过连接对象获取执行者对象,并对sql语句进行预编译
preparedStatement = connection.prepareStatement(sql);
/// 执行者对象获取源信息的对象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
int count = parameterMetaData.getParameterCount();
/// 判断参数数量是否一致
if(count!=objects.length)
{
throw new RuntimeException("参数个数不匹配");
}
/// 为sql语句占位符赋值
for (int i=0;i<objects.length;i++)
{
preparedStatement.setObject(i+1,objects[i]);
}
///执行sql语句
resultSet= preparedStatement.executeQuery();
/// 通过BeanListHandler方式对结果进行处理
list = resultSetHandler.handler(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DataSourceUtils.close(connection,preparedStatement,resultSet);
}
return list;
}
/*
查询方法 用于将一条记录封装成自定义对象并返回
*/
public <T> T queryForObject(String sql, ResultSetHandler<T> resultSetHandler,Object...objects)
{
///定义int类型变量,用于接收增删改后影响的行数
T obj=null;
try {
connection=dataSource.getConnection();
/// 通过连接对象获取执行者对象,并对sql语句进行预编译
preparedStatement = connection.prepareStatement(sql);
/// 执行者对象获取源信息的对象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
int count = parameterMetaData.getParameterCount();
/// 判断参数数量是否一致
if(count!=objects.length)
{
throw new RuntimeException("参数个数不匹配");
}
/// 为sql语句占位符赋值
for (int i=0;i<objects.length;i++)
{
preparedStatement.setObject(i+1,objects[i]);
}
///执行sql语句
resultSet= preparedStatement.executeQuery();
/// 通过BeanHandler方式对结果进行处理
obj = resultSetHandler.handler(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DataSourceUtils.close(connection,preparedStatement,resultSet);
}
return obj;
}
/// 定义update,参数sql语句,sql语句中的参数
public int update(String sql,Object...objects)
{
///定义int类型变量,用于接收增删改后影响的行数
int result =0;
try {
connection=dataSource.getConnection();
/// 通过连接对象获取执行者对象,并对sql语句进行预编译
preparedStatement = connection.prepareStatement(sql);
/// 执行者对象获取源信息的对象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
int count = parameterMetaData.getParameterCount();
/// 判断参数数量是否一致
if(count!=objects.length)
{
throw new RuntimeException("参数个数不匹配");
}
/// 为sql语句占位符赋值
for (int i=0;i<objects.length;i++)
{
preparedStatement.setObject(i+1,objects[i]);
}
///执行sql语句
result=preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DataSourceUtils.close(connection,preparedStatement);
}
return result;
}
}
测试代码
package com.itheima05;
import com.itheima.utils.DataSourceUtils;
import com.itheima05.domain.Student;
import com.itheima05.handler.BeanHandler;
import com.itheima05.handler.BeanListHandler;
import com.itheima05.handler.ScalarHandler;
import org.junit.Test;
import java.util.List;
/*
模拟dao层
*/
public class JDBCTemplate1 {
private JDBCTemplate template = new JDBCTemplate(DataSourceUtils.getDataSource());
@Test
public void queryForScalar()
{
String sql = "select count(*) from student";
Long aLong =template.queryForScalar(sql,new ScalarHandler<>());
System.out.println(aLong);
}
@Test
public void queryForList()
{
String sql = "select * from student";
List<Student> list =template.queryForList(sql,new BeanListHandler<>(Student.class));
for (Student student:list)
{
System.out.println(student);
}
}
@Test
public void queryForObject()
{
String sql = "select * from student where sid =?";
Student student=template.queryForObject(sql,new BeanHandler<>(Student.class),1);
System.out.println(student);
}
@Test
public void delete()
{
/// 输出数据的测试
String sql = "delete from student where name=?";
int result = template.update(sql,"周七");
}
@Test
public void update()
{
/// 修改数据的测试
String sql = "update student set age=? where name=?";
Object[] objects ={34,"周七"};
int result = template.update(sql,objects);
System.out.println(result);
}
@Test
public void insert()
{
String sql ="insert into student values(?,?,?,?)";
Object[] objects = {5,"周七",27,"1997-07-07"};
int update = template.update(sql, objects);
if(update!=0)
{
System.out.println("添加成功");
}
else
{
System.out.println("添加失败");
}
}
}