💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ## 问题01:什么是JDBC? > 一套访问数据库的标准Java类库 > 一套用于执行SQL语句的Java API > 位于``` java.sql.* ```中 ![](https://img.kancloud.cn/fa/ed/faed4d564e092e744001091998035c4e_511x474.png) JDBC是Java访问数据库的标准规范(即定义接口),具体的实现由各大数据库厂商来实现或提供(即数据库驱动)。 * 建立连接 * 发送命令 * 处理数据 * 得到结果 ## 问题02:JDBC开发步骤。 ![](https://img.kancloud.cn/09/c4/09c4ba8217925ee9d7d0942a017522ec_664x748.png) ## 问题03:如何进行驱动注册? ``` public static Class<?> forName(String className) throws ClassNotFoundException ``` Returns the Class object associated with the class or interface with the given string name. Parameters: className - the fully qualified name of the desired class. Returns: the Class object for the class with the specified name. Throws: **ClassNotFoundException - if the class cannot be located** > 如果抛出ClassNotFoundException异常,那么可以检查一下数据库驱动(*.jar包)是否加载到项目的classpath中。如果已经加载了jar包,那么检查一下驱动路径是否完全正确(包名和类名大小写等)。 ## 问题04:Class.forName()和DriverManager.regist()有什么区别? > 在 com.mysql.jdbc.Driver中已经有一段静态代码块用于向 DriverManager注册一个Driver实例 > 采用DriverManager.registerDriver(Driver driver)方法,会造成Driver实例被注册两次 > 在开发过程中,建议采用Class.forName("包名.类名")的方式进行注册 ### 不同版本的driver > MySQL 5.5及之前版本: com.mysql.jdbc.Driver > MySQL 5.6及之后版本:com.mysql.cj.jdbc.Driver ## 问题05:如何获得数据库连接?(URL格式) ``` public static Connection getConnection(String url, String user, String password) throws SQLException ``` 根据给定的数据库URL、用户名及密码与数据库建立连接,并返回一个Connection,其中user为数据库用户名, password为数据库的密码。 ### 不同版本的url ![](https://img.kancloud.cn/da/82/da8274ed289ec818f4982396d9dd1534_1011x173.png) MySQL 5.6及之后版本的MySQL数据库的时区设定比中国时间早8个小时,需要在URL地址后面指定时区。 > mysql8.x的jdbc升级了,增加了时区(serverTimezone)属性,并且不允许为空。 ``` jdbc:mysql://hostname:port/databasename?serverTimezone=GMT%2B8 ``` ``` jdbc:mysql://[IP]:[PORT]/[DB]?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true ``` ## 问题06:Statement和PreparedStatement的创建和区别? ### 方法 | 方法 | 描述 | | --- | --- | | Statement createStatement() | 创建一个 Statement 对象来将 SQL 语句发送到数据库 | | PreparedStatement prepareStatement(String sql) | 创建一个 PreparedStatement 对象来将预编译的SQL语句发送到数据库 | | CallableStatement prepareCall(String sql) | 创建一个 CallableStatement 对象来调用数据库的存储过程 | | void setAutoCommit(boolean autoCommit) | 用于设置Connection对象的提交模式 | | void commit() | 用于提交事务 | | void rollback() | 用于回滚事务 | ### 区别 > PreparedStatement 接口继承于Statement接口 > 不仅拥有Statement接口中的所有方法,还针对带有参数的SQL语句的执行进行了扩展 > 创建和使用的时候注意参数 ## 问题07:什么是SQL注入式攻击?如何避免? > 所谓SQL注入式攻击,就是通过输入特定数据和字符来构造(或者影响)SQL命令,进而欺骗服务器执行恶意的SQL命令。 ### 示例:用户登录判断 假设当前用户输入的用户名保存在变量usr中,密码保存在变量pwd中, 使用SQL语句``` select * from user where name=' "+usr+" ' and password = ' "+pwd+" ' ```来进行判断。 当用户输入的用户名和密码为``` 1'or'1'='1 ```,SQL语句在拼接输入变量之后会变为: ``` select * from user where name='1'or'1'='1' and password = '1'or'1'='1' ``` 其中'1'='1' 为true,SQL语句的where条件将会失效,即只要数据表user存在数据,该SQL语句都能查询到结果,从而实现注入式攻击。 > 在实际的开发过程中,如果涉及到向SQL语句传递参数时,最好使用PreparedStatement接口进行实现。因为该接口不仅可以提高SQL的执行效率,还可以避免SQL语句的注入式攻击。 ## 问题08:PreparedStatement的优点有哪些? 1. 效率高 2. 易读性高 3. 可维护性高 4. 安全性高 ## 问题09:如何执行SQL语句?描述一下返回值? | 方法 | 描述 | | --- | --- | | boolean execute() | 执行的SQL语句有查询结果,则返回true,否则返回false | | ResultSet executeQuery() | 执行查询类型(select)的SQL语句 | | int executeUpdate() | 执行修改类型(insert、update、delete)的SQL语句 | ## 问题10:如何对ResultSet进行遍历? ![](https://img.kancloud.cn/6e/41/6e410deaa2f13d814138bc2cd1cd0043_740x396.png) ``` getXXX(String columnLabel) ``` columnLabel表示的是字段名称。 ``` getXXX(int columnIndex) ``` columnIndex表示列的索引,索引值从1开始。 ## 问题11:如何释放资源?释放资源的顺序。 ![](https://img.kancloud.cn/09/c7/09c7d3aaacc332885aaeac6a2aff454f_219x143.png) 顺序: ``` ResultSet → Statement(或PreparedStatement、CallableStatement)→ Connection ``` # 实践:数据库连接 ## 1. 实验目的 1. 能够在Java Web项目中连接MySQL数据库; 2. 能够实现数据库的连接与查询; 3. 能够根据实际开发抽象出数据库工具类优化开发; 4. 能够按照MVC模式对数据库进行查询和显示。 ## 2. 实验要求 1. 设计功能菜单“文件列表”、“文件检索”功能; 2. 使用FileMsg.java对文件表的信息进行封装; 3. 编写JDBCUtil工具类来加载驱动、封装无参获得连接方法以及重载资源释放方法; 4. 编写db.properties来保存数据库信息; 5. 编写ShowServlet作为控制层,实现对数据库的查询并将数据保存在域对象中; 6. 编写SearchServlet作为控制层,实现对数据库的模糊查询并将数据保存在域对象中; 7. 在show.jsp视图层显示域对象中的用户数据。 ## 3. 实验内容 ### 1. 设计菜单栏 ![](https://img.kancloud.cn/f6/a5/f6a555c199d49294def888b2179cd7ea_713x104.png) ### 2. 编写映射类 ![](https://img.kancloud.cn/fb/08/fb081799513b0393d24c7490e14d36b2_293x199.png) ### 3. 编写数据库配置文件 ![](https://img.kancloud.cn/33/dc/33dc842d3ccdde8feabed5851f7e09ed_377x138.png) ### 4. 编写数据库工具类 ![](https://img.kancloud.cn/9d/08/9d08b38b515ea088ef01756576888936_715x272.png) ### 5. 编写显示页面show.jsp 1. 如果没有文件则显示空白提示 ![](https://img.kancloud.cn/ad/22/ad22a75852e64afbfe683461d7c18a34_1257x228.png) 2. 如果有内容则显示文件信息 ![](https://img.kancloud.cn/de/bf/debfbfc07d16b9f012b38257d42dc429_1215x480.png) ### 6. 编写查询所有控制器ShowServlet ![](https://img.kancloud.cn/b6/04/b6042311b8cf33536c02f7fa35b05194_1237x842.png) ### 7. 编写模糊查询控制器SearchServlet ![](https://img.kancloud.cn/b6/0e/b60e823898caba310814168b88229fdc_1263x303.png)