JDBC入门

目录

1.JDBC概述

1.1 什么是JDBC

1.2 JDBC体系结构

1.3 JDBC本质

1.4 JDBC快速入门

2 JDBC详解

2.1 DriverManager(驱动程序管理器)

2.2 Connection 

2.3 Statement

2.4 PreparedStatement

2.5 ResultSet 

2.6 ResultSetMetaData

3 资源的释放

4 总结

5 使用JDBC操作BLOB类型字段

5.1 MySQL中的BLOB类型

6 使用JDBC管理事务

7 数据库连接池

7.1 概念

7.2 多种开源的数据库连接池

C3P0数据库连接池

Druid数据库连接池


1.JDBC概述

1.1 什么是JDBC

JDBC(Java DataBase Connectivity-java数据库连接)是sun公司提供一套用于数据库操作的公共接口,可以为多种关系型数据库提供统一访问途径。使得程序员只需面对接口编程即可,而不同数据库的厂商,需要针对这套接口,提供不同实现的集合,即提供不同数据库的驱动。

1.2 JDBC体系结构

JDBC接口包含两个层次:

面向应用的API:Java API,抽象接口,供来发人员使用(连接数据库,执行sql语句,获得结果)。

面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。

1.3 JDBC本质

总结:

  • JDBC是Java连接数据库技术的统称
  • JDBC由两部分组成:

        1.Java提供的JDBC规范(接口)

        2.各个数据库厂商的实现驱动(jar)

  • JDBC是一种典型的面向接口编程 

1.4 JDBC快速入门

public static void main(String[] args) throws Exception {
        //1. 导入jar包

        //2. 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //3. 获取连接
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?" +
                "useSSL=false&serverTimezone=UTC","root","root");

        //4. 获取执行者对象
        Statement stat = con.createStatement();

        //5.执行sql语句,并且接收结果
        String sql = "SELECT * FROM boys";
        ResultSet rs = stat.executeQuery(sql);

        //6.处理结果
        while (rs.next()){
            System.out.println(rs.getString("boyName") + "\t" + rs.getString("userCP"));
        }

        //7.释放资源
        con.close();
        stat.close();
        rs.close();

    }

2 JDBC详解

2.1 DriverManager(驱动程序管理器)

将第三方数据库厂商的实现驱动jar注册到程序中

可以根据数据库连接信息获取connection

加载驱动

加载JDBC驱动需调用Class类的静态方法forName(),向其传递要加载的JDBC驱动的类名

Class.forName("com.mysql.jdbc.Driver")

 注册驱动

我们不需要显示的调用DriverManager类中的方法来注册驱动类的实例,因为在Driver接口的驱动类中包含了静态代码块。只要Driver类被使用,则会执行静态代码块完成注册

 获取数据库连接

获取数据库连接对象:public static Connection getConnection(String url, String user, String password)

返回值:Connection 数据库连接对象

参数

        url:指定连接路径。语法:jdbc:mysql://ip地址:端口号/数据库名称

        user:用户名

        password:密码

2.2 Connection 

和数据库建立的连接,在连接对象上,可以多次执行数据库CRUD

可以获取statement 和 preparedStatement、callableStatement

 

Connection数据库连接对象

        ①获取对象

        ②管理事务

          开启事务:setAutoCommit(boolean autoCommit);

          提交事务:commit();

          回滚事务:rollback();

        ③释放资源

          立即释放资源:void close();

2.3 Statement

通过调用Connection对象的createStatement()方法创建该对象。该对象用于执行静态的SQL语句,并且返回执行结果。

Statement接口中定义了下列方法用于执行sql 语句:

执行跟新操作(INSERT、UPDATE、DELETE):int excuteUpdate(String sql);

执行查询操作(SELECT):ResultSet executeQuery(String sql);

2.4 PreparedStatement

调用Connection对象的preparedStatement(String sql)方法获取PreparedStatement对象

PreparedStatement接口Statement的子接口,它表示一条预编译的sql语句

对于sql中的参数在PreparedStatement中用‘?’来表示,在调用其对象的.setXxx()方法来设置参数;setXxx()中有两个参数,第一个:sql语句中的参数的索引(从1开始);第二个:sql语句中的值

