尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

JavaWeb01

JavaWeb01
📅 发布时间:2026/6/19 10:35:35

1.JavaWeb介绍

什么是JavaWeb?

  • Web:全球广域网,也称万维网(www),能够通过浏览器访问的网站
  • JavaWeb:使用Java技术来解决相关web互联网领域的技术栈

image

  1. 网页:展现数据
  2. 数据库:存储和管理数据
  3. JavaWeb程序:逻辑处理

数据库已学习

2.JDBC

  • JDBC就是使用Java语言操作关系型数据库的一套API

image

2.1、JDBC简介

JDBC概念

  • JDBC就是使用Java语言操作关系型数据库的一套API
  • 全称:(Java DataBase Connectivity)Java数据库连接

JDBC本质:

  • 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
  • 各个数据库厂商去实现这套接口,提供数据库驱动jar包
  • 我们可以使用这套接口(JDBC)编程,真正执行代码的是驱动jar包中的实现类

JDBC的好处:

  • 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
  • 可随时替换底层数据库,访问数据库的Java代码基本不变

image

2.2、JDBC快速入门

步骤:

  1. 创建工程,导入驱动jar包

    image

  2. 注册驱动

    Class.forName("com.mysql.jdbc.Driver");
    
  3. 获取连接

    Connection conn = DriverManager.getConnection(url,username,password);
    
  4. 定义SQL语句

    String sql = "update..."
    
  5. 获取执行SQL对象

    Statement stmt = conn.createStatement();
    
  6. 执行SQL

    stmt.executeUpdate(sql);
    
  7. 处理返回结果

  8. 释放资源

