技术概述
JDBC的作用:
Java DataBase Connectivuty 与数据库建立连接
了解数据库的信息
查询数据库
获取并显示结果集
更新数据库(数据的增删改)
JDBC访问数据库的过程
1、注册驱动
2、建立数据库连接(Connection)
3、准备SQL语句
4、获取SQL语句发送器(Statement)
5、发送并执行SQL语句,得到结果集(ResultSet)
6、处理结果集
7、关闭资源(ResultSet,Statement,Connection)
JDBC的常用接口
Java.sql.DriverManager用来装载驱动程序,并且为创建新的数据库联接提供支持。
Java.sql.Connection完成对某一指定数据库的连接
Java.sql.Statement在一个给定的连接中作为SQL执行声明的容器
Java.sql.ResultSet对于给定声明取得结果的途径
package com.xjion.jdbc;
import java.sql.*;
/**
* jdbc连接数据库,执行查询操作
* @Auther:xjion
* @Date:2019/10/15
* @Description:com.xjion.jdbc
* @version:1.0
*/
public class TestJdbcQuery {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test2", "root", "root");
//定义SQL语句
String sql = "select * from employee";
//创建sql发送器,是由连接对象创建的
Statement stmt = conn.createStatement();
//发送并执行sql语句,得到结果集
ResultSet rs = stmt.executeQuery(sql);
//处理结果集
while (rs.next()){
//取出该行的每一列数据,依据数据类型取值
int empno = rs.getInt(1);//数据库列索引从1开始
String ename = rs.getString("ename");
Date hiredate = rs.getDate(3);
System.out.println(empno + "\t" +ename + "\t" + hiredate.toLocaleString());
}
//关闭资源,先开的后关
rs.close();
stmt.close();
conn.close();
}
}
基于Statement对数据进行操作
package com.xjion.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* 基于Statement对数据库进行查询操作
* @author Administrator
*
*/
public class Test2 {
public static void main(String[] args) {
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test2", "root", "root");
//获取运行sql语句的对象
Statement st=conn.createStatement();
//初始化一个查询语句
String sql="select * from person ";
//执行sql语句
ResultSet rs=st.executeQuery(sql);
while(rs.next()){
//通过字段数去取值
// int id=rs.getInt(1);
// String name=rs.getString(2);
// int age=rs.getInt(3);
//通过字段名取值
int age=rs.getInt("age");
int id=rs.getInt("id");
String name=rs.getString("name");
System.out.println(id+"-"+name+"-"+age);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
SQL注入问题
当使用Statement拼接参数时会出现恒成立条件,造成SQL注入。
select * from user where uname="" and pwd="" or 1=1;
加上像or 1=1之类的恒成立条件时就会造成SQL注入问题,不管怎么样都能查出数据
使用安全性和效率更高的Preparedstatement替代Statement
Statement对象在每次执行sql语句时都将语句传给数据库,在多次执行同一个语句时,效率比较低.
Statement对象Sql注入引起安全问题
可以使用PreparedStatement,使用数据库的预编译功能,速度可以提高很多.避免sql注入引起的安全问题
PreparedStatement对象的sql语句可以接受参数,每次执行时可以传递不同的参数.
例如
创建
String sql=“select * from emp where ename=?”
PreparedStatement ps=conn.prepareStatement(sql);
执行
ps.setInt(1,”SMITH”);
ResultSet rs=pstmt.executeQuery();
关闭资源
public boolean valiUname(String uname) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test2", "root", "root");
//获取st对象
ps=conn.prepareStatement("select * from user where uname=?");
ps.setString(1, uname);
//执行sql语句
rs=ps.executeQuery();
//遍历结果集
while(rs.next()){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
rs.close();
ps.close();
conn.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return false;
}
关于JDBC的一个简单封装
1、在src下创建一个properties文件
driverName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test2
username=root
password=root
2、封装DBUtil
package com.xjion.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class DBUtil {
/**
* 初始化数据库的资源
*/
private static String driver;
private static String url;
private static String username;
private static String password;
/**
* 通过静态块,加载数据库的资源和加载驱动
*/
static{
try {
//读取properties文件中的数据库信息
Properties properties=new Properties();
//指定读取db.properties文件
properties.load(DBUtil.class.getResourceAsStream("/db.properties"));
//读取配置的值
driver=properties.getProperty("driverName");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 关闭数据库资源
* @param objs
*/
public static void close(Object...objs){
if(objs!=null){
for(Object obj:objs){
try {
if(obj instanceof Connection){
((Connection)obj).close();
}else if(obj instanceof PreparedStatement){
((PreparedStatement)obj).close();
}else if(obj instanceof ResultSet){
((ResultSet)obj).close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 获取数据库的连接
* @return
*/
public static Connection getConn(){
Connection conn=null;
try {
conn=DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void main(String[] args) {
DBUtil.getConn();
}
}
3、使用
public boolean valiUname(String uname) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
boolean result=false;
try {
conn=DBUtil.getConn();
ps=conn.prepareStatement("select * from user where uname=?");
ps.setString(1, uname);
rs=ps.executeQuery();
result=rs.next();
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.close(rs,ps,conn);
}
return result;
}