使用PreparedStatement实现增、删、改

public void update(String sql,Object ... args){
	Connection conn = null;
	PreparedStatement ps = null;
	try {
		//1.获取数据库的连接
		conn = JDBCUtils.getConnection();
			
		//2.获取PreparedStatement的实例 (或:预编译sql语句)
		ps = conn.prepareStatement(sql);
		//3.填充占位符
		for(int i = 0;i < args.length;i++){
			ps.setObject(i + 1, args[i]);
		}
		
		//4.执行sql语句
		ps.execute();
	} catch (Exception e) {
			
		e.printStackTrace();
	}finally{
		//5.关闭资源
		JDBCUtils.closeResource(conn, ps);
		
	}
}

用PreparedStatement代替Statement

  • 提高代码的可读性和可维护性。
  • DBServer会对预编译的语句提供性能优化。被预编译一次的语句在下一次使用时不用再次进行编译而是直接调用即可
  • PreParedStatement可以防止SQL注入
    • 在执行sql语句前,先将sql语句进行编译。明确了sql语句的格式后,就不会改变了,剩下的内容都会认为是参数
    • sql语句的参数使用 '?' 作为占位符

SQL注入:利用sql语句的漏洞对系统进行攻击

如: SELECT user,password FROM user_table WHERE USER = '1' or ' AND PASSWORD = '='1' or '1' = '1';

原本sql语句是做一个AND的操作,当条件都满足时才查询,但是通过上述语句可以发现现在的sql语句变为了OR操作,只需满足任意一个条件即可,这样的情况显然是不允许出现的

2.5 ResultSet 

  • 查询需要调用PreparedStatement的executeQuery()方法,查询结果是一个ResultSet对象
  • ResultSet对象以表格的形式封装了数据库操作的结果集,即它返回的就是一张数据表,有一个指针指向数据表的第一条记录前面
  • ResultSet对象维护了一个指向当前数据行的游标,初始时,游标在第一行之前,可以调用ResultSet对象的next()方法移动到下一行。调用next()方法检测下一行是否有效。若有效返回true,且指针下移。
  • 当指针指向一行时,可以通过调用getXxx(Int index)或getXxx(int columnName)获取每一列的值

注意:Java于数据库交互涉及到的相关Java API中的索引都从1开始

2.6 ResultSetMetaData

用于获取关于ResultSet对象中列的类型和属性信息对象

  • ResultSetMetaData meta = rs.getMetaData();

    • getColumnName(int column):获取指定列的名称

    • getColumnLabel(int column):获取指定列的别名

    • getColumnCount():返回当前 ResultSet 对象中的列数。

    • getColumnTypeName(int column):检索指定列的数据库特定的类型名称。

    • getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。

    • isNullable(int column):指示指定列中的值是否可以为 null。

    • isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。

3 资源的释放

释放ResultSet、Statement、Connection

Connection是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早释放。

可以在finally中关闭,确保在其他代码出现异常时,资源也能关闭

4 总结

两种思想

1.面向接口编程的思想

2.ORM思想(object relational ,mapping)

  • 一个表对应一个Java类;
  • 表中的一条记录对应Java类中的一个对象;
  • 表中的一个字段对应Java类中的一个属性;

两种技术

  JDBC结果集的元数据:ResultSetMetaData

  • 获取列数:getColumnCount()
  • 获取列的别名:getColumnLabel()

通过反射,创建指定类的对象,获取指定的属性并赋值

5 使用JDBC操作BLOB类型字段

5.1 MySQL中的BLOB类型

MySQL中,BLOB是一个二大型的二进制对象,可以存储大量的数据

插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接的

注意:1.如果存储的文件过大,会导致数据库性能下降

           2.如果指定了相关的Bolb类型以后,还报错:xxx too large,那么在MySQL的安装目录下找到my.ini文件加上如下配置参数: max_allowed_packet=16M同时修改完后需重启数据库

演示:向数据表中插入大数据类型

//获取连接
Connection conn = JDBCUtils.getConnection();
		
String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
//预编译sql语句
PreparedStatement ps = conn.prepareStatement(sql);

