JDBC之入门篇

本文详细介绍了JDBC(Java数据库连接)的基本概念、原理、核心类及其使用方法,包括如何通过JDBC连接数据库、执行SQL语句、处理结果集,并重点讲解了如何使用PreparedStatement来防范SQL注入攻击。同时,提供了JDBC操作数据库的示例代码,旨在帮助开发者更高效、安全地进行数据库操作。
摘要由CSDN通过智能技术生成

什么是jdbc:

JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。


jdbc原理:


早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。



jdbc核心类:(先混个眼熟吧)


DriverManger  Connection  Statement  ResultSet

DriverManger(驱动管理器)的作用有两个:

l  注册驱动:这可以让JDBC知道要使用的是哪个驱动;

l  获取Connection:如果可以获取到Connection,那么说明已经与数据库连接上了。


Connection对象表示连接,与数据库的通讯都是通过这个对象展开的:

l  Connection最为重要的一个方法就是用来获取Statement对象;


Statement是用来向数据库发送SQL语句的,这样数据库就会执行发送过来的SQL语句:

l  void executeUpdate(String sql):执行更新操作(insert、update、delete等);

l  ResultSet executeQuery(String sql):执行查询操作,数据库在执行查询后会把查询结果,查询结果就是


ResultSet;

ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生。结果集是一个二维的表格,有行有列。操作结果集要学习移动ResultSet内部的“行光标”,以及获取当前行上的每一列上的数据:

l  boolean next():使“行光标”移动到下一行,并返回移动后的行是否存在;

XXX getXXX(int col):获取当前行指定列上的值,参数就是列数,列数从1开始,而不是0。


怎么用:

NO.1 导包:数据库的驱动包:mysql为例,mysql-connector-java-5.1.13-bin.jar


NO.2 准备四大参数:driverClassName、url、username、password  


No.3 注册驱动类 :Class.froName(driverClassName);搞定


No.4 获取连接 : DriverManger.getConnection(url,username,password);

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

import org.junit.Test;

public class DemoTwo {
	@Test
	public void fun1() throws ClassNotFoundException, SQLException {
		
		String driverClassName = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/demo";
		
		String user = "root";		
		String password = "123";
		
		Class.forName(driverClassName);
		
		//得到连接
		Connection connection = DriverManager.getConnection(url, user, password);
		
		//创建声明
		Statement statement = connection.createStatement();
		
//		执行查询操作
		String sqlString = "select * from bm_list";
		
		ResultSet rs = statement.executeQuery(sqlString);//返回结果集。
		
		/*
		 * rs内部有一个游标:
		 * 光标默认位置是第一行的前面
		 * rs.next()把光标位置向下移动一行。next()方法返回的boolean表示是否有这一行。
		 * 可利用这个方法对结果集进行遍历,前提是你需要知道字段名,或者其属性。
		 */
		//rs.next();
		
//		Object o = rs.getObject(1);
//		System.out.println(o);
		
//		String qq = rs.getString("qq");
//		String name = rs.getString("real_name");
/*		这两种方法都可以对其进行遍历。
		for (int i = 0; rs.next(); i++) {
			String qq = rs.getString("qq");
			String name = rs.getString("real_name");
			System.out.println("姓名:"+name+"  qq:"+qq);
		}

		while (rs.next()) {
			String qq = rs.getString("qq");
			String name = rs.getString("real_name");
			System.out.println("姓名:"+name+"  qq:"+qq);
		}
*/		如果列名不知道可以用如下方法获取。
		//获取结果集列数和行数!
		
		rs.last();//将光标设置到最后一行
		int row = rs.getRow();//获取行数
		rs.beforeFirst();//将光标移到初始位置
		
		//获取结果列的列数。
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();	//获取结果集列数
		String columnName = rsmd.getColumnName(1);	//获取第一列的名称
		
		System.out.println("共有"+row+"行数据,并且有"+columnCount+"列,第1列列名是"+columnName);
		
		
		//获取所有数据
		while (rs.next()) {
			for (int i = 1; i <= columnCount; i++) {
				//String cName = rsmd.getColumnName(i);//获得每列的名称。
				Object o = rs.getObject(i);
				
				System.out.print(o + "  ");
			}
		}
		
		/*
		 * 资源关闭顺序:
		 * 想得到的后关闭!
		 */
		rs.close();
		statement.close();
		connection.close();
		
	}
}



如何防止SQL攻击:

preparedStatement(预编译声明)

查询api可以知道preparedStatement接口是接口Statement的子接口,使用它有以下好处:

l  防止SQL攻击;

l  提高代码的可读性,以可维护性;

l  提高效率。


使用方法及代码规范化:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.junit.Test;

public class MyPreparadStatementTest {
	/**
	 * 使用preparadStatement(预编译声明)进行的增删改查!
	 */
	@Test
	public void insert() {
		Connection con = null;
		PreparedStatement pStatement = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			//使用sql模板,问好对应下面setXXX();的第一个参数,从1开始。。
			String sql = "insert into test1 values(?,?,?,?)";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setInt(1, 3);
			pStatement.setString(2, "吾王");
			pStatement.setString(3, "18");
			pStatement.setString(4, "898989898");
			
			//调用execute(),可以执行添加、修改、删除操作。
			pStatement.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	
	@Test
	public void update() {
		Connection con = null;
		PreparedStatement pStatement = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			
			String sql = "update test1 set name = ?,qq = ?,age = ? where id = ?";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setString(2, "898989898");
			pStatement.setString(1, "saber");
			pStatement.setString(3, "16");
			pStatement.setInt(4, 3);
			
			pStatement.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	@Test
	public void delete() {
		Connection con = null;
		PreparedStatement pStatement = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			
			String sql = "delete from test1 where id = ?";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setInt(1, 1);
			
			pStatement.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	@Test
	public void query() {
		Connection con = null;
		PreparedStatement pStatement = null;
		ResultSet rs = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			
			String sql = "select * from test1 where name = ? or age = ?";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setString(1, "saber");
			pStatement.setString(2, "18");
			
			rs = pStatement.executeQuery();
		
			
			//获取列。。遍历结果集
			ResultSetMetaData metaData = rs.getMetaData();
			int count = metaData.getColumnCount();
			
			while (rs.next()) {
				for (int i = 1; i <= count; i++) {
					Object object = rs.getObject(i);
					System.out.println("查询结果是:"+object);
				}
			}
			
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					/*
					 * 资源关闭顺序:
					 * 先得到的后关闭!
					 * 一定要关闭资源!
					 */
					if(rs != null)rs.close();
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值