• JavaWeb、JDBC


    目录

    一、JDBC简介

    二、JDBC快速入门

    三、JDBC API详解

    1、DriverManager

     2、Connection

           2.1、获取执行SQL的对象

                    SQL注入

                    preparedStatement 防止SQL注入

                    PreparedStatement原理

          2.2、 事务管理

    3、Statement

    4、ResultSet

    四、数据库连接池

    1、数据库连接池简介​编辑

    2、Druid数据库连接池

    五、JDBC增删改查练习

    1、JDBC查询

    2、JDBC添加

    3、JDBC修改

    4、JDBC删除


    一、JDBC简介

    面向接口编程

    二、JDBC快速入门

    1. public class JdbcDemo1 {
    2. public static void main(String[] args) throws Exception {
    3. //1、注册驱动
    4. //将Driver加载进程序中,mysql驱动5之后可以不写这段代码
    5. //Class.forName("com.mysql.jdbc.Driver");
    6. //2、获取连接
    7. /**
    8. * jdbc:mysql: 固定格式
    9. * localhost:3306 mysql服务器所在的主机ip和端口号
    10. * student 数据库名称
    11. * characterEncoding=utf8 字符集使用utf-8
    12. * useSSL=false 是否加密
    13. */
    14. String url = "jdbc:mysql://localhost:3306/student?/characterEncoding=utf8&useSSL=false";
    15. String username = "root"; //数据库用户名
    16. String password = "123456"; //数据库密码
    17. Connection con = DriverManager.getConnection(url,username,password);
    18. //3、定义sql语句
    19. String sql = "update account set money = money + 500 where name = \"李四\"";
    20. //4、获取执行sql的对象 Statement
    21. Statement stmt = con.createStatement();
    22. //5、执行sql,返回受影响的行
    23. int i = stmt.executeUpdate(sql);
    24. //6、输出结果
    25. System.out.println(i);
    26. //7、释放资源
    27. con.close();
    28. stmt.close();
    29. }
    30. }

    三、JDBC API详解

    1、DriverManager

     

     2、Connection

           2.1、获取执行SQL的对象

    SQL注入

    1. String name = "张三";
    2. //模拟SQL注入
    3. //原理:select * from user where username='张三' and password='' or '1' = '1'
    4. //不论这个输入的用户名或者密码是否正确,他都会成功登录系统后台,因为通过拼接or使得左右两边只要有一个为真值就为真
    5. //而1=1为真,所以会被系统判断为真
    6. String pwd = "'or '1' = '1";
    7. //3、定义sql语句
    8. //通过字符串拼接查询输入的信息
    9. String sql = "select * from user where username='"+name+"' and password='"+pwd+"'";
    10. Statement stmt = con.createStatement();
    11. ResultSet rs = stmt.executeQuery(sql);
    12. if (rs.next()){
    13. System.out.println("登陆成功!");
    14. System.out.println(rs.getString("username"));
    15. System.out.println(rs.getString("password"));
    16. System.out.println(rs.getString("product"));
    17. }else {
    18. System.out.println("登陆失败!");
    19. }
    20. //7、释放资源
    21. con.close();
    22. stmt.close();

    preparedStatement 防止SQL注入

    1. //3、定义sql语句
    2. String name = "张三";
    3. String pwd = "12345";
    4. String sql = "select * from user where username = ? and password = ?";
    5. //4、创建PreparedStatement防止sql注入
    6. PreparedStatement psmt = con.prepareStatement(sql);
    7. //5、设置问号参数
    8. //防止SQL注入 会将输入的敏感字符进行转义,会将注入语句'or '1' = '1 变成 \'or \'1\' = \'1 使它只能是一个符号而不参与运算
    9. psmt.setString(1,name);
    10. psmt.setString(2,pwd);
    11. //6、执行sql语句
    12. ResultSet rs = psmt.executeQuery();
    13. //7、处理结果
    14. if (rs.next()){
    15. System.out.println("登陆成功");
    16. }else {
    17. System.out.println("登陆失败");
    18. }
    19. //8、释放资源
    20. psmt.close();
    21. con.close();

    PreparedStatement原理

    直接将SQL语句写死,select * from tb_user where name = '张三';这样每次写一条语句都要经过检查、编译、执行会降低系统性能,而使用预编译SQL,参数采用符号代替,它只需要预编译这个带占位符?的语句一次,接收参数值后进行执行,使系统性能更高。

    开启预编译

    url中添加:useServerPrepStmts=true
    1. //2、获取连接
    2. //useServerPrepStmts=true 开启预编译
    3. String url = "jdbc:mysql://localhost:3306/student?/characterEncoding=utf8&useSSL=false&useServerPrepStmts=true";
    4. String username = "root"; //数据库用户名
    5. String password = "123456"; //数据库密码
    6. Connection con = DriverManager.getConnection(url,username,password);
    7. //3、定义sql语句
    8. String name = "张三";
    9. String pwd = "'or '1' = '1";
    10. String sql = "select * from user where username = ? and password = ?";
    11. //4、创建PreparedStatement防止sql注入
    12. PreparedStatement psmt = con.prepareStatement(sql);
    13. //5、设置问号参数
    14. //防止SQL注入 会自动将输入的字符进行转义,会将注入语句'or '1' = '1 变成 \'or \'1\' = \'1 使它只能是一个符号而不参与运算
    15. psmt.setString(1,name);
    16. psmt.setString(2,pwd);
    17. //6、执行sql语句
    18. ResultSet rs = psmt.executeQuery();

      2.2、 事务管理

    1. try {
    2. //开启事务
    3. con.setAutoCommit(false);
    4. //执行sql,返回受影响的行
    5. int i1 = stmt.executeUpdate(sql1);
    6. //输出结果
    7. System.out.println(i1);
    8. //中间出错,事务回滚
    9. int i = 4/0;
    10. //执行sql,返回受影响的行
    11. int i2 = stmt.executeUpdate(sql2);
    12. //输出结果
    13. System.out.println(i2);
    14. //没有出错提交事务
    15. con.commit();
    16. } catch (Exception e) {
    17. //出错了回滚事务
    18. con.rollback();
    19. }finally {
    20. //7、释放资源
    21. con.close();
    22. stmt.close();
    23. }
    24. }

    3、Statement

    1. //3、定义sql语句
    2. String sql = "INSERT INTO account VALUES(NULL,'王五',2000); ";
    3. //4、获取执行sql的对象 Statement
    4. Statement stmt = con.createStatement();
    5. //5、执行sql语句,返回受影响的行
    6. int i = stmt.executeUpdate(sql);
    7. //6、处理结果,执行DML的sql语句,可以通过判断结果是否大于0判断是否执行成功
    8. //处理DDL的sql语句不可以,执行成功也可能返回0,比如删除数据库
    9. if(i > 0){
    10. System.out.println("执行成功");
    11. }else {
    12. System.out.println("执行失败");
    13. }

    4、ResultSet

    它是用来封装Statement查询的结果再通过方法调用输出查询的结果。

    ResultSet会将表的查询结果封装起来,其内部有一个游标,默认位置在当前数据的上一行,获取数据时,它会判断当前行是否是有效行。

    1. //新建sql语句
    2. String sql = "select * from account";
    3. //获取statement对象
    4. Statement stmt = con.createStatement();
    5. //执行sql
    6. ResultSet rs = stmt.executeQuery(sql);
    7. //打印查询结果
    8. //光标向下移动一行,并判断是否有数据
    9. while(rs.next()){
    10. //获取该行的字段
    11. //通过id获取字段
    12. System.out.println(rs.getInt(1));
    13. //System.out.println(rs.getString(2));
    14. //也可以通过对应列的名称获取
    15. System.out.println(rs.getString("name"));
    16. System.out.println(rs.getDouble(3));
    17. System.out.println("-----------------------");
    18. }
    19. //释放资源
    20. //后启动先释放
    21. stmt.close();
    22. con.close();
    23. }

    1. public class JdbcTest {
    2. //创建一个静态容器
    3. public static final List accounts = new ArrayList<>();
    4. public static void main(String[] args) throws Exception {
    5. //将数据库中的数据查询到java容器中
    6. Class.forName("com.mysql.jdbc.Driver");
    7. //1、获取数据库连接
    8. String url = "jdbc:mysql://localhost:3306/student?/charaterEncoding=utf-8&useSSL=false";
    9. String usernamme = "root";
    10. String password = "123456";
    11. Connection con = DriverManager.getConnection(url,usernamme,password);
    12. //2、创建sql语句
    13. String sql = "select * from account";
    14. //3、创建Statement
    15. Statement stmt = con.createStatement();
    16. //4、执行sql语句
    17. ResultSet rs = stmt.executeQuery(sql);
    18. //5、处理查询结果
    19. while (rs.next()){
    20. int id = rs.getInt("id");
    21. String name = rs.getString("name");
    22. double money = rs.getDouble("money");
    23. //将获取到的数据封装成账户对象
    24. Account account = new Account(id,name,money);
    25. //将账户对象放入容器
    26. accounts.add(account);
    27. }
    28. //6、对集合容器进行遍历输出
    29. System.out.println(accounts);
    30. }
    31. }

    四、数据库连接池

    1、数据库连接池简介

     在不使用数据库连接池与数据库交互时,每来一个用户请求,就需要创建一个数据库连接,用户使用完后关闭连接,由于开启数据库连接是个非常耗时的工作,而关闭连接也需要消耗资源,无法进行资源复用,就相当于招聘一个饭店服务员,服务员将客户带到空余座位后就将这个服务员开除,因此非常消耗资源,所以引入数据库连接池,处理一个用户的请求后再回到连接池中,不会关闭这个连接,继续等待下一个客户请求,如果数据库连接池中的所有连接都被占用了,再来一个客户会进行等待,并且连接池中会对当前正在进行的连接进行筛查,一旦发现某一个连接处于静止或者睡眠(后台)状态,就会强制断开这个连接,并归还到连接池,处理下一个请求的客户,避免数据库连接遗漏。

    2、Druid数据库连接池

    1. public class DruidDemo1 {
    2. //使用数据库连接池
    3. public static void main(String[] args) throws Exception {
    4. //1、导入jar包
    5. //2、修改配置文件
    6. //3、加载配置文件
    7. Properties prop = new Properties();
    8. prop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
    9. //4、获取连接池对象
    10. DataSource ds = DruidDataSourceFactory.createDataSource(prop);
    11. //5、获取数据库连接
    12. Connection conn = ds.getConnection();
    13. System.out.println(conn);
    14. }
    15. }
    1. #配置文件
    2. driverClassName=com.mysql.jdbc.Driver
    3. url=jdbc:mysql://localhost:3306/student?useSSL=false&useServerPrepStmts=true
    4. username=root
    5. password=12345
    6. #初始化连接数量
    7. initialSize=5
    8. #最大连接数
    9. maxActive=10
    10. #最大等待时间
    11. maxWait=3000

    五、JDBC增删改查练习

    1. /**
    2. * 由于使用int类型默认为0会对结果造成影响,改用包装类Integer默认为null
    3. * 在实体类中建议基本信息类型使用包装类
    4. */
    5. public class Brand {
    6. //主键
    7. private Integer id;
    8. //品牌名称
    9. private String brandName;
    10. //公司名称
    11. private String companyName;
    12. //排名
    13. private Integer ordered;
    14. //公司口号
    15. private String description ;
    16. //状态 0表示禁用 1表示启用
    17. private Integer status;

    1、JDBC查询

    1. public class JdbcSelectAll {
    2. private List brandList = new ArrayList<>();
    3. //查询数据库中的所有用户
    4. @Test
    5. public void BrandTest() {
    6. try {
    7. Properties pop = new Properties();
    8. //修改配置文件
    9. pop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
    10. //创建连接池
    11. DataSource dataSource = DruidDataSourceFactory.createDataSource(pop);
    12. //获取数据库连接
    13. Connection con = dataSource.getConnection();
    14. //定义sql语句
    15. String sql ="select * from tb_brand";
    16. //防止SQL注入获取PreparedStatement
    17. PreparedStatement pstmt = con.prepareStatement(sql);
    18. //执行sql,返回结果集集合
    19. ResultSet resultSet = pstmt.executeQuery(sql);
    20. while (resultSet.next()){
    21. //获取遍历到每一行的数据
    22. int id = resultSet.getInt("id");
    23. String brandName = resultSet.getString("brand_name");
    24. String companyName = resultSet.getString("company_name");
    25. int ordered = resultSet.getInt("ordered");
    26. String description = resultSet.getString("description");
    27. int status = resultSet.getInt("status");
    28. //封装成 品牌对象
    29. Brand brand = new Brand(id,brandName,companyName,ordered,description,status);
    30. //添加到品牌集合中
    31. brandList.add(brand);
    32. }
    33. for (Brand brand : brandList) {
    34. System.out.println("主键\t品牌名称\t企业名称\t企业排名\t公司描述\t状态");
    35. System.out.println(brand.getId() + "\t" + brand.getBrandName() + "\t" + brand.getCompanyName() + "\t"
    36. + brand.getOrdered() + "\t" + brand.getDescription() + "\t" + brand.getStatus());
    37. System.out.println("------------------------------------");
    38. }
    39. resultSet.close();
    40. pstmt.close();
    41. con.close();
    42. } catch (Exception e) {
    43. e.printStackTrace();
    44. }
    45. }
    46. }

    2、JDBC添加

    1. public class JdbcAddBrand {
    2. //品牌数据的增加
    3. @Test
    4. public void testAdd() throws Exception {
    5. //1、修改配置文件
    6. Properties pro = new Properties();
    7. pro.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
    8. //2、创建数据库连接池
    9. DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
    10. //3、创建连接
    11. Connection conn = dataSource.getConnection();
    12. //4、创建sql语句
    13. String sql = "insert into tb_brand(brand_name,company_name,ordered,description,status)" +
    14. "values(?,?,?,?,?)";
    15. //5、创建PrepareStatement
    16. PreparedStatement psmt = conn.prepareStatement(sql);
    17. //6、设置参数
    18. psmt.setString(1,"微软");
    19. psmt.setString(2,"美国微软国际公司");
    20. psmt.setInt(3,10);
    21. psmt.setString(4,"微软微软微软");
    22. psmt.setInt(5,1);
    23. //7、执行sql
    24. int i = psmt.executeUpdate();
    25. //8、判断是否添加成功
    26. if (i > 0){
    27. System.out.println("添加成功!");
    28. }else {
    29. System.out.println("添加失败!");
    30. }
    31. //9、释放资源
    32. psmt.close();
    33. conn.close();
    34. }
    35. }

    3、JDBC修改

    1. public class JdbcUpdate {
    2. //根据id修改数据
    3. @Test
    4. public void testUpdate() throws Exception {
    5. //1、获取配置文件
    6. Properties pop = new Properties();
    7. pop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
    8. //2、创建数据库连接池
    9. DataSource dataSource = DruidDataSourceFactory.createDataSource(pop);
    10. //3、创建数据库连接
    11. Connection conn = dataSource.getConnection();
    12. //4、创建sql语句
    13. String sql = "update tb_brand set brand_name=?,company_name=?,ordered=?,description=?,status=? " +
    14. "where id=?";
    15. //5、创建PrepareStatement
    16. PreparedStatement pstmt = conn.prepareStatement(sql);
    17. //6、设置参数
    18. pstmt.setInt(6,4);
    19. pstmt.setString(1,"谷歌");
    20. pstmt.setString(2,"微软");
    21. pstmt.setInt(3,34);
    22. pstmt.setString(4,"谷歌公司谷歌谷歌");
    23. pstmt.setInt(5,0);
    24. //7、执行sql
    25. int i = pstmt.executeUpdate();
    26. //8、处理结果
    27. if (i>0){
    28. System.out.println("修改成功!");
    29. }else {
    30. System.out.println("修改失败!");
    31. }
    32. //9、释放资源
    33. pstmt.close();
    34. conn.close();
    35. }
    36. }

    4、JDBC删除

    1. public class JdbcDelete {
    2. //根据id删除
    3. @Test
    4. public void testDelete() throws Exception {
    5. //1、获取配置文件
    6. Properties pop = new Properties();
    7. pop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
    8. //2、创建数据库连接池
    9. DataSource dataSource = DruidDataSourceFactory.createDataSource(pop);
    10. //3、创建数据库连接
    11. Connection conn = dataSource.getConnection();
    12. //4、创建sql语句
    13. String sql = "delete from tb_brand where id=?";
    14. //5、创建PrepareStatement
    15. PreparedStatement pstmt = conn.prepareStatement(sql);
    16. //6、设置参数
    17. pstmt.setInt(1,5);
    18. //7、执行sql
    19. int i = pstmt.executeUpdate();
    20. if (i>0){
    21. System.out.println("删除成功!");
    22. }else {
    23. System.out.println("删除失败!");
    24. }
    25. }
    26. }

  • 相关阅读:
    [工业自动化-22]:西门子S7-15xxx编程 - 软件编程 - 如何PLC建立用户界面: SIMATIC 面板式HMI 或工控机PC HMI
    【关于Spring MVC框架中的@RequestBody】
    体验极速——在旭日X3派上使用双频1300M USB无线网卡
    学习 vite + vue3 + pinia + ts(四)setup异步返回 async setup
    记录|C#主界面设计【Web风格】
    RabbitMQ 链接管理-发布者-消费者
    SpringBoot SpringBoot 原理篇 1 自动配置 1.14 自动配置思想
    正点原子嵌入式linux驱动开发——TF-A初探
    40.讲初识动态规划:如何巧妙解决“双十一”购物时的凑单问题
    什么是RPA自动化办公?
  • 原文地址:https://blog.csdn.net/m0_56044262/article/details/126087716