JDBC自定义框架

自定义JDBC框架:

定义必要的信息、获取数据库的连接、释放资源都是重复的代码,在操作JDBC时通常都是执行SQL语句就可以了,所以需要抽取出来一个模板类来封装一些方法(Update、Query),专门执行增删改查的SQL语句,简化使用步骤。

DataBaseMetaData:数据库的源信息
  • java.sql.DataBaseMetaData:封装了整个数据库的综合信息

例如:

  • String getDatabaseProductName():获取数据库产品的名称
  • int getDatabaseProductVersion():获取数据库产品的版本号
ParameterMetaData:参数的源信息
  • java.sql.ParameterMetaData:封装的是预编译执行者对象中每个参数的类型和属性
  • 这个对象可以通过预编译执行者对象中的getParameterMetaData()方法来获取

核心功能:

int getParameterCount():获取sql语句中参数的个数

ResultSetMetaData:结果集的源信息

java.sql.ResultSetMetaData:封装的是结果集对象中列的类型和属性
这个对象可以通过结果集对象中的getMetaData()方法来获取

核心功能:

  • int getColumnCount():获取列的总数
  • String getColumnName(int i):获取列名
查询的方法:
  • 查询一条记录并封装对象的方法:queryForObject()
  • 查询多条记录并封装到集合的方法:queryForList()
  • 查询聚合函数并返回单条数据的方法:queryForScalar()
JDBCTemplate类增删改功能的编写
public class JDBCTemplate {// 1. 定义参数变量:数据源、连接对象、执行者对象、结果集对象private DataSource dataSource;private Connection connection;private PreparedStatement ps;private ResultSet resultSet;// 2. 通过有参构造为数据赋值public JDBCTemplate(DataSource dataSource) {this.dataSource = dataSource;}// 3. 定义Update方法,参数:sql语句、sql语句中的参数public int update(String sql, Object... objects) {// 4. 定义int变量,用于接收增删改后影响的行数int result = 0;try {// 5. 通过数据获取一个数据库连接connection = dataSource.getConnection();// 6. 通过数据库连接对象获取执行者对象,并对sql语句进行预编译ps = connection.prepareStatement(sql);// 7. 通过执行者对象获取参数的源信息对象ParameterMetaData parameterMetaData = ps.getParameterMetaData();// 8. 通过参数源信息对象获取参数的个数int count = parameterMetaData.getParameterCount();// 9. 判断参数数量是否一致if (count != objects.length) {throw new RuntimeException("参数个数不匹配");}// 10. 为sql语句占位符赋值for (int i = 0; i < objects.length; i++) {ps.setObject(i + 1, objects[i]);}// 11. 执行sql语句并接收结果result = ps.executeUpdate();} catch (SQLException sqlException) {sqlException.printStackTrace();} finally {// 12. 释放资源DataSourceUtils.close(connection, ps);}// 13. 返回结果return result;}
}
JDBCTemplate类查询功能的编写:
  • 实体类
/*学生实体类*/
public class Student {private Integer sid;private String name;private Integer age;private Date birthday;public Student() {}public Student(Integer sid, String name, Integer age, Date birthday) {this.sid = sid;this.name = name;this.age = age;this.birthday = birthday;}public Integer getSid() {return sid;}public void setSid(Integer sid) {this.sid = sid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "Student{" +"sid=" + sid +", name='" + name + '\'' +", age=" + age +", birthday=" + birthday +'}';}
}
  • ResultSetHandler接口
/*用于处理结果集的接口*/
public interface ResultSetHandler<T> {//处理结果集的抽象方法。<T> T handler(ResultSet rs);
}
  • BeanHandler实现类
