JDBC数据库连接

JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,它是一种用Java语言编写的类与接口,是Java访问数据库的标准规范。

JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备的提供商规定,设备提供商为设备提供驱动软件,通信软件可以与该设备进行通信。

JDBC原理

   JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库的连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供,自己只要会用就行

JDBC开发步骤

     1、注册驱动

            告知JVM使用的是哪一类数据库的驱动

     2、获得连接

          使用JDBC中的类,完成对MySQL数据库的连接

     3、获得语句执行平台

          通过连接对象获取对SQL语句的执行者对象

     4、执行SQL语句

          使用执行者对象,向数据库执行SQL语句

          获取到数据库的执行后的结果

     5、返回结果集

     6、释放资源(先开的后关)

          调用一堆close()方法

导入驱动jar包

    创建lib目录,用于存放当前项目需要的所有jar

    选择jar包,右键执行build path / Add to Build Path

         

开发第一步:注册驱动

使用Class.forName("com.mysql.jdbc.Driver"); 加载一个使用字符串描述的驱动类。

使用Class.forName()将类加载到内存,该类的静态代码块将自动执行。

查询com.mysql.jdbc.Driver源码,发现Driver类“主动”将自己进行注册
所以此时直接用Class.forName()直接将类加载到内存中,而不在重新注册
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!");
		}
	}
……
}

开发第二步:获得连接

获取连接的方法是DriverManager的getConnection(url,username,password)方法

        url="jdbc:mysql://主机IP:端口号/数据库名"

         例如:String url = "jdbc:mysql://localhost:3306/demo_jdbc?characterEncoding=utf-8";

String url = "jdbc:mysql://localhost:3306/demo_jdbc?characterEncoding=utf-8";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);

开发第三步:获取语句执行平台

 Statement sta = conn.createStatement();

开发第四步:执行sql语句

String sql="某sql语句";

int row=sta.executeUpdate(sql); //executeUpdate  返回SQL语句执行后的行数

开发第五步:返回结果集

System.out.println(row);

开发第六步:释放资源(先开的后关)

例如:sta.close();

           conn.close();

SQL注入问题

假设有登录案例SQL语句如下:

SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;

此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’  OR ‘a’=’a时,则真正执行的代码变为:

SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’  OR ’a’=’a’;

此时,上述查询语句时永远可以查询出结果的。那么用户就直接登录成功了,显然我们不希望看到这样的结果,这便是SQL注入问题。

为此,我们使用PreparedStatement来解决对应的问题。

PreparedStatement预处理对象

String sql="某SQL执行语句";

PreparedStatement  pst =conn.prepareStatement(sql);

执行SQL语句

  int executeUpdate(); --执行insert update delete语句.

  ResultSet executeQuery(); --执行select语句.

  boolean execute(); --执行select返回true 执行其他的语句返回false.

设置实际参数

   void setXxx(int index, Xxx xx) 将指定参数设置为给定Java的xx值。在将此值发送到数据库时,驱动程序将它转换成一个 SQL Xxx类型值。

预处理对象的executeUpdate方法

插入insert
public void demo01() throws Exception {
 // 1注册驱动
     Class.forName("com.mysql.jdbc.Driver");
 // 2获取连接
    Connection conn = DriverManager.getConnection
     ("jdbc:mysql://localhost:3306/mydb", "username", "password");
 // 3获得预处理对象
    String sql = "insert into sort(sname) values(?)";
    PreparedStatement pst = conn.prepareStatement(sql);
 // 4 SQL语句占位符设置实际参数
    pst.setString(1, "奢侈品");
 // 5执行SQL语句
    int line =pst.executeUpdate();
    System.out.println("新添加记录数:" + line);
 // 6释放资源
    pst.close();
    conn.close();
	}

  

