1 JDBC快速入门
1.1 JDBC概念
1.1.1 JDBC的概念
Java DataBase Connectivity(java数据库连接)是由一组用java语言编写的类和接口组成的用于执行sql语句的Java API,可以为多种关系型数据库提供统一访问。
1.1.2 JDBC的本质
jdbc其实就是java官方提供的一套规范,用于帮助开发人员快速实现不同关系型数据库的连接(通过java操作各种关系型数据库的接口,官方提供统一接口,各个数据库厂商分别编写实现类,实现类体现为导入的jar包)。
1.2 JDBC入门程序
1.2.1 jdbc使用步骤
- 导入相关jar包;
- 注册驱动;
- 获取数据库连接;
- 获取执行者对象;
- 执行sql语句并返回结果;
- 处理结果;
- 释放资源;
2 JDBC功能类详解
2.1 DriverManager驱动管理对象
2.1.1 注册驱动功能
代码实现:Class.forName("com.mysql.jdbc.Driver");
- 注:在DriverManager类的内部有注册驱动的静态方法registerDriver(),但此处无需手动调用该方法,因为该方法被封装到了Driver类中的静态代码块中,只要Driver类一被使用就会执行其静态代码块中的内容完成注册驱动。
2.1.2 获取数据库连接对象功能
1 代码实现:static Connection getConnection(String url,String user,String password);
2 参数:
url,指定连接的路径,例:jdbc:mysql://ip地址(域名):端口号/数据库名称;
user:数据库登录用户名;
password:数据库登录密码;
2.2 Connection数据库连接对象
2.2.1 获取执行者对象功能
1 获取普通执行者对象:Statement createStatement();
2 获取预编译执行者对象:PreparedStatement prepareStatement(String sql);
2.2.2 管理事务功能
1 开启事务:setAutoCommit(boolean autoCommit);
参数为false则开启事务。
2 提交事务:commit();
3 回滚事务:rollback();
2.2.3 释放资源功能
释放数据库连接对象,void close();
2.3 Statement执行sql语句的对象
2.3.1 执行DML语句
int executeUpdae(String sql);
- 返回值int:返回影响的行数;
- 参数:可以执行增删改sql语句;
2.3.2 执行DQL语句
ResultSet executeQuery(String sql);
- 返回值ResultSet:封装查询的结果;
- 参数:可以执行select语句;
2.3.3 释放资源
可以释放执行者对像:void close();
2.4 ResultSet结果集对象
2.4.1 判断结果集中是否还有数据
boolean next();
- 有数据返回true,并将索引向下移动一行;没有数据则返回false。
2.4.2获取结果集中的数据
数据类型1 get数据类型1(“列名”);
- 例:假设某个数据库中有一张user表,表中有int类型的id字段和varchar类型的name字段,若想要获取两个字段的值则可以调用结果集的该方法:
int getInt("age");
String getString("name");
2.4.3 释放资源
可以释放结果集对象:void close();
3 JDBC案例
使用JDBC完成对studnet表的CRUD操作
- 注:需要创建Student类,类中的成员变量要和数据库中student表的字段相对应。Student类的作用是封装数据库中查询出来的数据,类中所有基本数据类型需要使用对应的包装类,以免表中查询出来为null的数据无法赋值给Student。
4 JDBC工具类
-
工具类的抽取:
-
关于工具类:
1.工具类的构造方法应该私有化,且其内部的方法应该是静态的,可以通过类名点来调用
2.工具类中的异常最好全都try{}catch(){},而不是直接抛出; -
代码:
public class JDBCUtils {
/* 1.私有化该类的构造方法,目的是不允许其他类去创建该类的对象,因为 作为工具类,其内部的方法都是静态的,通过【类名点】来调用内部的方法 */ private JDBCUtils() {} //2.声明所要的配置变量 private static String driverClass; private static String url; private static String username; private static String password; private static Connection con; //3.提供静态代码块:读取配置文件中的信息赋值给相应变量,注册驱动 static { try { //读取配置文件中的信息赋值给相应变量 /*加载配置文件进内存,类加载器可以加载【SRC】路径下的文件 Properties集合中的load方法可以自动从流对象中加载文件中的信息 */ Properties pro = new Properties(); ClassLoader classLoader = JDBCUtils.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("config.properties"); pro.load(is); //读取配置文件中的数据,并赋值给声明的变量 driverClass = pro.getProperty("driverClass"); url = pro.getProperty("url"); username = pro.getProperty("username"); password = pro.getProperty("password"); //注册驱动 Class.forName(driverClass); } catch (Exception e) { e.printStackTrace(); } } //4.提供获取数据库连接的方法 public static Connection getConnection() { try { con = DriverManager.getConnection(url, username, password); } catch (SQLException e) { e.printStackTrace(); } return con; } //5.提供释放资源的方法【先获取的后释放】【因为参数个数的问题,要使用到方法的重载】 public static void close(Connection con, Statement stat, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stat != null) { try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (con != null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } } //对close方法进行重载,当执行增删改操作时,无结果集对象,无需释放ResultSet【因为参数个数的问题,要使用到方法的重载】 public static void close(Connection con, Statement stat) { if (stat != null) { try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (con != null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } }
}
-
5 SQL注入攻击
5.1什么是sql注入攻击
- 利用sql语句的漏洞来对系统进行攻击。
5.2 SQL注入攻击的原理
- 正常情况下密码框中所有的内容都应该是密码的的组成,但通过特定字符串的拼接,使得Statement对象在执行sql时将密码的部分内容当作查询条件来执行了。简单来说就是利用sql语句特定字符串的拼接使sql语句中的查询条件恒成立,进而来跳过权限验证。
5.3 SQL注入攻击的解决
- 使用预编译执行者对象PreparedStatement,将sql语句提前编译并设定参数,明确sql语句的格式。sql语句中的参数使用?作为占位符。
6 JDBC事务
-
JDBC管理事务
JDBC通过数据连接对象Connection对象来管理事务;- 开启事务:setAutoCommit(boolean autoCommit); 参数为false则开启事务;
- 提交事务:commit();
- 回滚事务:rollback();
注:事务的管理需在业务层进行而不是在dao层,因为dao 层的功能要给很多模块提供功能的支撑,而有些模块并不需要事务。