JDBC基础

JDBC基础


1.引言


JDBC是什么?

JDBC:Java Database Connectivity —— sun公司推出的一套java应用程序访问数据库产品的技术和规范

  • 规范:抽象类或接口
  • java.sql包或javax.sql包

JDBC 是一个独立于特定数据库管理系统(DBMS)、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,使用这个类库可以以一种标准的方法、方便地访问数据库资源。

JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。

为什么需要JDBC

JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。

JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。

在这里插入图片描述

JDBC能够做什么

Java程序可以通过 JDBC API 实现数据库数据的增删改查

JDBC API是一系列的接口,它统一和规范了应用程序与数据库的连接、执行SQL语句,并到得到返回结果等各类操作。声明在java.sql与javax.sql包中。

?????

2.JDBC使用步骤


前期准备

引入JDBC驱动程序

  • 1.导入jar包
  • 2.将jar包添加到项目的类路径下:Build Path - Add to Build Path

注意:如果是Dynamic Web Project(动态的web项目)话,则是把驱动jar放到WebContent(有的开发工具叫WebRoot)目录中的WEB-INF目录中的lib目录下即可

2.1 加载并注册驱动

1.加载驱动,把驱动类加载到内存

2.注册驱动,把驱动类的对象交给DriverManager管理,用于后面创建连接等使用。

方式1:new 对象

使用new com.mysql.jdbc.Driver 创建驱动对象,并使用DriverManager.registerDriver方法注册:

//1.加载并注册驱动
DriverManager.registerDriver(new Driver());

不足:

  • 1)导致Driver new 了两遍,效率较低
  • 2)编译期加载,数据库驱动jar的依赖性太高

因为:在 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver() 方法来注册自身的一个实例:

package com.mysql.jdbc;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
	static {
		try {
			java.sql.DriverManager.registerDriver(new Driver());
		} catch (SQLException E) {
			throw new RuntimeException("Can't register driver!");
		}
	}
		......
}

所以可以换一种方式来加载驱动。只要让驱动类的这段静态代码块执行,即可注册驱动类,而要让这段静态代码块执行,让该类被类加载器加载即可。

方式2:Class.forName( ) 反射√

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

//1.加载与注册驱动类:通过反射,解耦合(不直接依赖)
Class.forName("com.mysql.jdbc.Driver");

Class类对象加载,对应的静态代码块也就会执行,对应的驱动类对象也就会加载并注册。

2.2 获取连接

可以通过 java.sql.DriverManager 类建立到数据库的连接 Connection:

  • DriverManager 试图从已注册的 JDBC 驱动程序集中选择一个适当的驱动程序。

DriverManager 类的 getConnection 方法:返回值 java.sql.Connection

public static Connection getConnection(String url) 
public static Connection getConnection(String url,String user, String password)
public static Connection getConnection(String url,Properties info)  
1. JDBC URL

JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。JDBC URL的标准由三部分组成,各部分间用冒号分隔。

jdbc:<子协议>:<子名称>
  • 协议:JDBC URL中的协议总是jdbc
  • 子协议:子协议用于标识一个数据库驱动程序
  • 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息

MySQL的连接URL编写方式:

  • jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值
  • jdbc:mysql://localhost:3306/testdb
  • jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8(如果JDBC程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集)
  • jdbc:mysql://localhost:3306/testdb?user=root&password=123456

Oracle9i:

  • jdbc:oracle:thin:@主机名称:oracle服务端口号:数据库名称
  • jdbc:oracle:thin:@localhost:1521:testdb

SQLServer:

  • jdbc:sqlserver://主机名称:sqlserver服务端口号:DatabaseName=数据库名称

  • jdbc:sqlserver://localhost:1433:DatabaseName=testdb

    //1、加载与注册驱动
    Class.forName(“com.mysql.jdbc.Driver”);

    //2、获取数据库连接
    String url = “jdbc:mysql://localhost:3306/test”;
    Connection conn = DriverManager.getConnection(url, “root”, “root”);

2. Properties

1.创建Properties对象

Properties properties = new Properties();

2.加载properties文件:properties.lode(InputStream inStream)

方式1:通过当前类的类加载器,加载源文件目录下的properties文件[推荐]

properties .load(Test.class.getClassLoader().getResourceAsStream("database.properties"));

方式2:

properties.load(new FileInputStream("src\\database.properties"));

其中Properties info通常至少应该包括 “user” 和 “password” 属性

案例:

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

//2.获取连接
Properties info = new Properties();
info.load(Test.class.getClassLoader().getResourceAsStream("database.properties"));
Connection connection = DriverManager.getConnection("jdbc:mysql:///girls", info);

2.3 操作或访问数据库

数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。

其实一个数据库连接就是一个Socket连接。

数据库调用的三类不同接口

在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

  • Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
  • PrepatedStatement extends Statement:SQL 语句被预编译并存储在此对象中,然后可以使用此对象多次高效地执行该语句。
  • CallableStatement extends PreparedStatement:用于执行 SQL 存储过程