更新update
public void demo02() throws Exception {
// 1注册驱动
	Class.forName("com.mysql.jdbc.Driver");
// 2获取连接
	Connection conn = DriverManager.getConnection
        ("jdbc:mysql://localhost:3306/mydb", "username", "password");
// 3获得预处理对象中
	String sql = "update sort set sname=? where sid=?";
	PreparedStatement pst = conn.prepareStatement(sql);
// 4 SQL语句占位符设置实际参数
	pst.setString(1, "数码产品");
	pst.setInt(2, 1);
// 5执行SQL语句
	int line = pst.executeUpdate();
	System.out.println("更新记录数:" + line);
// 6释放资源
	pst.close();
	conn.close();
	}

  

删除delete
public void demo03() throws Exception {
// 1注册驱动
	Class.forName("com.mysql.jdbc.Driver");
// 2获取连接
	Connection conn = DriverManager.getConnection
         ("jdbc:mysql://localhost:3306/mydb", "username", "password");
// 3获得预处理对象
	String sql = "delete from sort where sid=?";
	PreparedStatement pst = conn.prepareStatement(sql);
// 4 SQL语句占位符设置实际参数
	pst.setInt(1, 1);
// 5执行SQL语句
	int line = pst.executeUpdate();
	System.out.println("删除记录数:" + line);
// 6释放资源
	pst.close();
	conn.close();
	}

预处理对象executeQuery方法

实现查询分类表所有记录
	public void demo04() throws Exception {
		// 1注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		// 2获取连接
		Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb", "username", "password");
		// 3获得预处理对象
		String sql = "select * from sort";
		PreparedStatement pst = conn.prepareStatement(sql);
		// 4 SQL语句占位符设置实际参数
	        // 5执行SQL语句
		ResultSet rs = pst.executeQuery();
		// 6处理结果集(遍历结果集合)
		while( rs.next() ){
			//获取当前行的分类ID
			String sid = rs.getString("sid");//方法参数为数据库表中的列名
			//获取当前行的分类名称
			String sname = rs.getString("sname");
			//显示数据
			System.out.println(sid+"-----"+sname);
		}
		// 7释放资源
		rs.close();
		pst.close();
		conn.close();
	}

  在做数据库连接时我们会发现一些重复性的代码比如:注册驱动、获得连接,释放资源,所以将其封装成一个方法以便日后去用。

package com.oracle.demo1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DButil {

		private DButil(){}
		static Connection conn;
		static{
			try {
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql://localhost:3306/demo_jdbc?characterEncoding=utf-8";
			String username = "root";
			String password = "123456";		
			conn = DriverManager.getConnection(url, username, password);
			} catch (Exception ex) {
				throw new RuntimeException(ex+"数据库连接失败");
			}
		}
         public static Connection getConn(){
        	 return conn;
         }
         public static void close(Statement sta,Connection conn){
        	if(sta!=null){
        		try{
        			sta.close();
        		}catch(SQLException ex){}
        	}
        	if(conn!=null){
        		try{
        			conn.close();
        		}catch(SQLException ex){}
        	}
         }
         public static void close(ResultSet rs,Statement sta,Connection conn){
        	 if(rs!=null){
          		try{
          			rs.close();
          		}catch(SQLException ex){}
          	}
        	 if(sta!=null){
         		try{
         			sta.close();
         		}catch(SQLException ex){}
         	}
         	if(conn!=null){
         		try{
         			conn.close();
         		}catch(SQLException ex){}
         	}
          }
	}

 总结:

Statement 接口提供了三种执行 SQL 语句的方法:executeQuery、executeUpdate 和 execute。
使用哪一个方法由 SQL 语句所产生的内容决定。

方法executeQuery
用于产生单个结果集的语句,例如 SELECT 语句。
被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。

方法executeUpdate
用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,
例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。
executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。
对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。

使用executeUpdate方法是因为在 createTableCoffees 中的 SQL 语句是 DDL (数据定义语言)语句。
创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。

方法execute:
用于执行返回多个结果集、多个更新计数或二者组合的语句。因为多数程序员不会需要该高级功能

原文地址:https://www.cnblogs.com/Java-125/p/8744464.html