JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范
JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。
JDBC原理:
Java提供访问数据库规范称为JDBC,而生产厂商提供规范的实现类称为驱动。JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。
存在sql注入:
// 注册驱动 {使用Class.forName()利用反射将类加载到内存,该类的静态代码将自动执行}
--------------------------------------------------------------------------------------------------------
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
---------------------------------------------------------------------------------------------------------
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
String url = "jdbc:mysql://localhost:3306/datademo";
String user = "root";
String password = "123";
Connection conn = DriverManager.getConnection(url, user, password);
// 获得sql执行对象{存在sql注入}
Statement stat = conn.createStatement();
// 执行sql语句
Scanner sc = new Scanner(System.in);
String us = sc.next();
String ps = sc.next();
String sql = "SELECT * FROM word WHERE users='" + us + "' AND passwords='" + ps + "'";
/*
* //注入攻击 String sql = "SELECT * FROM word WHERE users='a' AND passwords='xx'OR 1=1";
* a xx'or'1=1
*/
System.out.println(sql);
//执行sql语句
ResultSet rs = stat.executeQuery(sql);
//处理结果集
while (rs.next()) {
System.out.println(rs.getString("users") + " " + rs.getString("passwords"));
}
//关闭资源
rs.close();
stat.close();
conn.close();
使用PreparedStatement预编译不存在sql注入:
//注册驱动{原理同上}
Class.forName("com.mysql.jdbc.Driver");
//获得连接
String url = "jdbc:mysql://localhost:3306/datademo";
String user = "root";
String password = "123";
Connection conn = DriverManager.getConnection(url, user, password);
Scanner sc = new Scanner(System.in);
String us = sc.next();
String ps = sc.next();
// 获得预处理对象{对sql语句进行预编译处理,并且对?占位符进行设置实际参数,不存在普通的sql注入}
String sql ="SELECT * FROM word WHERE users=? AND passwords=?";
PreparedStatement pst = conn.prepareStatement(sql);
//SQL语句占位符设置实际参数
pst.setString(1, us);
pst.setString(2,ps);
//执行SQL语句
ResultSet rs = pst.executeQuery();
//处理结果集
while(rs.next()) {
System.out.println(rs.getString("users")+" "+rs.getString("passwords"));
}
//关闭资源
rs.close();
pst.close();
conn.close();
实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池。
用池来管理Connection,这样可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。池就可以再利用这个Connection对象了。