目录
1.什么是JDBC?
2.JDBC运行原理
3.JDBC开发步骤
4.常见API详解
5.实现增删改查
6.登录验证(SQL注入问题)
7.PreparedStatement接口(解决SQL注入问题)
8.DAO开发
java database connectivity(java连接数据库技术),是sun公司为了简化开发,设计的一套数据库连接管理规范,主要由一些接口组成。
JDBC运行原理如下图所示:
步骤
代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.jdbc.Driver;
public class Test {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//1.注册驱动
DriverManager.registerDriver(new Driver());
//2.建立连接
conn = DriverManager.getConnection(
//?useSSL=true 加密传输,保证数据安全
"jdbc:mysql://localhost:3306/mysql?useSSL=true",
"root",
"root");
System.out.println(conn);
//3.发送sql命令
String sql = "select * from student";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//4.获取响应并处理
while(rs.next()){//获取记录
//逐列获取数据
int sid = rs.getInt("sid");
String sname = rs.getString("sname");
int cid = rs.getInt("cid");
System.out.printf("sid:%s,sname:%s,cid:%s\n",sid,sname,cid);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//5.释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
常见类及接口:
DriverManager:
作用:注册和管理驱动程序;获取连接对象。
示例:
//注册驱动的两种方式:
//1.通过DriverManager进行注册
DriverManager.registerDriver(new Driver());
//2.加载类的时候静态改代码块里面调用下面的代码进行驱动注册
Class.forName("com.mysql.jdbc.Driver");//(建议使用)
//通过DriverManager获取数据库连接
conn = DriverManager.getConnection(url,user,password);
Connection:
作用:作为数据传输通道;用于创建发送sql命令的对象Statement或PreparedStatement。
常用方法:
//设置自动提交
conn.setAutoCommit();
conn.commit();
conn.rollback();
//创建发送sql命令的对象
conn.createStatement();
conn.prepareStatement(sql);//PreparedStatement接口是Statement 接口的子接口
conn.prepareCall(sql);//CallableStatement接口是Statement 接口的子接口 用于调用存储过程
//元数据:解释数据的数据
DatabaseMetaData md = conn.getMetaData();
String dpn = md.getDatabaseProductName();
String driverName = md.getDriverName();
String url = md.getURL();
String username = md.getUserName();
Statement:
作用:发送sql指令
子接口:PreparedStatement(用于替换父接口) 和 CallableStatement(调用存储过程)
常用方法:
ResultSet:
作用:底层封装指向结果集的游标,可以获取结果集中的数据
常用方法:
登录验证中的问题?使用Statement对象发送sql指令时,利用检验不合格、不充分绕过验证,从而完成SQL注入。
何为SQL注入?
//定义sql字符串
String sql = "select * from user where uname='"+uname+"' and password='"+password+"'";
//若uname和password的值如下:
String username="' or 1=1 or '";
String password="";
//将uname和password传入上面的sql字符串,将得到如下SQL语句
sql = "select * from user where uname='' or 1=1 or '' and password=''";
//这条sql语句的过滤条件是恒成立的,所以,一定会有查询结果,从而无法达到验证登录的效果
SQL注入产生的原因?利用sql的拼接。
如何解决SQL注入问题?使用PreparedStatement接口发送sql指令,即可解决,具体见下文。
什么是PreparedStatement?
示例代码:
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
String sql = "select * from userinfo where username=? and password=?";
//预编译(语法、语义等检查)
ps = conn.prepareStatement(sql);
//赋值
ps.setString(1, username);
ps.setString(2, password);
rs = ps.executeQuery();
if (rs.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
什么是DAO?data access object,即数据访问对象,被定义成接口,专门用于对数据库表的进行增删改查操作。
什么是DAO开发?sun公司提出三层开发架构,其中数据持久层是实现与数据库的交互,因此数据持久层开发称为DAO开发。
如何进行DAO开发?
dao开发:由接口+实现类组成,每个接口只做一件事,对某一张表进行增删改查操作(松耦合,尽可能避免依赖某一个具体类)
步骤:
包、接口与类:
完整代码:
package entity;
public class User {
private int uid;
private String uname;
private String password;
public User(){}
public int getUid() {
return uid;
}
public User setUid(int uid) {
this.uid = uid;
return this;
}
public String getUname() {
return uname;
}
public User setUname(String uname) {
this.uname = uname;
return this;
}
public String getPassword() {
return password;
}
public User setPassword(String password) {
this.password = password;
return this;
}
@Override
public String toString() {
return "User [uid=" + uid + ", uname=" + uname + ", password=" + password + "]";
}
}
package dao;
import java.util.List;
import entity.User;
public interface UserDao {
//增删改查
int insert(User user);
int delete(User user);
int update(User user);
List select(User user);
List queryAll();
}
package dao;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
import util.JdbcUtils;
public class BaseDao {
private Connection conn;
private PreparedStatement ps;
private ResultSet rs;
//通用增删改方法
public int excuteUpdate(String sql, Object[] objects){
int res = 0;
try {
//获取数据库连接
conn = JdbcUtils.getConnection();
//获取执行sql的对象
ps = conn.prepareStatement(sql);
for(int i=0; i List excuteQuery(String sql, Object[] objects, Class clz){
List res = new ArrayList<>();
try {
//获取数据库连接
conn = JdbcUtils.getConnection();
//获取执行sql的对象
ps = conn.prepareStatement(sql);
for(int i=0; i
package dao.impl;
import java.util.List;
import dao.*;
import entity.User;
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public int insert(User user) {
String sql = "insert into user(uname,password) values(?,?)";
Object[] objects = {user.getUname(),user.getPassword()};
return excuteUpdate(sql, objects);
}
@Override
public int delete(User user) {
String sql = "delete from user where uid=?";
Object[] objects = {user.getUid()};
return excuteUpdate(sql, objects);
}
@Override
public int update(User user) {
String sql = "update user set uname=?,password=? where uid=?";
Object[] objects = {user.getUname(),user.getPassword(),user.getUid()};
return excuteUpdate(sql, objects);
}
@Override
public List select(User user) {
String sql = "select * from user where uname=? and password=?";
Object[] objects = {user.getUname(),user.getPassword()};
return excuteQuery(sql, objects, User.class);
}
@Override
public List queryAll() {
String sql = "select * from user";
Object[] objects = {};
return excuteQuery(sql, objects, User.class);
}
}
package util;
import java.io.*;
import java.sql.*;
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 {
InputStream is =
JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
System.out.println(is);
Properties properties = new Properties();
properties.load(is);
is.close();
//1.注册驱动
driver = properties.getProperty("driver");
System.out.println(driver);
Class.forName(driver);
url = properties.getProperty("url");
System.out.println(url);
user = properties.getProperty("user");
System.out.println(user);
password = properties.getProperty("password");
System.out.println(password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//获取Connection连接
public static Connection getConnection() throws SQLException{
//2.获取数据库连接
return DriverManager.getConnection(url, user, password);
}
//关闭资源
public static void closeRes(ResultSet rs, PreparedStatement ps, Connection conn){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
jdbc.properties文件的内容,该文件要放置在src下面才能被正常访问。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bd1808?useSSL=true
user=root
password=root