一、连接数据库的过程

  连接数据库的过程:加载数据库驱动程序,不过只需在第一次访问数据库时加载一次,然后在每次访问数据库时创建一个Connection实例,然后执行操作数据库的SQL语句,并返回执行结果,最后在完成此次操作时销毁前面创建的Connection实例,释放与数据库的连接。

  1.加载JDBC驱动程序

    // 加载数据库驱动类,加载失败抛出ClassNotFoundException异常Class.forName(Driver);   

  2.创建数据库连接

// 创建一个数据库连接对象,创建失败会抛出SQLException异常Connection conn = DriverManager.getConnection(Url, User, Password);

  3.创建一个Statement对象

            // 通过Connection示例创建Statement实例Statement statement = conn.createStatement();

  4.执行SQL语句并获得查询结果

            // 通过Statement实例执行SQL语句并返回执行结果ResultSet rs = statement.executeQuery("select * from user");

  5.关闭连接释放资源

  在每次访问数据库后,应该按照下面的顺序,及时销毁这些实例,释放它们占用的所有资源。

            rs.close();statement.close();conn.close();

  二、Statement实例的三种类型

  Statement接口中,执行executeQuery方法可以返回查询结果到结果集中,执行executeUpdate方法可以插入、删除或者修改数据库记录,并返回一个int型数值,表示影响数据库记录的条数。

  Statement实例分为三种类型:Statement实例、(继承自Statement)PreparedStatement实例和(继承自PreparedStatement)CallableStatement实例。

  (1)Statement实例是最简单的Statement实例,只能用来执行静态的SQL语句

            ResultSet rs_queue = statement.executeQuery("select * from user");while (rs_queue.next()) {System.out.println(rs_queue.getInt("id") + " " + rs_queue.getString("name") + " " + rs_queue.getString("sex") + "  "+ rs_queue.getString("birthday"));}System.out.println(statement.executeUpdate("update user set sex='女' where id=1"));  // 打印:1       rs_queue.close();            statement.close()

  (2)PreparedStatement实例增加了执行动态SQL语句的功能

            String sql = "update user set name = ?, sex = ?, birthday = ?where id =?";PreparedStatement predStatement = conn.prepareStatement(sql);predStatement.setString(1, "loser");predStatement.setString(2, "女");predStatement.setDate(3, new Date(System.currentTimeMillis()));predStatement.setInt(4, 1);System.out.println(predStatement.executeUpdate());    // 打印:1predStatement.close();

  (3)CallableStatement实例增加了执行数据库存储过程的功能

  首先在MySQL中创建一个存储过程并测试:

