什么是JDBC

Posted 劲火星空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是JDBC相关的知识,希望对你有一定的参考价值。

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。

一、:JDBC的简单使用

首先JDBC是一个接口的集合,是用来控制SQL语句的,要导入一些包,本例子中使用的是junit.Test的测试方式

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

// 测试方法,方法必须是public void,再加上一个@Test,然后选中方法,右键run as junit
import org.junit.Test;

public class Demo {
	@Test
	//发送插入语句
	public void fun1() throws Exception{
		//1 导入驱动类库
		//2 注册驱动
		DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 
		//3 连接数据库
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "7q7q77qq");
		//4 操作数据库
		Statement st = conn.createStatement();
		String sql =  " INSERT INTO `t_user` "+
					  "	VALUES (NULL, 'tom', 18)" ;
		st.executeUpdate(sql);
		
		//5 关闭资源
		st.close();
		conn.close();
	}
	
	@Test
	//发送查询语句
	public void fun2() throws Exception{
		//1 导入驱动类库
		//2 注册驱动
		DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 
		//3 连接数据库,最后的day05代表的是数据库的意思
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "7q7q77qq");
		//4 操作数据库
		Statement st = conn.createStatement();
		String sql =  " select * from t_user " ;
		
		ResultSet rs = st.executeQuery(sql);
		
		//遍历结果集中的内容并打印
		while(rs.next()){
			String name = rs.getString("name");
			int id = rs.getInt("id");
			int age = rs.getInt("age");
			
			System.out.println(name+"==>"+age+"==>"+id);
		}
		
		//5 关闭资源
		st.close();
		conn.close();
	}
}


二、:JDBC驱动的注册

推荐使用的是第二种方式,第一种在静态代码块调用了,静态代码块在类加载时被调用,所以我们加载类就可以了

package cn.itcast.b_dm;

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

import org.junit.Test;
//DriverManager细节
public class Demo {
	@Test
	public void fun1() throws Exception{
		// 注册驱动
		//注册方式1:不推荐 => 驱动实现类中 的静态代码以及调用过
		// DriverManager.registerDriver(driver);
		//注册方式2:推荐
		Class.forName("com.mysql.jdbc.Driver");
	}
	@Test
	public void fun2() throws Exception{
		// 获得连接
		DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/day05", "root", "1234");
		
		//url完整 格式:  大协议:子协议://IP地址:端口号/库名?参数键=参数值
		//完整:			  jdbc:mysql://127.0.0.1:3306/day05?useUnicode=true&characterEncoding=utf8
		//简单: <span style="white-space:pre">		</span>  jdbc:mysql:///day05?useUnicode=true&characterEncoding=utf8
	}
}

三、:JDBC四种执行方式

package cn.itcast.c_st;

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

import org.junit.Test;
//Statement细节
public class Demo {
	@Test
	//execute 	原始,增删改查都可以 返回值  true=> 查询有结果集  |  false=> 查询没有结果集
	//executeBatch	批量执行sql
	//executeUpdate 执行增删改
	//executeQuery 执行查询
	public void fun1() throws Exception{
		//1 注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2 获得连接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "7q7q77qq");
		//3 创建Statement
		Statement st = conn.createStatement();
		//4 书写sql
		String sql =  " INSERT INTO `t_user` "+
				  "	VALUES (NULL, 'jerry', 16)" ;
		//5 执行sql
	boolean result = 	st.execute(sql);
	System.out.println(result);//false
		//6关闭资源
	 st.close();
	 conn.close();
	}
	@Test
	public void fun2() throws Exception{
		//1 注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2 获得连接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "7q7q77qq");
		//3 创建Statement
		Statement st = conn.createStatement();
		//4 书写sql
		String sql =  "select * from t_user" ;
		//5 执行sql
	boolean result = 	st.execute(sql);
		if(result){
			ResultSet  rs = st.getResultSet();
			System.out.println(rs);
		}
		//6关闭资源
	 st.close();
	 conn.close();
	}
	@Test
	//executeUpdate
	public void fun3() throws Exception{
		//1 注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2 获得连接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "7q7q77qq");
		//3 创建Statement
		Statement st = conn.createStatement();
		//4 书写sql
		String sql =  " INSERT INTO `t_user` "+
				  "	VALUES (NULL, 'jack', 20)" ;
		//5 执行sql
		int row =  st.executeUpdate(sql);
		if(row!=1){
			throw new RuntimeException("插入失败!");
		}
		System.out.println(row);//1
		//6关闭资源
	 st.close();
	 conn.close();
	}
	@Test
	//executeQuery
	public void fun4() throws Exception{
		//1 注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2 获得连接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "7q7q77qq");
		//3 创建Statement
		Statement st = conn.createStatement();
		//4 书写sql
		String sql =  "select * from t_user" ;
		//5 执行sql
		ResultSet rs = st.executeQuery(sql);
		//遍历rs
		System.out.println(rs);
		//6关闭资源
	 st.close();
	 conn.close();
	}
}