// 填充占位符
ps.setString(1, "高启强");
ps.setString(2, "gaoqiqiang@126.com");
ps.setDate(3, new Date(new java.util.Date().getTime()));
// 操作Blob类型的变量
FileInputStream fis = new FileInputStream("gqq.png");
ps.setBlob(4, fis);
//执行
ps.execute();
		
fis.close();
JDBCUtils.closeResource(conn, ps);

6 使用JDBC管理事务

在MySQL中存在事务的概念。想要具体了解的小伙伴可以看我前面总结的MySQL事务

JDBC管理事务的功能类:Connection

  • 调用Connection对象的setAutoCommit(false) ;以取消自动提交
  • 在所有的SQL语句都成功执行后,调用commit()方法提交事务
  • 在出现异常时,调用rollback()方法回滚事务

 若此时Connection没有被关闭,还可以重复使用,则需要先恢复到自动提交状态(setAutoCommit(true))。特别是在使用数据库连接池技术时,执行close()前,恢复自动提交状态

7 数据库连接池

7.1 概念

基本思想:为数据库建立一个“缓冲池”。在里面事先放入一定数量的连接,当需要创建连接时直接在池中取一个,使用完后又放回池中 ;这样就不用每次创建、使用再关闭,达到重复使用的效果

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新创建一个

7.2 多种开源的数据库连接池

JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由服务器来实现(Woblogic,WebSphere,Tomcat),当然也有一些开源组织提供实现:

  • DBCP 是Apache提供的数据库连接池。tomcat 服务器自带dbcp数据库连接池。速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持。

  • C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以。hibernate官方推荐使用

  • Proxool 是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点

  • BoneCP 是一个开源组织提供的数据库连接池,速度快

  • Druid 是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池,但是速度不确定是否有BoneCP快

C3P0数据库连接池

使用步骤:

        ①导入jar包;

        ②导入配置文件到src目录下

        ③创建C3P0连接池对象

        ④获取数据库连接进行使用

注意:C3P0的配置文件会自动加载,但必须命名为c3p0-config.xml或c3p0-config.properties

代码演示:

 配置文件如下:将文件命名为c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<named-config name="helloc3p0">
		<!-- 获取连接的4个基本信息 -->
		<property name="user">root</property>
		<property name="password">root</property>
		<property name="jdbcUrl">jdbc:mysql:///test</property>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		
		<!-- 涉及到数据库连接池的管理的相关属性的设置 -->
		<!-- 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 -->
		<property name="acquireIncrement">5</property>
		<!-- 初始化数据库连接池时连接的数量 -->
		<property name="initialPoolSize">5</property>
		<!-- 数据库连接池中的最小的数据库连接数 -->
		<property name="minPoolSize">5</property>
		<!-- 数据库连接池中的最大的数据库连接数 -->
		<property name="maxPoolSize">10</property>
		<!-- C3P0 数据库连接池可以维护的 Statement 的个数 -->
		<property name="maxStatements">20</property>
		<!-- 每个连接同时可以使用的 Statement 对象的个数 -->
		<property name="maxStatementsPerConnection">5</property>

	</named-config>
</c3p0-config>

获取连接

//使用C3P0数据库连接池的配置文件方式,获取数据库的连接
private static DataSource cpds = new ComboPooledDataSource("helloc3p0");
public static Connection getConnection() throws SQLException{
	Connection conn = cpds.getConnection();
	return conn;
}

Druid数据库连接池

Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、Proxool等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,可以说是目前最好的连接池之一。

使用步骤 

        ①导入jar包;

        ②导入配置文件到src目录下

        ③通过Properties集合加载配置文件

        ④通过Druid连接池工厂类获取数据库连接池对象

        ⑤获取数据库连接进行使用

代码演示:

public class DruidTest1 {
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();

        //通过反射读取druid配置文件
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        prop.load(is);

        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        Connection con = dataSource.getConnection();

        String sql = "SELECT * FROM books";
        PreparedStatement pst = con.prepareStatement(sql);

        ResultSet rs = pst.executeQuery();

        while (rs.next()){
            System.out.println(rs.getInt("id") + "\t" + rs.getString("title") + " \t" + rs.getString("author") + "\t" + rs.getDouble("price"));
        }

        rs.close();
        pst.close();
        con.close();
    }
}

结果演示:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值