1. java.sql.Statement接口

1)创建方式:

  • 通过调用 Connection 对象的 createStatement() 方法创建Statement对象

2)作用:

  • 该对象用于执行静态的 SQL 语句,并且返回执行结果

3)方法

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

  • int excuteUpdate(String sql):执行更新操作INSERT、UPDATE、DELETE,返回受影响的行数

  • ResultSet excuteQuery(String sql):执行查询操作SELECT,返回结果集

  • boolean execute(String sql);//执行任何sql语句,返回是否为结果集

      ///1、连接数据库
      Class.forName("com.mysql.jdbc.Driver");
      
      String url = "jdbc:mysql://localhost:3306/1221db";
      String user = "root";
      String password = "123456";
      Connection conn = DriverManager.getConnection(url, user, password);
      
      //2、创建Statement对象
      Statement st = conn.createStatement();
    
      //3、编写sql
      String sql = "INSERT INTO emp (ename,mid,did) VALUES('" + name+"'," + mid + "," + did + ")";
      
      //4、执行sql
      int update = st.executeUpdate(sql);
      System.out.println(update>0?"添加成功":"添加失败");
    
      //5、释放资源
      st.close();
      conn.close();
    

4)Statement的不足

  • 1>SQL拼接
  • 2>SQL注入
  • 3>处理不了Blob类型的数据

5)BLOB (binary large object)——二进制大对象。BLOB常常是数据库中用来存储二进制文件的字段类型。

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

MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的):

类型大小(字节)
TinyBlob最大 255
Blob最大 65K
MediumBlob最大 16M
LongBlob最大 4G

6)SQL注入

SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,从而利用系统的 SQL 引擎完成恶意行为的做法。对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了。

2. java.sql.PreparedStatement

Statement接口的不足,可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象 PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句

特点:

  • 性能高
  • 会把sql语句先编译
  • 能过滤掉用户输入的关键字。

PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数.

  • setXxx( ) 方法:有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值
  • ResultSet executeQuery():执行查询,并返回该查询生成的 ResultSet 对象。
  • int executeUpdate( ):执行更新,包括增、删、该,返回SQL影响的行数

案例:

//1、连接数据库
Class.forName("com.mysql.jdbc.Driver");

String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);

//2、编写带占位符?的SQL
String sql = "INSERT INTO t_employee (ename,tel,gender,salary,did) VALUES(?,?,?,?,?)";

// 3、准备一个PreparedStatement:预编译sql
PreparedStatement pst = conn.prepareStatement(sql);// 对带?的sql进行预编译

// 4、把?用具体的值进行代替
pst.setString(1, name);
pst.setString(2, tel);
pst.setString(3, gender);
pst.setDouble(4, salary);
pst.setInt(5, did);

// 5、执行sql
int len = pst.executeUpdate();
System.out.println(len>0?"添加成功":"添加失败");

// 6、释放资源
pst.close();
conn.close();
3. PreparedStatement vs Statement
  • 1.代码的可读性和可维护性. Statement 的sql拼接是个难题。
  • 2.PreparedStatement 可以防止 SQL 注入
  • 3.PreparedStatement 可以处理Blob类型的数据
  • 4.PreparedStatement 可以实现批处理功能
  • 5.PreparedStatement 能最大可能提高性能:(Oracle和PostgreSQL8是这样,但是对于MySQL不一定比Statement高)

DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。

4. java.sql.ResultSet 接口

通过调用 Statement 对象的 excuteQuery() 方法返回该对象

ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商实现。

ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行。

ResultSet 接口的常用方法:

  • boolean next():将游标移至下一行,并返回下一行是否有数据的布尔值
  • getXxx(String columnLabel):columnLabel使用 SQL AS 子句指定的列标签。如果未指定 SQL AS 子句,则标签是列名称
  • getXxx(int index) :索引从1开始

案例:

//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");		
//2.获取连接
Properties  pro = new Properties();
pro.load(new FileInputStream("src\\druid.properties"));
//创建Druid数据库连接池,获取连接
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
Connection connection = ds.getConnection();

//3.执行查询
//①获取执行sql的命令对象
Statement statement = connection.createStatement();

//②执行sql
ResultSet set = statement.executeQuery("select name bname,sex gender,borndate born from beauty");

while(set.next()) {
	String name = set.getString("bname");
	char gender = set.getString("gender").charAt(0);
	Date date = set.getDate("born");
	//String date = set.getString("born");
	System.out.println(name+"\t"+gender+"\t"+date);
}
	
//4.关闭资源
set.close();
statement.close();
connection.close();
5.Java与SQL数据类型

在这里插入图片描述

2.4 释放资源

前三步中使用的 Connection、Statement、ResultSet都是应用程序和数据库服务器的连接资源,使用后一定要关闭,可以在finally中关闭。

MySQL数据库中设置有最大连接数量(my.ini中max_connections=10),如果不关闭该资源,连接会一直占用。

//4.关闭资源
set.close();
statement.close();
connection.close();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值