package com.itheima.jdbc;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;public class JDBCDemo {public static void main(String[] args) throws Exception {// 1.注册驱动Class.forName("com.mysql.jdbc.Driver");// 2.获取连接String url = "jdbc:mysql://127.0.0.1:3306/itheima";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);// 3.定义sqlString sql = "update account set money = 2000 where id = 1";// 4.获取执行sql的对象 StatementStatement stmt = conn.createStatement();// 5.执行sqlint count = stmt.executeUpdate(sql);//受影响的行数// 6.处理返回结果System.out.println(count);// 7.释放资源stmt.close();conn.close();}
}

image

2.3、JDBC API详解

(1)DriverManager

  • DriverManager(驱动管理类)作用:

    1. 注册驱动

      Class.forName("com.mysql.jdbc.Driver");
      
      • 查看Driver类源码

        image

        提示:

        • MySQL 5之后的驱动包,可以省略注册驱动的步骤
        • 自动加载jar包中的META-INF/services/java.sql.Driver文件中的驱动类
    2. 获取数据库连接

      image

      • 参数

        1. url:连接路径

          语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
          示例:jdbc:mysql://127.0.0.1:3306/itheima
          细节:
          1.如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称?参数键值对
          2.配置 useSSL = false参数,禁用安全连接方式,解决警告问题
          
        2. user:用户名

        3. password:密码

      package com.itheima.jdbc;import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.Statement;/*** JDBC API详解:DriverManager*/
      public class JDBCDemo2_DriverManager {public static void main(String[] args) throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///itheima?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);// 3.定义sqlString sql = "update account set money = 2000 where id = 1";// 4.获取执行sql的对象 StatementStatement stmt = conn.createStatement();// 5.执行sqlint count = stmt.executeUpdate(sql);//受影响的行数// 6.处理返回结果System.out.println(count);// 7.释放资源stmt.close();conn.close();}
      }

(2)Connection

  1. 获取执行SQL的对象

    • 普通执行SQL对象

      Statement createStatement()
      
    • 预编译SQL的执行SQL对象:防止SQL注入

      PreparedStatement prepareStatement(sql)
      
    • 执行存储过程的对象

      CallableStatement prepareCall(sql)
      
  2. 事务管理

    • MySQL事务管理

      开启事务:begin;/start transaction;
      提交事务:commit
      回滚事务:rollback;MySQL默认自动提交事务
      
    • JDBC事务管理:Connection接口中定义了3个对应的方法

      开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务
      提交事务:commit()
      回滚事务:rollback()
      
    package com.itheima.jdbc;import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;/*** JDBC API详解:Connection*/
    public class JDBCDemo3_Connection {public static void main(String[] args) throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///itheima?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);// 3.定义sqlString sql1 = "update account set money = 3000 where id = 1";String sql2 = "update account set money = 3000 where id = 2";// 4.获取执行sql的对象 StatementStatement stmt = conn.createStatement();try {//开启事务conn.setAutoCommit(false);// 5.执行sqlint count1 = stmt.executeUpdate(sql1);//受影响的行数// 6.处理返回结果System.out.println(count1);// 5.执行sqlint count2 = stmt.executeUpdate(sql2);//受影响的行数// 6.处理返回结果System.out.println(count2);//提交事务conn.commit();} catch (Exception throwables) {//事务回滚conn.rollback();throwables.printStackTrace();}// 7.释放资源stmt.close();conn.close();}
    }

    使用try catch 来捕捉异常,一旦在sql语句执行过程中出现异常,进行事务回滚。

    如:

    try {//开启事务conn.setAutoCommit(false);// 5.执行sqlint count1 = stmt.executeUpdate(sql1);//受影响的行数// 6.处理返回结果System.out.println(count1);int i = 3/0;// 5.执行sqlint count2 = stmt.executeUpdate(sql2);//受影响的行数// 6.处理返回结果System.out.println(count2);//提交事务conn.commit();} catch (Exception throwables) {//事务回滚conn.rollback();throwables.printStackTrace();}
    

    在第9行代码中 出现int i= 3/0 异常,account表中还是保持原来的数据不变,若没有开启事务,则会将第一条数据改为3000;

(3)Statement

  • Statement作用:

    1. 执行SQL语句
  • 执行SQL语句

    int executeUpdate(sql):执行DML、DDL语句返回值:(1)DML语句影响的行数(2)DDL语句执行后,执行成功也可能返回0
    
    ResultSet executeQuery(sql):执行DQL语句返回值:ResultSet结果集对象
    
    • 执行DML语句
    package com.itheima.jdbc;import org.junit.Test;import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;/*** JDBC API详解:Statement*/
    public class JDBCDemo4_Statement {@Testpublic void testDML() throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///itheima?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url, username, password);// 3.定义sqlString sql1 = "update account set money = 3000 where id = 2";String sql2 = "insert into account values (3,'王五',1000)";// 4.获取执行sql的对象 StatementStatement stmt = conn.createStatement();// 5.执行sqlint count1 = stmt.executeUpdate(sql1);//执行完DML语句,受影响的行数int count2 = stmt.executeUpdate(sql2);//执行完DML语句,受影响的行数// 6.处理返回结果//System.out.println(count);if (count1 > 0) {System.out.println("修改成功");} else {System.out.println("修改失败");}if (count2 > 0) {System.out.println("添加成功");} else {System.out.println("添加失败");// 7.释放资源stmt.close();conn.close();}}
    }
    • 执行DQL语句

      image

(4)ResultSet

  • ResultSet(结果集对象)作用:

    1. 封装了DQL查询语句的结果
    ResultSet stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象
    
  • 获取查询结果

    boolean next():
    (1)将光标从当前位置向下移动一行 
    (2)判断当前行是否为有效行返回值:true:有效行,当前行有数据false:无效行,当前行没有数据
    
    xxx getXxx(参数):获取数据xxx:数据类型;如:int getInt(参数);String getString(参数)参数:int:列的编号,从1开始String:列的名称
    
  • 使用步骤

    1. 游标向下移动一行,并判断该行是否有数据:next()
    2. 获取数据:getXxx(参数)
    //循环判断游标是否是最后一行末尾
    while(rs.next()){//获取数据rs.getXxx(参数);
    }
    

    image

案例:

image

步骤:

  1. 定义实体类Account

    package com.itheima.pojo;public class Account {private int id;private String name;private double money;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
    }
  2. 查询数据,封装到Account对象中

  3. 将Account对象存入ArrayList集合中

package com.itheima.jdbc;import com.itheima.pojo.Account;
import org.junit.Test;import java.sql.*;
import java.util.ArrayList;
import java.util.List;/*** JDBC API详解:ResultSet*/
public class JDBCDemo5_ResultSet {/*** 执行DQL* @throws Exception*/@Testpublic void testResultSet() throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///itheima?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);//3.定义SQLString sql = "select * from account";//4.获取statement对象Statement stmt = conn.createStatement();//5.执行sqlResultSet rs = stmt.executeQuery(sql);//6.处理结果,遍历rs中所有数据// 6.1光标向下移动一行,并判断该行是否有数据while(rs.next()){//6.2获取数据 getXxx()int id = rs.getInt(1);String name = rs.getString(2);double money = rs.getDouble(3);System.out.println(id);System.out.println(name);System.out.println(money);System.out.println("------------------------");}//7.释放资源rs.close();stmt.close();conn.close();}/*** 查询account账户表数据,封装为Account对象中,并且存储到Arraylist集合中* 1.定义实体类Account* 2.查询数据,封装到Account对象中* 3.将Account对象存入ArrayList集合中* @throws Exception*/@Testpublic void testResultSet2() throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///itheima?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);//3.定义SQLString sql = "select * from account";//4.获取statement对象Statement stmt = conn.createStatement();//5.执行sqlResultSet rs = stmt.executeQuery(sql);//创建集合List<Account> list = new ArrayList<>();//6.处理结果,遍历rs中所有数据// 6.1光标向下移动一行,并判断该行是否有数据while(rs.next()){Account account = new Account();//6.2获取数据 getXxx()int id = rs.getInt(1);String name = rs.getString(2);double money = rs.getDouble(3);//赋值account.setId(id);account.setName(name);account.setMoney(money);// 存入集合list.add(account);}System.out.println(list);//7.释放资源rs.close();stmt.close();conn.close();}}

image

(5)PreparedStatement

  • PrepareStatement作用:
    1. 预编译SQL语句并执行:预防SQL注入问题
  • SQL注入
    • SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。

image

package com.itheima.jdbc;import org.junit.Test;import java.sql.*;/*** 用户登录*/
public class JDBCDemo6_UserLogin {@Testpublic void testLogin() throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///test?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);//接受用户输入的用户名和密码String name = "zhangsan";String pwd = "123";String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";//获取stmt对象Statement stmt = conn.createStatement();//执行sqlResultSet rs = stmt.executeQuery(sql);//判断登录是否成功if(rs.next()){System.out.println("登陆成功");}else {System.out.println("登陆成功");}// 7.释放资源rs.close();stmt.close();conn.close();}@Testpublic void testLogin_inject() throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///test?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);//接受用户输入的用户名和密码String name = "sajdhsad";String pwd = "'or '1' = '1";String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";System.out.println(sql);//获取stmt对象Statement stmt = conn.createStatement();//执行sqlResultSet rs = stmt.executeQuery(sql);//判断登录是否成功if(rs.next()){System.out.println("登陆成功");}else {System.out.println("登陆成功");}// 7.释放资源rs.close();stmt.close();conn.close();}}

第一个测试用例是输入正常的用户名和密码 显示登陆成功

但是第二个测试,用户名和密码并不正确,为何会显示登陆成功呢?

我们通过打印sql语句可以看到:

image

where条件后 username = 'sajdhsad' and password = ''这个条件为false。'1' = '1'恒等式 为true 则'sajdhsad' and password = ''or '1' = '1'为true 所以也显示登录成功,这就是SQL注入。PreparedStatement这个接口就是为了解决SQL注入的。

如何解决?

image

@Testpublic void testPreparedStatement() throws Exception {// 1.注册驱动//Class.forName("com.mysql.jdbc.Driver");// 2.获取连接 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,可以简化书写String url = "jdbc:mysql:///test?useSSL=false";String username = "root";String password = "wwh030705";Connection conn = DriverManager.getConnection(url,username,password);//接受用户输入的用户名和密码String name = "zhangsan";String pwd = "'or '1' = '1";//定义sql语句,其中的参数用?来代替String sql = "select * from tb_user where username = ? and password = ? ";//通过Connection对象获取,并传入对应的sql语句PreparedStatement pstmt = conn.prepareStatement(sql);//设置参数pstmt.setString(1,name);pstmt.setString(2,pwd);//执行sqlResultSet rs = pstmt.executeQuery();//判断登录是否成功if(rs.next()){System.out.println("登陆成功");}else {System.out.println("登陆失败");}// 7.释放资源rs.close();pstmt.close();conn.close();}

这样的话则登录失败~ 实质上是将敏感字符进行转移如密码中的单引号进行转义

image

相关新闻

  • SAM+ARM
  • 《代码大全2》观后感(二):需求分析——代码质量的“源头防线”
  • NRF54LM20A 芯片的优点

最新新闻

  • 阿拉善盟闲置黄金变现多少钱?本地5家回收门店最新报价参考 - 马刺总冠军
  • 华为OD机试真题 新系统【数据中心最佳维护窗口】
  • capl--static
  • 直播操作可视化:如何让观众清晰看到你的每一个精彩操作?
  • VisualCppRedist AIO终极指南:一站式解决Windows DLL错误的完整方案
  • FDE大模型实战指南:小白程序员必备高薪技能,速收藏!

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号