/*实现类1:用于完成将查询出来的一条记录,封装到Student对象中*/
public class BeanHandler<T> implements ResultSetHandler<T> {//1.声明对象类型变量private Class<T> beanClass;//2.有参构造对变量赋值public BeanHandler(Class<T> beanClass) {this.beanClass = beanClass;}/*将ResultSet结果集中的数据封装到beanClass类型对象中*/@Overridepublic T handler(ResultSet rs) {//3.声明对象T bean = null;try{//4.创建传递参数的对象bean = beanClass.newInstance();//5.判断是否有结果集if(rs.next()) {//6.得到所有的列名//6.1先得到结果集的源信息ResultSetMetaData rsmd = rs.getMetaData();//6.2还要得到有多少列int columnCount = rsmd.getColumnCount();//6.3遍历列数for(int i = 1; i <= columnCount; i++) {//6.4得到每列的列名String columnName = rsmd.getColumnName(i);//6.5通过列名获取数据Object columnValue = rs.getObject(columnName);//6.6列名其实就是对象中成员变量的名称。于是就可以使用列名得到对象中属性的描述器(get和set方法)PropertyDescriptor pd = new PropertyDescriptor(columnName.toLowerCase(),beanClass);//6.7获取set方法Method writeMethod = pd.getWriteMethod();//6.8执行set方法,给成员变量赋值writeMethod.invoke(bean,columnValue);}}} catch (Exception e) {e.printStackTrace();}//7.将对象返回return bean;}
}
  • BeanListHandler实现类
/*实现类2:用于将结果集封装到集合中*/
public class BeanListHandler<T> implements ResultSetHandler<T> {//1.声明对象变量private Class<T> beanClass;//2.有参构造为变量赋值public BeanListHandler(Class<T> beanClass) {this.beanClass = beanClass;}@Overridepublic List<T> handler(ResultSet rs) {//3.创建集合对象List<T> list = new ArrayList<>();try{//4.遍历结果集对象while(rs.next()) {//5.创建传递参数的对象T bean = beanClass.newInstance();//6.得到所有的列名//6.1先得到结果集的源信息ResultSetMetaData rsmd = rs.getMetaData();//6.2还要得到有多少列int columnCount = rsmd.getColumnCount();//6.3遍历列数for(int i = 1; i <= columnCount; i++) {//6.4得到每列的列名String columnName = rsmd.getColumnName(i);//6.5通过列名获取数据Object columnValue = rs.getObject(columnName);//6.6列名其实就是对象中成员变量的名称。于是就可以使用列名得到对象中属性的描述器(get和set方法)PropertyDescriptor pd = new PropertyDescriptor(columnName.toLowerCase(),beanClass);//6.7获取set方法Method writeMethod = pd.getWriteMethod();//6.8执行set方法,给成员变量赋值writeMethod.invoke(bean,columnValue);}//7.将对象保存到集合中list.add(bean);}} catch (Exception e) {e.printStackTrace();}//8.返回结果return list;}
}
  • ScalarHandler实现类
