在文中我们将学习下手动封装JdbcTemplate,其好处是通过(sql语句+参数)模板化了编程。而真正的JdbcTemplate类,是Spring框架为我们写好的。它是 Spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。除了JdbcTemplate,spring 框架还提供了很多的操作模板类。
/*
实现类3:用于返回一个聚合函数的查询结果
*/publicclassScalarHandler<T>implementsResultSetHandler<T>{@OverridepublicLonghandler(ResultSet rs){//1.声明一个变量Long value =null;try{//2.判断是否有结果if(rs.next()){//3.获取结果集的源信息ResultSetMetaData rsmd = rs.getMetaData();//4.获取第一列的列名String columnName = rsmd.getColumnName(1);//5.根据列名获取值
value = rs.getLong(columnName);}}catch(Exception e){
e.printStackTrace();}//6.将结果返回return value;}}
JDBCTemplate类
publicclassJDBCTemplate{privateDataSource dataSource;privateConnection con;privatePreparedStatement pst;privateResultSet rs;publicJDBCTemplate(DataSource dataSource){this.dataSource = dataSource;}/*
专用于执行聚合函数sql语句的方法
*/publicLongqueryForScalar(String sql,ResultSetHandler<Long> rsh,Object...objs){Long result =null;try{
con = dataSource.getConnection();
pst = con.prepareStatement(sql);//获取sql语句中的参数源信息ParameterMetaData pData = pst.getParameterMetaData();int parameterCount = pData.getParameterCount();//判断参数个数是否一致if(parameterCount != objs.length){thrownewRuntimeException("参数个数不匹配");}//为sql语句中的?占位符赋值for(int i =0; i < objs.length; i++){
pst.setObject(i+1,objs[i]);}//执行sql语句
rs = pst.executeQuery();//通过ScalarHandler方式对结果进行处理
result = rsh.handler(rs);}catch(Exception e){
e.printStackTrace();}finally{//释放资源DataSourceUtils.close(con,pst,rs);}//将结果返回return result;}/*
专用于查询所有记录sql语句的方法
*/public<T>List<T>queryForList(String sql,ResultSetHandler<T> rsh,Object...objs){List<T> list =newArrayList<>();try{
con = dataSource.getConnection();
pst = con.prepareStatement(sql);//获取sql语句中的参数源信息ParameterMetaData pData = pst.getParameterMetaData();int parameterCount = pData.getParameterCount();//判断参数个数是否一致if(parameterCount != objs.length){thrownewRuntimeException("参数个数不匹配");}//为sql语句中的?占位符赋值for(int i =0; i < objs.length; i++){
pst.setObject(i+1,objs[i]);}//执行sql语句
rs = pst.executeQuery();//通过BeanListHandler方式对结果进行处理
list = rsh.handler(rs);}catch(Exception e){
e.printStackTrace();}finally{//释放资源DataSourceUtils.close(con,pst,rs);}//将结果返回return list;}/*
专用于执行查询一条记录sql语句的方法
*/public<T>TqueryForObject(String sql,ResultSetHandler<T> rsh,Object...objs){T obj =null;try{
con = dataSource.getConnection();
pst = con.prepareStatement(sql);//获取sql语句中的参数源信息ParameterMetaData pData = pst.getParameterMetaData();int parameterCount = pData.getParameterCount();//判断参数个数是否一致if(parameterCount != objs.length){thrownewRuntimeException("参数个数不匹配");}//为sql语句中的?占位符赋值for(int i =0; i < objs.length; i++){
pst.setObject(i+1,objs[i]);}//执行sql语句
rs = pst.executeQuery();//通过BeanHandler方式对结果进行处理
obj = rsh.handler(rs);}catch(Exception e){
e.printStackTrace();}finally{//释放资源DataSourceUtils.close(con,pst,rs);}//将结果返回return obj;}}
2.4 测试自定义JDBC框架的使用
publicclassJDBCTemplateTest{//创建JDBCTemplate对象JDBCTemplate template =newJDBCTemplate(DataSourceUtils.getDataSource());@TestpublicvoidselectScalar(){//查询student表的记录条数String sql ="SELECT COUNT(*) FROM student";Long count = template.queryForScalar(sql,newScalarHandler<Long>());System.out.println(count);}@TestpublicvoidselectAll(){//查询所有学生信息String sql ="SELECT * FROM student";List<Student> list = template.queryForList(sql,newBeanListHandler<Student>(Student.class));for(Student stu : list){System.out.println(stu);}}@TestpublicvoidselectOne(){//查询张三这条记录String sql ="SELECT * FROM student WHERE sid=?";//通过BeanHandler将结果封装成一个Student对象Student stu = template.queryForObject(sql,newBeanHandler<Student>(Student.class),1);System.out.println(stu);}@Testpublicvoidinsert(){//新增周七记录String sql ="INSERT INTO student VALUES (?,?,?,?)";Object[] params ={5,"周七",27,"2007-07-07"};int result = template.update(sql, params);System.out.println(result);}@Testpublicvoiddelete(){//删除周七这条记录String sql ="DELETE FROM student WHERE sid=?";int result = template.update(sql,5);System.out.println(result);}@Testpublicvoidupdate(){//修改张三的年龄为33String sql ="UPDATE student SET age=? WHERE name=?";Object[] params ={33,"张三"};int result = template.update(sql,params);System.out.println(result);}}