四、:JDBC修改数据库

下面使用的是updateString的方式来修改的

package cn.itcast.d_rs;

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

import org.junit.Test;
//ResultSet细节
// 2.结果集反向修改数据库
public class Demo3 {
	@Test
	public void fun1() throws Exception{
		//1 注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2 获得连接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day05", "root", "1234");
		//3 创建Statement
		Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
		//4 书写sql
		String sql =  "select * from t_user" ;
		//5 执行sql
		ResultSet rs = st.executeQuery(sql);
		//使用结果集 反向修改数据库
		rs.next();//将光标移动到第一行
		rs.updateString("name", "汤姆");// 修改第一行name列的值为中文汤姆
		rs.updateRow();// 确认修改
		//6关闭资源
	 st.close();
	 conn.close();
	}
}

五、:JDBC中的工具类

通过使用工具类来导入db.properties中的数据来获得用户名密码等信息,最终获得连接的过程

package cn.itcast.e_tool;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtils {
	private static String driver;
	private static String url;
	private static String user;
	private static String password;
	
	static{
		
		try {
			//0读取配置文件
			Properties prop  = new Properties();
			
			InputStream is = new FileInputStream("src/db.properties");
			
			prop.load(is);
			
			is.close();
			
			driver = prop.getProperty("driver");
			url = prop.getProperty("url");
			user = prop.getProperty("user");
			password = prop.getProperty("password");
			
			//1 注册驱动
			Class.forName(driver);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	//1 获得连接
	public static Connection getConnection(){
		Connection conn = null;
		try {
			//2 获得连接
			conn = DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("创建连接失败!");
		}
		
		return conn;
	}
	
	//2 释放资源
		//1> 参数可能为空
		//2> 调用close方法要抛出异常,确保即使出现异常也能继续关闭
		//3>关闭顺序,需要从小到大
	public  static void  close(Connection conn , Statement st , ResultSet rs){
		
		try {
			if(rs!=null){
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				if(st!=null){
				st.close();	
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				try {
					if(conn!=null){
						conn.close();	
						}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}	
		}	
	}
	public static void main(String[] args) {
		System.out.println(getConnection());
	}
}

六、:SQL注入问题

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。下边的fun1()就是一个SQL注入的问题,fun2使问题得以解决了。

package cn.itcast.f_ps;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

import cn.itcast.e_tool.JDBCUtils;
public class Demo {
	@Test
	//演示使用Statement对象,sql注入问题
	public void fun1() throws Exception{
		String name ="xxx' OR 1=1 -- ";
		String password ="7q7q77qq";
		
		//1 获得连接
		Connection conn= JDBCUtils.getConnection();
		//2 获得Statement
		Statement st = conn.createStatement();
		//3 拼装sql语句
		String sql = "SELECT * FROM t_user  WHERE NAME='"+name+"' AND   PASSWORD='"+password+"';";
		//4 执行sql并拿到结果
		ResultSet rs = st.executeQuery(sql);
		//5 根据结果判断是否登录成功
		if(rs.next()){
			System.out.println("登录成功!");
		}else{
			System.out.println("登录失败!");
		}
		//6关闭资源
		JDBCUtils.close(conn, st, rs);
	}
	
	@Test
	//演示使用PrepareStatement对象,解决sql注入问题
	public void fun2() throws Exception{
		String name ="xxx' OR 1=1 -- ";
		String password ="7q7q77qq";
		
		//1 获得连接
		Connection conn= JDBCUtils.getConnection();
		//2 拼装sql语句
		String sql = "SELECT * FROM t_user  WHERE NAME=? AND   PASSWORD=?";
		//3 获得PrepareStatement
		PreparedStatement ps = conn.prepareStatement(sql);
		//4 设置参数到ps对象中
		ps.setString(1, name);
		ps.setString(2, password);
		//5 运送参数,执行sql并拿到结果
	ResultSet rs = 	ps.executeQuery();
		//5 根据结果判断是否登录成功
		if(rs.next()){
			System.out.println("登录成功!");
		}else{
			System.out.println("登录失败!");
		}
		//6关闭资源
		JDBCUtils.close(conn, ps, rs);
	}
}

最后的这个PreparedStatement是有点问题的,正在努力解决中。



以上是关于什么是JDBC的主要内容,如果未能解决你的问题,请参考以下文章

面试常用的代码片段

mysql jdbc源码分析片段 和 Tomcat's JDBC Pool

如何在片段中填充列表视图?

JDBC操作数据库之查询数据

C# 最有用的(自定义)代码片段是啥? [关闭]

此 Canon SDK C++ 代码片段的等效 C# 代码是啥?