通过jdbc完成单表的curd操作以及对JDBCUtils的封装
概述:jdbc是oracle公司制定的一套规范(一套接口),驱动是jdbc的实现类,由数据库厂商提供。所以我们可以通过一套规范实现对不同的数据库操作(多态)
jdbc的作用:连接数据库,发送sql语句,处理结果
curd操作:它代表创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete)操作
jdbc操作步骤:
1.数据库和表
在这里,用exercise数据库下的student表。
2.创建一个项目
由于是在javase版本的ecplise下创建的,lib文件夹是我手动创建的,用来存放导入的驱动jar包。
3.导入驱动jar包
记得右键单击jar包,然后点击build path。
4.编写代码
首先,采用硬编码的方式进行,注意,以下需要导包的所有类都是java.sql下的包,以下为代码和注释:
- @Test
- public void jdbc1() throws ClassNotFoundException, SQLException{//将类加载到内存中有3种方式
- //注册驱动
- Class.forName("com.mysql.jdbc.Driver");
- //获取连接
- Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/exercise", "root", "123456");
- //编写sql
- String sql = "select * from student";
- //创建预编译的语句执行者
- PreparedStatement st = conn.prepareStatement(sql);
- //执行sql,这里是r操作(读取操作)
- ResultSet rs = st.executeQuery();
- //处理结果,rs.next初始指向第一个。
- while(rs.next()){
- System.out.println(
- rs.getString("id")+" "+rs.getString("name")
- +" "+rs.getString("score"));
- }
- //后开的先关
- rs.close();
- st.close();
- conn.close();
- }
jdbc-api:所有的包都是java.sql或者javax.sql下的
DriverManger(驱动管理者):管理了一组jdbc的操作,是一个类。
常用方法:
1.注册驱动:static void registerDriver(Driver driver)
然而为什么注册驱动却用的Class.forName(),而不是拿registerDriver函数注册驱动呢?
由上文知,执行registerDriver函数,里面需要传入一个Driver类型的对象,查看源码我们发现
java.mysql.jdbc.Driver类中有一个静态代码块,众所周知,在类加载进内存中时,静态代码块只会运行一次。我们发现,这个静态代码块里也调用了registerDriver函数。
如果我们代码编写本身用的是registerDriver(Driver driver)函数注册驱动,那么在加载Driver这个类的时候,静态代码块执行,里面的registerDriver函数又会执行一次,相当于注册了两次驱动。这是不被允许的。为了让驱动只被注册一次,我们只需要执行Driver类中的静态代码块即可,所以我们只需要让Driver类加载进内存即可。
类加载进内存有三种方法:Class.forName("全限定名"); 类名.class 对象.getClass();
这三种方法都能将类加载进内存并成功注册驱动。上面的代码所使用的是第一种。
2.获取连接:static Connection getConnection(String url, String user, String password)
url告诉我们连接什么类型的数据库及连接哪个数据库协议:数据库类型:子协议 参数。
例如:
mysql: jdbc:mysql://localhost:3306/数据库名称
oracle: jdbc:oracle:thin@localhost:1521@实例 thin代表瘦连接
user就是账户名,password就是密码
Connection:连接 接口
常用方法:
1.获取语句执行者:
Statement createStatement() :获取普通的语句执行者 会出现sql注入问题
PreparedStatement prepareStatement(String sql) :获取预编译语句执行者
CallableStatement prepareCall(String sql):获取调用存储过程的语句执行者。
2.关于事务的一些方法:
setAutoCommit(false) 手动开启事务 选择false是因为默认是不开启事务的
commit()提交事务
rollback()事务回滚
Statement:语句执行者 接口
PreparedStatement:预编译语句执行者 接口
常用方法:
1.设置参数
setXxx(int 第几个问号,Object 实际参数);
2.执行sql
ResultSet executeQuery() :执行 r 语句 返回值:结果集
int executeUpdate() :执行cud 语句 返回值:影响的行数。一般是1,可以通过判断返回的行数来确定sql语句是否执行成功。
ResultSet:结果集 接口 执行查询语句之后返回的结果
常用方法:
1.boolean next();判断是否有下一条记录,若有,返回true,且将光标移到下一行。若无,返回false
注意:光标一开始处于第一条记录的上面,所以就算结果中只有一条记录,也会返回一个true。
2.getXxx(int/string);获取具体内容。若参数为Int,获取第几列。若参数为String,获取列名(字段名)。
getString()也可以获取int值,getObject()可以获取任意。
以上为jdbc的最基本操作,在实际操作中,当上述代码被编译为.class文件后,改动上面的参数会变得有些困难。为了方便期间,采用xml或properties文件,将里面的所有参数提取出来,封装成一个工具类,即:JDBCUtils工具类,就会方便很多。下面就是封装JDBCUtils工具类的过程。
在这里我们采用的是properties文件的方式。
properties文件的内容格式为:key=value,放在src目录下。
我们可以通过ResourceBundle工具类快速获取里面的配置信息。
使用步骤:1.获取ResourceBundle 对象: static ResourceBundle getBundle("文件名称不带后缀名") 返回值是ResourceBundle对象。
2.通过ResourceBundle 对象获取配置信息 String getString(String key) :通过执行key获取指定的value。
注意:properties文件不能有多余的空格。
由于获取参数的配置信息以及注册驱动只需要加载一次,所以将他们放入静态代码块中。
- static{
- ResourceBundle rb = ResourceBundle.getBundle("ha"); //获取properties文件。
- DRIVERCLASS = rb.getString("driverclass");
- URL = rb.getString("url");
- USER = rb.getString("user");
- PASSWORD = rb.getString("password");
- }
- static{
- //这个是注册驱动
- try {
- Class.forName(DRIVERCLASS);
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
由于获取连接时也需要用到参数的配置信息,所以将这些配置的常量定义再了静态代码块外面,并采用final修饰,表示只赋值一次。
- static final String DRIVERCLASS;
- static final String URL;
- static final String USER;
- static final String PASSWORD;
将获取连接和释放连接分别定义成静态方法。
释放连接时传入的是Statement接口,而不是prepareStatement接口。这样可以提高代码的复用性。
- public static Connection getConnection() throws ClassNotFoundException, SQLException{
- Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
- return conn;
- }
- public static void closeResource(Connection conn,Statement st,ResultSet rs) throws SQLException{
- //注意:这里传入的是statement,不是preparestatement,因为statement是父接口
- closeConn(conn);
- closeSt(st);
- closeRs(rs);
- }
- /**
- * 释放连接
- *
- * @param conn
- * 连接
- */
- public static void closeConn(Connection conn) {
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- conn = null;
- }
- }
- /**
- * 释放语句执行者
- *
- * @param st
- * 语句执行者
- */
- public static void closeSt(Statement st) {
- if (st != null) {
- try {
- st.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- st = null;
- }
- }
- /**
- * 释放结果集
- *
- * @param rs
- * 结果集
- */
- public static void closeRs(ResultSet rs) {
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- rs = null;
- }
- }
以上为工具类JDBCUtils的全部代码。
但是还是存在局限性:
即:使用jdbc的时候,每操作一次都需要获取连接(创建)用完之后把连接释放掉了(销毁)。
解决方法:,通过连接池来优化curd操作。
关于连接池的操作以及如何自定义连接池,详情见下一篇。
通过jdbc完成单表的curd操作以及对JDBCUtils的封装的更多相关文章
- 【Java EE 学习 44】【Hibernate学习第一天】【Hibernate对单表的CRUD操作】
一.Hibernate简介 1.hibernate是对jdbc的二次开发 2.jdbc没有缓存机制,但是hibernate有. 3.hibernate的有点和缺点 (1)优点:有缓存,而且是二级缓存: ...
- 使用yii AR 完成单个表的CURD操作
什么是AR(ActiveRecord) Active Record (活动记录,以下简称AR)提供了一个面向对象的接口, 用以访问数据库中的数据.一个 AR 类关联一张数据表, 每个 AR 对象对应表 ...
- jdbc笔记(二) 使用PreparedStatement对单表的CRUD操作
首先声明,本文只给出代码,并不是做教程用,如有不便之处,还请各位见谅. PreparedStatement相较于Statement,概括来说,共有三个优势: 1. 代码的可读性和易维护性:Prepar ...
- jdbc笔记(一) 使用Statement对单表的CRUD操作
jdbc连接mysql并执行简单的CRUD的步骤: 1.注册驱动(需要抛出/捕获异常) Class.forName("com.mysql.jdbc.Driver"); 2.建立连接 ...
- MySQL学习(五)——使用JDBC完成用户表CRUD的操作
通过案例我们发现“获得连接”和“释放资源”两次代码将在之后的增删改查所有功能中都存在,开发中遇到此种情况,将采用工具类的方法进行抽取,从而达到代码的重复利用. 1.使用properties配置文件 开 ...
- 使用JDBC完成分类表CRUD的操作
工具类 通过之前的案例回顾,不难发现,有很多的代码操作是重复的,比如“获取链接”和“释放资源”等,将来在增删改查中经常遇到,开发中遇到这种情况,将采用工具类的方法进行抽取,从而达到代码的重复利用. 此 ...
- Spring的jdbc模板3:完成CURD操作
测试类代码如下 package zcc.spring_jdbc.demo2; import java.sql.ResultSet; import java.sql.SQLException; impo ...
- 6.单表的CRUD操作
1.插入后用新id初始化被插入对象 <insert id="insertStudentCatchId"> insert into student (age,name,s ...
- mybatis入门--单表的增删改操作
单表的增加操作 前面我们看了如何搭建mybatis框架以及查询操作,这里我们说下如何使用mybatis进行增加用户的操作.首先是在user.xml文件中添加insert的方法.代码如下 <!-- ...
随机推荐
- 【翻译】在Sencha Touch中创建离线/在线代理
原文:Creating an Online/Offline proxy in Sencha Touch 概述 在Sencha Touch中,一个常见的需求就是,当设备在没有连接互联网的时候,应用程序必 ...
- Android群英传笔记——第十章:Android性能优化
Android群英传笔记--第十章:Android性能优化 随着Android应用增多,功能越来越复杂,布局也越来越丰富了,而这些也成为了阻碍一个应用流畅运行,因此,对复杂的功能进行性能优化是创造高质 ...
- Ext JS添加子组件的误区
经常会有人问我,为什么我的Grid不能岁窗口的变得而自动调整.了解后,发现很多人都习惯在渲染子组件的时候将Gird渲染到容器内的一个div里,而这正是问题的所在. 在Ext JS的布局系统中,能控制到 ...
- 在Android中afinal框架下实现sqlite数据库版本升级的办法
上一篇文章采用的是SQLiteOpenHelper中的onUpgrade方法实现数据库的升级. 首先获取Context: private Context mContext=this; 然后实现Fina ...
- Media Player Classic - HC 源代码分析 6:MediaInfo选项卡 (CPPageFileMediaInfo)
===================================================== Media Player Classic - HC 源代码分析系列文章列表: Media P ...
- navicat为mysql建立索引
索引的目的是大大提高查询效率,还有读写效率. kettle向sql里面插入,更新时,也要建立索引,可以大大提升处理时间. 但是建立索引报错:Specified key was too long; ma ...
- 用Xstream时候遇到的两个小异常
第一个 com.thoughtworks.xstream.converters.ConversionException: Cannot construct ClassXXX as it does no ...
- GNU中的处理目标文件的若干工具
AR 创建静态库,插入.删除.列出和提取成员: SRING 列出目标文件中的字符串: SIRIP 从目标文件中删除符号表信息: NM 列出目标文件符号表中定义的符号: SIZE 列出目标文件中节的名字 ...
- 你不知道你不懂javascript
过去几年我注意到技术圈一个很奇怪的现象,有太多程序员将那些他们只是有过非常浅显的了解, 但其实根本就不懂的技术写到他们的简历中,这个现象几乎每种语言都有,但这其中最严重的就要数javascript了. ...
- java日期操作常用工具
java日期操作常用工具 package com..util; import java.sql.Timestamp; import java.text.SimpleDateFormat; import ...