mysql> select * from user //
+----+-------+------+------------+
| id | name  | sex  | birthday   |
+----+-------+------+------------+
|  1 | loser | 女   | 2018-08-06 |
|  2 | lsl   | 男   | 2017-12-12 |
|  3 | zgs   | 女   | 2016-06-01 |
+----+-------+------+------------+
3 rows in set (0.00 sec)mysql> create procedure proc_count_select_by_sex(IN girl_or_boy VARCHAR(255))-> READS SQL DATA-> BEGIN-> select count(*) from user where sex=girl_or_boy;-> END-> //
Query OK, 0 rows affected (0.00 sec)mysql> call proc_count_select_by_sex('女') //
+----------+
| count(*) |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)Query OK, 0 rows affected (0.00 sec)

  然后使用CallableStatement对象调用存储过程:

            String sql = "{call proc_count_select_by_sex(?)}";CallableStatement cablStat = conn.prepareCall(sql);cablStat.setString(1, "女");ResultSet rs = cablStat.executeQuery();while (rs.next()) {System.out.println(rs.getInt(1));    // 打印:2}            rs.close();cablStat.close();

  三、标准JDBC程序设计

package jdbc.jun.iplab;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class JDBC {private static final String Driver = "com.mysql.jdbc.Driver";private static final String Url =  "jdbc:mysql://localhost:3306/mysqldb?useSSL=false";private static final String User = "root";private static final String Password = "bjtungirc";static {try {Class.forName(Driver); } catch (ClassNotFoundException e) {e.printStackTrace();}}public static void main(String[] args) {try {     // 创建一个数据库连接对象,创建失败会抛出SQLException异常Connection conn = DriverManager.getConnection(Url, User, Password);// 通过Connection示例创建Statement实例Statement statement = conn.createStatement();// 通过Statement实例执行SQL语句并返回执行结果ResultSet rs_queue = statement.executeQuery("select * from user");while (rs_queue.next()) {System.out.println(rs_queue.getInt("id") + " " + rs_queue.getString("name") + " " + rs_queue.getString("sex") + "  "+ rs_queue.getString("birthday"));}System.out.println(statement.executeUpdate("update user set sex='女' where id=1"));rs_queue.close();statement.close();conn.close();} catch (SQLException e) {e.printStackTrace();} }
}

JDBC标准代码设计

  实际工程中使用JDBC的标准写法

package fileTransfer;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;public class DBUtils {private static String driverClass;private static String url ;private static String userName;private static String password;private static Connection connection = null;static{//读取配置文件,加载数据库相关信息ResourceBundle resourceBundle = ResourceBundle.getBundle("info");driverClass = resourceBundle.getString("driverClass");url = resourceBundle.getString("url");userName = resourceBundle.getString("userName");password = resourceBundle.getString("password");try {Class.forName(driverClass);} catch (Exception e) {System.out.println(e.toString()+"加载驱动失败!");}}public static Connection getConnection(){try {connection =  DriverManager.getConnection(url, userName, password);} catch (SQLException e) {// TODO Auto-generated catch blockSystem.out.println(e.toString()+"数据库连接失败!");}return connection;}public static void CloseAll(ResultSet resultSet, PreparedStatement pStatement, Connection connection){if (resultSet!=null) {try {resultSet.close();} catch (SQLException e) {// TODO Auto-generated catch block
                e.printStackTrace();}}if (pStatement != null) {try {pStatement.close();} catch (SQLException e) {// TODO Auto-generated catch block
                e.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException e) {// TODO Auto-generated catch block
                e.printStackTrace();}}}
}

JDBC标准工程写法

  四、JDBC连接池

  实际工程中应该考虑下面的问题:建立数据库连接需要开销,因为数据库连接是有限的资源,如果用户要离开应用一段时间,那么他占用的连接就不应该保持打开状态;另一方面,每次查询都获取连接并在随后关闭它的代价也是相当高的。

  解决上述问题的方法时建立数据库连接池(pool),这意味着数据库连接在物理上并为关闭,而是保留在一个队列中并被反复重用。

  连接池的使用对程序员来说是完全透明的,可以通过获取数据源并调用getConnection方法来得到连接池中的连接。使用完连接后,需要调用close()方法,该方法不再物理上关闭连接,而是只告诉连接池已经使用完该连接,将Connection对象返回到LinkedList对象中。

  1.编写连接池需要实现java.sql.DataSource接口

  2.创建LinkedList对象,并创建“最小连接数”个Connection对象并将这些对象添加到LinkedList对象中

  3.重写getConnection方法,使用动态代理技术管理连接池中的Connection对象

  4.封装getConnection()方法和release()方法

  示例代码

  • 配置文件jdbc.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mysqldb?useSSL=false
userName = root
password = bjtungircConnectionPoolInitSize = 10

jdbc.properties

  • 连接池类ConnectionPool
  1. 初始化:通过ResourceBundle.getBundle("jdbc")读取jdbc.properties里面的配置内容,然后初始化新建立默认的最小数据库连接对象10个Connection对象,并将这些对象加入到由LinkedList类实现的链表中。

    public class ConnectionPool implements DataSource {private static String driver;private static String url ;private static String userName;private static String password;private static int ConnectionPoolInitSize;private static LinkedList<Connection> conn_list = new LinkedList<>();static {try {ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");driver = resourceBundle.getString("driver");url = resourceBundle.getString("url");userName = resourceBundle.getString("userName");password = resourceBundle.getString("password");ConnectionPoolInitSize = Integer.parseInt(resourceBundle.getString("ConnectionPoolInitSize"));Class.forName(driver);for (int i = 0; i < ConnectionPoolInitSize; i++) {Connection conn = DriverManager.getConnection(url, userName, password);conn_list.add(conn);}} catch (SQLException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}
    @Overridepublic Connection getConnection() throws SQLException {...    }
    }

  2. getConnection()方法的重写:执行该方法会从LinkedList链表中拿出一个Connection对象conn并返回,然后通过动态代理实现:如果拿出来的这个conn对象执行了close方法,就将这个conn对象重新放回到LinkedList链表中。
        @Overridepublic Connection getConnection() throws SQLException {if (conn_list.size()>0) {final Connection conn = conn_list.removeFirst();System.out.println(1);return (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (!method.getName().equalsIgnoreCase("close")) {return method.invoke(conn, args);} else {conn_list.add(conn);return null;}}});} else {System.out.println("数据库连接失败");}return null;}

  • 封装的JDBC连接类DBUtils类(包括了getConnection方法和closeAll方法)

    package connPool.jun.iplab;import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;public class Get_jdbc_conn_from_cPool {private static ConnectionPool cPool = new ConnectionPool();public static Connection getConnection() throws SQLException{return cPool.getConnection();}public static void CloseAll(ResultSet resultSet, PreparedStatement pStatement, Connection connection){if (resultSet!=null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (pStatement != null) {try {pStatement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
    }

  • 测试类
    package connPool.jun.iplab;import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;public class CPoolTest {public static void main(String[] args) throws SQLException {// 得到数据库连接对象Connection conn = DBUtils.getConnection();// 数据库操作Statement statement = conn.createStatement();ResultSet rs = statement.executeQuery("select * from user where sex='男'");while (rs.next()) {System.out.println(rs.getInt("id") + " " + rs.getString("name") + " " + rs.getString("sex") + "  "+ rs.getString("birthday"));}// 执行这条语句时,conn对象执行了close()方法,因此会将conn对象重新添加到LinkedList集合中
            DBUtils.CloseAll(rs, statement, conn);}
    }

  • 输出
    2 lsl 男  2017-12-12
    4 winner 男  2018-08-07
    9 nine 男  2018-08-07
    ResultSet对象已关闭
    Statement对象已关闭
    Connection对象已关闭

转载于:https://www.cnblogs.com/BigJunOba/p/9431241.html

Java基础(三十二)JDBC(2)连接数据库相关推荐

  1. javaweb学习总结(三十二)——JDBC学习入门

    一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...

  2. Java基础(十二)

    合成设计模式的引出 引用传递实际应用 案例一(类关联结构) 有的人有一辆汽车,有些人坐公交:要求通过面向对象的设计来解决实现以上的这种关系转换. class Car{private String na ...

  3. Java基础语法十二 泛型程序设计

    1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element ( ...

  4. 重学java基础第二十二课:IDEA安装

  5. 重学java基础第十二课:计算机语言发展史

  6. 静态树表查找算法及C语言实现,数据结构算法C语言实现(三十二)--- 9.1静态查找表...

    一.简述 静态查找表又分为顺序表.有序表.静态树表和索引表.以下只是算法的简单实现及测试,不涉及性能分析. 二.头文件 /** author:zhaoyu date:2016-7-12 */ #inc ...

  7. 【零基础学Java】—Java 日期时间(三十二)

    [零基础学Java]-Java 日期时间(三十二) DateFormat 是日期/时间格式化子类的抽象类,它以语言无关的方式格式化和分析日期或时间. 日期/时间格式化子类(如SimpleDateFor ...

  8. 三十二、Java集合中的ArrayList

    @Author:Runsen @Date:2020/6/3 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...

  9. 第三十二章 XML基础知识概念

    文章目录 第三十二章 XML基础知识概念 attribute CDATA区域 comment content model default namespace DOM DTD(文档类型定义) eleme ...

  10. Java设计模式(十二) 策略模式

    策略模式介绍 策略模式定义 策略模式(Strategy Pattern),将各种算法封装到具体的类中,作为一个抽象策略类的子类,使得它们可以互换.客户端可以自行决定使用哪种算法. 策略模式类图 策略模 ...

最新文章

  1. jsp简介mysql_个人知识管理系统的设计与实现(JSP,MySQL)(含录像)
  2. delphi处理消息的几种方式
  3. 连接查询中where子句的执行
  4. Oracle中如何使用imp语言导入dmp文件
  5. r语言 小树转化百分数_“小树”机器人1.0新品发布会
  6. Mybatis配置信息浅析 MyBatis简介(二)
  7. android设置字符串到剪贴板
  8. 消息中间件的使用场景
  9. linux 源码包解压编译安装
  10. oracle11g64位精简版客户端,oracle11g 64位|oracle11g 64位客户端下载 附安装教程 - 121下载站...
  11. Android Service startForeground不显示Notification的办法
  12. FPGA_Verilog学习之旅(3)---VGA贪吃蛇游戏
  13. Linux与数据库简要说明
  14. Springboot毕设项目理财管理系统mnl7cjava+VUE+Mybatis+Maven+Mysql+sprnig)
  15. 如何在线获取抖音无水印视频和视频背景音乐?
  16. 无法运行Hi3516CV-DEMB-uboot-DDR...-BUS_266M.xsl宏。可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用。
  17. 数学建模学习||竞赛心得||全国大学生数学建模竞赛||华为杯数学建模竞赛
  18. JSP页面兼容IE7
  19. android.win论坛,Android中的WIN DEATH错误?
  20. 记录用AnimeGAN将图转换成动漫风所遇到的问题

热门文章

  1. SAP标准培训课程C4C10学习笔记(一)第一单元
  2. highroller赌城java下载,非常有用的链接
  3. python requests库api_Python+requests库发送接口入参为xml格式的接口请求
  4. 一道GCD LCM题目题解
  5. mysql 导入密码_mysql 常用命令导入导出修改root密码
  6. android studio复选按钮样式_Ubuntu与Android开发的邂逅
  7. java 线程同步condtion_Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信...
  8. 用diag直接使用错误_用python学量子力学(1)
  9. colinux php,利用colinux 搭建linux开发环境
  10. 压缩感知高斯测量矩阵matlab,浅谈压缩感知(十七):测量矩阵之有限等距常数RIC的计算...