/*实现类3:用于返回一个聚合函数的查询结果*/
public class ScalarHandler<T> implements ResultSetHandler<T> {@Overridepublic Long handler(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类
public class JDBCTemplate {private DataSource dataSource;private Connection con;private PreparedStatement pst;private ResultSet rs;public JDBCTemplate(DataSource dataSource) {this.dataSource = dataSource;}/*专用于执行聚合函数sql语句的方法*/public Long queryForScalar(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) {throw new RuntimeException("参数个数不匹配");}//为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 = new ArrayList<>();try{con = dataSource.getConnection();pst = con.prepareStatement(sql);//获取sql语句中的参数源信息ParameterMetaData pData = pst.getParameterMetaData();int parameterCount = pData.getParameterCount();//判断参数个数是否一致if(parameterCount != objs.length) {throw new RuntimeException("参数个数不匹配");}//为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> T queryForObject(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) {throw new RuntimeException("参数个数不匹配");}//为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;}
}
测试自定义JDBC框架的使用:
public class JDBCTemplateTest {//创建JDBCTemplate对象JDBCTemplate template = new JDBCTemplate(DataSourceUtils.getDataSource());@Testpublic void selectScalar() {//查询student表的记录条数String sql = "SELECT COUNT(*) FROM student";Long count = template.queryForScalar(sql, new ScalarHandler<Long>());System.out.println(count);}@Testpublic void selectAll() {//查询所有学生信息String sql = "SELECT * FROM student";List<Student> list = template.queryForList(sql, new BeanListHandler<Student>(Student.class));for(Student stu : list) {System.out.println(stu);}}@Testpublic void selectOne() {//查询张三这条记录String sql = "SELECT * FROM student WHERE sid=?";//通过BeanHandler将结果封装成一个Student对象Student stu = template.queryForObject(sql, new BeanHandler<Student>(Student.class), 1);System.out.println(stu);}@Testpublic void insert() {//新增周七记录String sql = "INSERT INTO student VALUES (?,?,?,?)";Object[] params = {5,"周七",27,"2007-07-07"};int result = template.update(sql, params);System.out.println(result);}@Testpublic void delete() {//删除周七这条记录String sql = "DELETE FROM student WHERE sid=?";int result = template.update(sql, 5);System.out.println(result);}@Testpublic void update() {//修改张三的年龄为33String sql = "UPDATE student SET age=? WHERE name=?";Object[] params = {33,"张三"};int result = template.update(sql,params);System.out.println(result);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpingMVC 执行的流程

一&#xff1a;SpringMVC的开发步骤 ①&#xff1a;在web.xml文件中定义前端控制器DispatcherServlet来拦截用户请求。 由于Web应用是基于请求/响应结构的应用&#xff0c;所以不管哪个MVC Web框架&#xff0c;都需要在web.xml中配置该框架的核心Servlet或Filter&#xff0c;这…

UI 07 _ 导航视图控制器 与 属性传值

首先, 先创建三个VC. 完毕点击按钮, 进入下一页, 并可以返回. 要先把导航视图控制器创建出来. 在AppDelegate.m 文件里代码例如以下: #import "AppDelegate.h" #import "MainViewController.h" interface AppDelegate () endimplementation AppDelegate …

el表达式具体解释

引用内容百度百科(http://baike.baidu.com/view/1488964.htm) 參考百度百科&#xff0c;然后自己又加入了一部分自己感觉实用的东西&#xff0c;整理一下希望对大家有所帮助&#xff01;E L&#xff08;Expression Language&#xff09; 目的&#xff1a;为了使JSP写起来更加简…

MyBatis接口代理

MyBatis接口代理&#xff1a; 采用 Mybatis 的代理开发方式实现 DAO 层的开发&#xff0c;这种方式是目前的主流方式。Mapper 接口开发方法只需要程序员编写Mapper 接口&#xff08;相当于Dao 接口&#xff09;&#xff0c;由Mybatis 框架根据接口定义创建接口的动态代理对象&a…

编译OSG的FreeType插件时注意的问题

使用自己编译的freetype.lib&#xff0c;在编译osgdb_freetype插件项目时&#xff0c;报错LINK错误&#xff0c;找不到png的一堆函数 最简单的方式是不要使用PNG编译freetype。记住不要犯贱。 转载于:https://www.cnblogs.com/coolbear/p/7205906.html

openresty总结

协程 1.例如当获取的数据没有前后依赖关系时&#xff0c;可以使用ngx.thread.spawn和ngx.thread.wait同时从数据库不同的库、表或者不同来源&#xff08;mysql&#xff0c;redis等&#xff09;获取数据。https://github.com/openresty/lua-nginx-module#ngxthreadspawnhttps://…

PageHelper分页插件使用

分页插件PageHelper&#xff1a; MyBatis没有分页功能&#xff0c;需要手动编写LIMIT语句&#xff0c;可以使用第三方的插件来对功能进行扩展&#xff0c;分页助手PageHelper是将分页的复杂操作进行封装&#xff0c;使用简单的方式即可获得分页的相关数据 PageInfo&#xff1a;…

jquery插件开发通用框架

2017-07-24 更新&#xff1a;增加单例模式。 jquery插件开发框架代码&#xff1a; /** 插件编写说明&#xff1a;* 1、插件命名&#xff1a;jquery.[插件名].js&#xff0c;如jquery.plugin.js* 2、对象方法添加到jQuery.fn上&#xff0c;全局方法添加到jQuery对象本身上* 3、插…

Mybatis多表模型

多表模型&#xff1a; 多表模型分类 一对一&#xff1a;在任意一方建立外键&#xff0c;关联对方的主键。一对多&#xff1a;在多的一方建立外键&#xff0c;关联一的一方的主键。多对多&#xff1a;借助中间表&#xff0c;中间表至少两个字段&#xff0c;分别关联两张表的主键…

关于zkfc与zkserver频繁断开的问题

详见http://blog.csdn.net/dslztx/article/details/51596951转载于:https://www.cnblogs.com/roger888/p/7211625.html

高动态范围红外图像压缩

BF&DRC 近期看了一篇高动态范围红外图像压缩的文章&#xff0c;《New technique for the visualization of high dynamic range infrared images》.这篇文章主要利用双边滤波器把宽动态红外图像切割为基本图像和细节图像&#xff0c;再分别对基本图像和细节图像进行处理。对…

Mybatis构建sql语法

构建sql&#xff1a; 之前通过注解开发时&#xff0c;相关 SQL 语句都是自己直接拼写的。一些关键字写起来比较麻烦、而且容易出错。MyBatis 给我们提供了 org.apache.ibatis.jdbc.SQL 功能类&#xff0c;专门用于构建 SQL 语句 常用方法&#xff1a; 查询功能的实现&#xf…

Mqtt协议IOS端移植3

ServerMqFramework.h #import "MqttFramework.h"interface ServerMqFramework : MqttFramework/*** brief 得到模块控制器的句柄单例** param [in] N/A* param [out] N/A* return void* note*/(ServerMqFramework*)getMQttServerFrameInstance;- (int)callBusine…

java第三课,流程控制语句

流程控制语句条件语句&#xff1a;if语句&#xff1a;*if&#xff08;条件 boolean类型&#xff09;{ true }*if(boolean表达式){true}else&#xff5b;false结果&#xff5d;*多重 if else if(){}else if(){}else *嵌套ifSwitch语句&#xff1a;*switch(表达式){ case…

在cli命令行上显示当前数据库,以及查询表的行头信息

在$HIVE_HOME/conf/hive-site.xml文件下加入以下配置文件 <property><name>hive.cli.print.header</name><value>true</value><description>Whether to print the names of the columns in query output.</description> </proper…

两点之间最短路径:弗洛伊德算法

弗洛伊德算法是计算无向有权图中两点间最短路径的算法&#xff0c;复杂度为O(n^3)。其思路是将两点间距离分为过&#xff08;指定的&#xff09;第三点或是不过&#xff0c;然后取它们的最小值&#xff0c;如此循环就可以得到两点之间真正的最小值。 void floyd() {for (int k …

最常用的JavaScript 事件

JavaScript 事件&#xff1a; 事件指的就是当某些组件执行了某些操作后&#xff0c;会触发某些代码的执行。 更多事件&#xff1a;https://www.w3school.com.cn/jsref/dom_obj_event.asp 常用的事件&#xff1a; 属性触发时机onabort图像加载被中断onblur元素失去焦点onchange…

Codevs 1025 选菜

1025 选菜 时间限制: 1 s空间限制: 128000 KB题目等级 : 黄金 Gold题解题目描述 Description在小松宿舍楼下的不远处&#xff0c;有PK大学最不错的一个食堂——The Farmer’s Canteen&#xff08;NM食堂&#xff09;。由于该食堂的菜都很不错&#xff0c;价格也公道&#xff0c…

SAS笔记(2) RETAIN语句

本文重点&#xff1a; 使用RETIAN,INPUT在每次循环执行时保留上一次PDV中的变量值。SUM语句和SET语句会自动RETAIN变量。1. RETAIN语句 1.1 Example 1 先来看看在DATA步不使用和使用RETAIN语句的差异 没有使用RETAIN: DATA WITHOUT_1;PUT "Before the INPUT statement: &…

Hive优化策略

hive优化目标 在有限的资源下&#xff0c;运行效率高。常见问题 数据倾斜、Map数设置、Reduce数设置等 hive运行 查看运行计划 explain [extended] hql 例子 explain select no,count(*) from testudf group by no; explain extended select no,count(*) from testudf group …