JDBC(Java Database Connectivity)Java数据库连接,是Java语言中规范客户端程序来访问数据库的应用程序接口,提供了更新数据库的方法。
JDBC API既支持数据库访问的双层架构(C/S),同时也支持三层架构(B/S)
1. 加载驱动程序
加载MySQL驱动
Class.forName("com.mysql.jdbc.Driver");
加载Oracle驱动
Class.forName("oracle.jdbc.driver.OracleDriver")
2. 获取数据库连接
建立数据库连接:(三个参数分别为url, user, password)
MySQL数据库连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/user", "root", "root");
Oracle数据库连接
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "root", "root");
3. 创建Statement\PreparedStatement对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
4.Statement\PreparedStatement传参
preparedStatement.setObject(1, 1);
5.执行
JDBC中有三种执行方式
第一种:executeQuery();适用于查询语句执行,返回ResultSet对象
文档解释为:在这个PreparedStatement对象中执行SQL查询,并返回查询生成的ResultSet对象。
ResultSet resultSet = preparedStatement.executeQuery();
第二种:execute();适用于所有SQL语句,返回boolean 类型
文档解释:在这个PreparedStatement对象中执行SQL语句,该对象可以是任何类型的SQL语句。一些预处理语句返回多个结果;execute方法处理这些复杂的语句以及executeQuery和executeUpdate方法处理的简单语句。
boolean execute = preparedStatement.execute();
第三种:executeUpdate();适用于增删改SQL语句,返回int类型
文档解释:执行PreparedStatement对象中的SQL语句,该对象必须是SQL数据操作语言(DML)语句,如插入、更新或删除;或者不返回任何内容的SQL语句,例如DDL语句。
int update = preparedStatement.executeUpdate();
6.关闭连接
resultSet.close();
preparedStatement.close();
connection.close();
/**
* @author yly
* @ClassName Insert
* @Date 2020/2/28 14:40
* @Version 1.0
**/
public class Insert {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
connection.setAutoCommit(false);//JDBC中默认是true,自动提交事务
preparedStatement = connection.prepareStatement("insert into user (name,age) values(?,?)");
preparedStatement.setString(1, "yly");
preparedStatement.setString(2, "23");
preparedStatement.execute();
connection.commit();
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC中需要注意的是:
/**
* @author yly
* @ClassName Delete
* @Date 2020/2/28 14:48
* @Version 1.0
**/
public class Delete {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
connection.setAutoCommit(false);//JDBC中默认是true,自动提交事务
preparedStatement = connection.prepareStatement("delete FROM user where id = ?");
preparedStatement.setInt(1, 3);
preparedStatement.execute();
connection.commit();
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* @author yly
* @ClassName Update
* @Date 2020/2/28 14:54
* @Version 1.0
**/
public class Update {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
connection.setAutoCommit(false);//JDBC中默认是true,自动提交事务
preparedStatement = connection.prepareStatement("update user set name = ? where id = ?");
preparedStatement.setString(1, "aa");
preparedStatement.setInt(2, 1);
preparedStatement.executeUpdate();
connection.commit();
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* @author yly
* @ClassName Select
* @Date 2020/2/28 15:01
* @Version 1.0
**/
public class Select {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "zgwbgh959");
preparedStatement = connection.prepareStatement("select * from user where id =?");
preparedStatement.setObject(1, 1);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + "---" + resultSet.getString(2) + "--" + resultSet.getInt(3));
}
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(resultSet!=null){
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
查找数据注意事项:
由于JDBC连接有大量重复代码,所以可以写一个工具类JDBCUtil
mysqlDriver=com.mysql.jdbc.Driver
mysqlURL=jdbc:mysql://localhost:3306/test
mysqlUser=root
mysqlPwd=root
oracleDriver=oracle.jdbc.driver.OracleDriver
oracleURL=jdbc\:oracle\:thin\:@localhost\:1521\:orcl
oracleUser=root
oraclePwd=root
public class JDBCUtil {
static Properties pros = null; //可以帮助读取和处理资源文件中的信息
static { //加载JDBCUtil类的时候调用
pros = new Properties();
try {
pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getMysqlConn() {
try {
Class.forName(pros.getProperty("mysqlDriver"));
return DriverManager.getConnection(pros.getProperty("mysqlURL"),
pros.getProperty("mysqlUser"), pros.getProperty("mysqlPwd"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Connection getOracleConn() {
try {
Class.forName(pros.getProperty("oracleDriver"));
return DriverManager.getConnection(pros.getProperty("oracleURL"),
pros.getProperty("oracleUser"), pros.getProperty("oraclePwd"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void close(ResultSet rs, Statement ps, Connection conn) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement ps, Connection conn) {
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Connection conn) {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
SQL注入问题是一种恶意的注入攻击,可以执行恶意SQL导致数据库数据丢失,使用SQL注入可以绕过web应用程序的身份验证和授权,直接可以获取到数据库资料。
之前JDBC使用Statement对象执行SQL程序,假如有下面一段程序
public class demo02 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
statement = connection.createStatement();
String id= "5 or 1=1 ";
String sql = "delete from user where id="+id;
statement.execute(sql);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(connection!=null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(statement!=null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
其中使用Statement对象直接执行SQL
String id = "5 or 1=1 ";
String sql = "delete from user where id="+id;
statement.execute(sql);
则会导致数据库中的所有数据被删除。
现在将Statement对象换成PreparedStatement 对象之后,将SQL中的参数以?占位符的方式表示,可以完美解决SQL注入的问题。