函数_jdbc

day03.函数_jdbc

课前回顾:
  1.聚合函数:对列进行操作,会产生单个数据
    count(列名):统计总记录数
    sum(列名):对指定列求和
    avg(列名):对指定列求平均值
    max(列名):求指定列的最大值
    min(列名):求指定列的最小值
  2.分组查询:group by
    having:在分组之后进行筛选
    按照哪一列分组呢:相同的在一组,不同的在一组
  3.分页: limit m,n
    m:代表的是每页的起始位置
    n:代表的是每页显示条数
    起始位置:(当前页-1)*每页显示条数
    总记录数:count统计
    总页数:Math.ceil(总记录数/每页显示条数)
  4.mysql三范式:
    原子性,唯一性,不可依赖性
  5.多表关系:一对多  多对多  一对一
  6.交叉查询:select 列名 from 表A,表B->笛卡尔乘积
  7.内连接:inner join on
  8.外连接:
    a.左外连接:left outer join
    b.右外连接:right outer join
    c.怎么区分左表和右表:看join,在join左边的就是左表,join右边的就是右表
    d.左外连接,右外连接,内连接区别:
      左:查询的是和右表的交集,以及左表的全部
      右:查询的是和左表的交集,以及右表的全部
      内:只查交集
  9.子查询:一个查询语句作为另外一个查询语句的条件使用
          查询出来的结果还可以作为伪表使用
  10.UNION:将两个查询结果合并,去重复
  11.函数:字符串中的函数,用法其实和聚合函数一样,都是针对某一列的数据进行操作
    
今日重点:
  从第三章开始,都是重点

第一章.MySQL的常用函数

-- 用户表
CREATE TABLE t_user (
  id INT(11) NOT NULL AUTO_INCREMENT,
  uname VARCHAR(40) DEFAULT NULL,
  age INT(11) DEFAULT NULL,
  sex INT(11) DEFAULT NULL,
  PRIMARY KEY (id)
);

INSERT  INTO t_user VALUES (NULL,'zs',18,1);
INSERT  INTO t_user VALUES (NULL,'ls',20,0);
INSERT  INTO t_user VALUES (NULL,'ww',23,1);
INSERT  INTO t_user VALUES (NULL,'zl',24,1);
INSERT  INTO t_user VALUES (NULL,'lq',15,0);
INSERT  INTO t_user VALUES (NULL,'hh',12,0);
INSERT  INTO t_user VALUES (NULL,'wzx',60,NULL);
INSERT  INTO t_user VALUES (NULL,'lb',NULL,NULL);

1.1 数值函数

1.1.1 数值函数列表

函数用法
ABS(x)返回x的绝对值
CEIL(x)返回大于x的最小整数值
FLOOR(x)返回小于x的最大整数值
RAND()返回0~1的随机值
POW(x,y)返回x的y次方

1.1.2 常用数值函数练习

练习1: 获取 -12 的绝对值

SELECT ABS(-12);

练习2: 将 -11.2 向上取整

SELECT CEIL(-11.2);

练习3: 将 1.6 向下取整

SELECT FLOOR(1.6);

练习4: 获得2的2次幂的值

SELECT POW(2,2);

练习5: 获得一个在0-100之间的随机数

SELECT RAND()*100;

1.2 日期函数

1.2.1 日期函数列表

函数用法
CURDATE() 或 CURRENT_DATE()返回当前日期 年月日
CURTIME() 或 CURRENT_TIME()返回当前时间 时分秒
NOW() / SYSDATE() / CURRENT_TIMESTAMP() / LOCALTIME() / LOCALTIMESTAMP()返回当前系统日期时间
DATEDIFF(date1,date2) / TIMEDIFF(time1, time2)返回date1 - date2的日期间隔 / 返回time1 - time2的时间间隔

1.2.2 常用日期函数的练习

练习1:获取当前的日期

SELECT CURDATE();

练习2: 获取当前的时间(仅仅需要时分秒)

SELECT CURTIME();

练习3: 获取当前日期时间(包含年月日时分秒)

SELECT NOW();

练习4: 获取到五一还有多少天

SELECT DATEDIFF('2022-05-01',CURDATE());

1.3 流程函数_判断

函数用法
IF(比较,t ,f)如果比较是真,返回t,否则返回f
IFNULL(value1, value2)如果value1不为空,返回value1,否则返回value2
CASE WHEN 条件1 THEN result1 WHEN 条件2 THEN result2 … [ELSE resultn] END相当于Java的if…else if…else…
  • 练习1:获取用户的姓名、性别,如果性别为1则显示1,否则显示0;要求使用if函数查询:

    SELECT uname,IF(sex=1,1,0) 'sex' FROM t_user;
    
    
  • 练习2:获取用户的姓名、性别,如果性别为null则显示为0;要求使用ifnull函数查询:

    SELECT uname,IFNULL(sex,0) FROM t_user;
    
    
  • 练习3:如果age<=12,显示儿童,如果age<=18,显示少年,如果age<=40,显示中年,否则显示老年

    SELECT id,uname,CASE WHEN age<=12 THEN '儿童' 
    WHEN age<=18 THEN '少年' 
    WHEN age<=40 THEN '中年' 
    ELSE '老年' END '年龄段',IFNULL(sex,0) 'sex' FROM t_user;
    
    
CASE WHEN 条件1 THEN result1 WHEN 条件2 THEN result2 .... [ELSE resultn] END

case when:相当于if
when:相当于else if
THEN:后面跟条件对应的结果

判断完毕,用end结束

第二章 DCL语句

我们现在默认使用的都是root用户,超级管理员,拥有全部的权限。但是,一个公司里面的数据库服务器上面可能同时运行着很多个项目的数据库。所以,我们应该可以根据不同的项目建立不同的用户,分配不同的权限来管理和维护数据库。

2.1 创建用户

CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

关键字说明:

1.用户名:创建的用户名
2.主机名:指定该用户在哪个主机上可以登录,如果是本地用户,可以用'localhost',如果想让该用户可以任意远程主机登录,可以使用通配符%
3.密码:该用户登录的密码,密码可以为空,如果为空,该用户可以不输入密码就可以登录mysql

具体操作:

-- user1用户只能在localhost这个IP登录mysql服务器
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123';
-- user2用户可以在任何电脑上登录mysql服务器
CREATE USER 'user2'@'%' IDENTIFIED BY '123';

2.2 授权用户

用户创建之后,基本没什么权限!需要给用户授权
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EAPy6JbY-1649325662748)(img/DCL02.png)]

授权格式

GRANT 权限1, 权限2... ON 数据库名.表名 TO '用户名'@'主机名';

关键字说明

a.GRANT:授权关键字
b.授予用户的权限,比如  'select' 'insert' 'update',如果要授予所有的权限,使用 'ALL'
c.数据库名.表名:该用户操作哪个数据库的哪些表,如果要授予该用户对所有数据库和表的相关操作权限,就可以用*表示: *.*
d.'用户名'@'主机名':给哪个用户分配权限

具体操作:

  1. 给user1用户分配对test这个数据库操作的权限

    GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON test.* TO 'user1'@'localhost';
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7HqEWBcf-1649325662749)(img/DCL03.png)]

  2. 给user2用户分配对所有数据库操作的权限

    GRANT ALL ON *.* TO 'user2'@'%';
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-quVAhAvc-1649325662750)(img/DCL04.png)]

2.3 撤销授权

REVOKE  权限1, 权限2... ON 数据库.表名 FROM '用户名'@'主机名';

具体操作:

  • 撤销user1用户对test操作的权限

    REVOKE ALL ON test.* FROM 'user1'@'localhost';
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUhv7g0p-1649325662750)(img/DCL05.png)]

2.4 查看权限

SHOW GRANTS FOR '用户名'@'主机名';

具体操作:

  • 查看user1用户的权限

    SHOW GRANTS FOR 'user1'@'localhost';
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ztRM5v3v-1649325662751)(img/DCL06.png)]

2.5 删除用户

DROP USER '用户名'@'主机名';

具体操作:

  • 删除user2

     DROP USER 'user2'@'%';
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NtXCdE2J-1649325662752)(img/DCL07.png)]

/*
  1.创建用户:
    CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
    
  2.关键字介绍:
    a.用户名:创建的用户名
    b.主机名:指定该用户在哪个主机上登录,如果是本地用户,可以用'localhost',
             如果想让该用户可以任意远程主机登录,可以使用通配符%
    c.密码:该用户登录的密码,密码可以为空,如果为空,该用户可以不输入密码就可以登录mysql
*/
-- user1用户只能在localhost这个IP上登录mysql服务器,密码为123
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123';

-- user2用户可以在任何电脑上登录mysql服务器,密码为123
CREATE USER 'user2'@'%' IDENTIFIED BY '123';


/*
  2.分配用户的权限:
    GRANT 权限1, 权限2... ON 数据库名.表名 TO '用户名'@'主机名';
    
    关键字介绍:
      a.GRANT:授权关键字
      b.权限1,权限2...:授予用户的权限
        比如:select,insert,update,代表该用户只能对数据进行查询,添加,修改操作
        如果要授予所有的权限,使用 ALL
      c.数据库名.表名:该用户可以操作哪个库的哪些表
      
        如果要授予该用户对所有数据库和表的相关操作权限,可以用*表示:  *.*
        如果要是授予该用户指定库中的所有表相关操作权限,可以用:  库名.*
        
      d.'用户名'@'主机名':给哪个用户分配权限
      
      e.注意:授权时,用户名和主机名要和创建用户的时候指定的要对应
*/
GRANT CREATE,ALTER,DROP,INSERT,UPDATE,SELECT ON 220227_java2_2.* TO 'user1'@'localhost';
GRANT ALL ON *.* TO 'user2'@'%';


/*
  3.删除用户:
    DROP USER '用户名'@'主机名';
    
    注意:删除用户的时候,用户名和主机名要和创建用户的时候指定的要对应
*/

DROP USER 'user2'@'%';-- 正确

DROP USER 'user2'@'localhost';-- 错误,在创建user2的时候,主机名是%不是localhost

2.6 修改用户密码

2.6.1 修改管理员密码

mysqladmin -uroot -p password 新密码  -- 新密码不需要加上引号

注意:需要在未登陆MySQL的情况下操作。

具体操作:

mysqladmin -uroot -p password root
输入老密码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HanN6dwu-1649325662752)(img/DCL08.png)]

2.6.2 修改普通用户密码

set password for '用户名'@'主机名' = password('新密码');

注意:需要在登陆MySQL的情况下操作。

具体操作:

set password for 'user1'@'localhost' = password('666666');

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n2wY6AoN-1649325662753)(img/DCL09.png)]

第三章.JDBC

1.JDBC介绍

1.问题描述:将来开发,我们不能直接在mysql环境中写sql语句,我们需要将sql语句放到java代码逻辑中
          所以我们就需要将java代码中的sql语句执行起来,从而间接操作mysql数据库中的数据
    
2.那么怎么让java代码中的sql语句执行呢?->需要用到java中的api了-> JDBC技术
    
3.JDBC概述:用于操作数据库的java技术,此技术包含了很多操作数据库的接口,对象,方法,是一种标准
          Java DataBase Connectivity->java数据库连接技术
    
4.JDBC中四大核心接口:
  a.DriverManager  类  用户注册驱动
  b.Connection     接口  用于连接数据库,获取连接
  c.Statement      接口  用于执行sql语句
  d.ResultSet      接口  用于处理结果集->针对于查询
      
  思路小技巧:首先要指明操作哪款数据库(注册驱动,DriverManager),然后连上数据库(获取连接,Connection接口),再然后执行sql语句操作数据库(执行sql,Statement接口) ,最后查询结果有很多数据,需要放到集合中,然后遍历集合获取查询出来的数据(处理结果集,ResultSet接口) 
     

2.JDBC准备(导入jar包)

1.导入操作数据库的核心jar包:只要是用java代码操作数据库,都离不开这个jar包
  mysql-connector-java-8.0.25.jar
2.如何导包:
  a.在当前模块下,创建文件夹,取名为lib
  b.将要使用的jar包粘贴到lib下
  c.解压jar包到当前模块环境下->对着lib右键->add as library
  d.level选择module
  e.点击ok,jar包导入成功

3.JDBC开发步骤以及详解

1.注册驱动           DriverManager2.获取连接           Connection接口
  DriverManager类中的方法:
     static Connection getConnection(数据库地址, 数据库登录用户名, 数据库登录密码) 
         
3.获取执行平台        Statement接口->用于执行sql语句
  Connection接口中的方法:
     Statement createStatement()  
         
4.执行sql           Statement中的方法
  Statement中的方法:针对不用的sql语句,调用不同的方法去执行
      
     int executeUpdate(String sql) -> 针对于增删改操作 
     ResultSet executeQuery(String sql)->针对于查询操作,要处理结果集  
      
5.处理结果集         ResultSet接口
    a.针对于增删改操作,不用处理结果集
    b.针对于查询操作,用处理结果集:其实就是遍历结果集,将结果集中的查询结果获取出来
        
6.关闭资源           close()方法  

4.JDBC注册驱动

          1.注册驱动

            a.用到的类:DriverManager
            b.方法:static void registerDriver(Driver driver)->注册驱动
            c.参数:Driver接口,调用registerDriver方法时需要传递Driver接口的实现类
                  Driver接口是:java.sql包下的接口

              java.sql.Driver接口实现类在导入的jar包中:com.mysql.cj.jdbc.Driver

            d.问题:如果使用DriverManager.registerDriver(new Driver());注册驱动,其实不合适
              原因:通过翻阅Driver实现类的底层我们发现,里面有一个静态代码块,
                  在静态代码块中也写了DriverManager.registerDriver(new Driver());

                  如果我们用DriverManager.registerDriver(new Driver());注册驱动,那么驱动
                  将会注册两次,没必要

            e.如何写才能保证Driver驱动只注册一次呢?
              我们不写DriverManager.registerDriver了,我们直接将Driver实现类加载到内存
              Driver实现类中的静态代码块自然就给我们注册驱动了

              直接反射Driver,直接就将com.mysql.cj.jdbc.Driver加载到内存了,自然也就执行
              静态代码块了

Class.forName("com.mysql.cj.jdbc.Driver");

5.JDBC获取连接

1.获取连接:Connection接口
  a.获取:DriverManager类中的方法:
    static Connection getConnection(String url, String user, String password) 
  b.参数说明:
    url:数据库地址   jdbc:mysql://localhost:3306/数据库名字?时区&其他参数
    user:数据库登录用户名  root
    password:数据库登录密码
        
2.注意细节:
   a.mysql8中导入的jar包如果是mysql-connector-java-8.0.19.jar需要指定时区
     serverTimezone=UTC
     UTC是世界协调时间
       
     mysql8中导入的jar包如果是mysql-connector-java-8.0.25.jar不需要指定时区
       
   b.rewriteBatchedStatements=true  代表可以批量添加执行添加sql语句
     mysql默认,不能批量执行添加语句,他会将多条sql拆散,一句一句执行
     如果添加了此参数rewriteBatchedStatements=true,mysql就会批量执行添加语句
       
   c.url中?后面写的就是参数
     参数都是key=value形式,每一组参数用&连接
     
     请求路径?参数&参数

       //2.获取连接
        String url = "jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true";
        String name = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, name, password);
        System.out.println(connection);

细节:

1.使用:mysql-connector-java-8.0.19.jar,url上需要加时区
使用:mysql-connector-java-8.0.25.jar,url上不需要加时区
   
如果记不清,那么直接都加上,咱们就不考虑小版本区别,直接粘贴以下代码:
jdbc:mysql://localhost:3306/数据库名字?serverTimezone=UTC&rewriteBatchedStatements=true

2.常见错误

在这里插入图片描述

3.连接数据库用的啥协议:
TCP协议

6.JDBC实现增删改操作

-- 准备工作

CREATE TABLE `user`(
   uid INT PRIMARY KEY AUTO_INCREMENT,
   username VARCHAR(10),
   `password` VARCHAR(10)
);

    /*
      添加功能
    */  
 
    @Test
    public void add()throws Exception{
        /*
          1.注册驱动

            a.用到的类:DriverManager
            b.方法:static void registerDriver(Driver driver)->注册驱动
            c.参数:Driver接口,调用registerDriver方法时需要传递Driver接口的实现类
                  Driver接口是:java.sql包下的接口

              java.sql.Driver接口实现类在导入的jar包中:com.mysql.cj.jdbc.Driver

            d.问题:如果使用DriverManager.registerDriver(new Driver());注册驱动,其实不合适
              原因:通过翻阅Driver实现类的底层我们发现,里面有一个静态代码块,
                  在静态代码块中也写了DriverManager.registerDriver(new Driver());

                  如果我们用DriverManager.registerDriver(new Driver());注册驱动,那么驱动
                  将会注册两次,没必要

            e.如何写才能保证Driver驱动只注册一次呢?
              我们不写DriverManager.registerDriver了,我们直接将Driver实现类加载到内存
              Driver实现类中的静态代码块自然就给我们注册驱动了

              直接反射Driver类,直接就将com.mysql.cj.jdbc.Driver加载到内存了,自然也就执行
              静态代码块了
         */

        Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接
        String url = "jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true";
        String name = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, name, password);

        /*
          3.获取执行平台-> Statement接口-> 执行sql
            Connection接口下的方法:Statement createStatement()
         */
        Statement st = connection.createStatement();

        /*
          4.执行sql:Statement接口中的方法
            int executeUpdate(String sql)-> 针对于增删改操作->不用处理结果集
            ResultSet executeQuery(String sql)  -> 针对于查询操作,由于查询出来时有很多数据,所以需要容器存放,所以返回结果集


         */
        String sql = "insert into user(username,password) values ('柳岩','5436')";
        int result01 = st.executeUpdate(sql);
        System.out.println("result01 = " + result01);

        /*
           5.处理结果集
             针对于增删改来说不用处理结果集
         */

        /*
          6.关闭资源
            统一用close()
         */
        st.close();
        connection.close();

    }

 /**
     * 删除功能
     */
    @Test
    public void delete()throws Exception{
       //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接
        String url = "jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true";
        String name = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, name, password);

        //3.获取执行平台
        Statement st = connection.createStatement();

        //4.执行sql
        String sql = "delete from user where uid = 2";
        int result01 = st.executeUpdate(sql);
        System.out.println("result01 = " + result01);

        //5.处理结果集-> 增删改操作不用处理结果集,直接不写了

        //6.关闭资源
        st.close();
        connection.close();
    }


    /**
     * 修改功能
     */
    @Test
    public void update()throws Exception{
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接
        String url = "jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true";
        String name = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, name, password);

        //3.获取执行平台
        Statement st = connection.createStatement();

        //4.执行sql
        String sql = "update user set password = '6666' where uid = 4";
        int result01 = st.executeUpdate(sql);
        System.out.println("result01 = " + result01);

        //5.处理结果集-> 增删改操作不用处理结果集,直接不写了

        //6.关闭资源
        st.close();
        connection.close();
    }


细节:

1.sql代码在java语句中:可以带上``,可以不带

2.sql代码在java语句中,最后可以加;也可以不加

3.如果不确定sql是否写的正确,可以将java中的sql语句放到sqlyog中验证一下

​ 或者先在sqlyog中写完sql,然后粘到java中

image-20220407115656947

7.JDBC实现查询操作

1.执行查询语句的方法:
  ResultSet executeQuery(String sql)  -> 针对于查询操作,由于查询出来时有很多数据,所以需要容器存放,所以返回结果集
2.处理结果集:ResultSet中获取查询的数据->查询出来的数据会先封到ResultSet,我们需要从ResultSet中获取查询的数据
  boolean next()->判断结果集中是否有下一个元素

3.获取结果集中的数据
  int getInt(int columnIndex)->获取第几列的数据  
    			 columnIndex:写的是第几列
                     
  int getInt(String columnLabel) -> 获取指定列的数据
                 columnLabel:写的是列名
                     
  String getString(int columnIndex)->获取第几列的数据
                       columnIndex:写的是第几列
                           
  String getString(String columnLabel) -> 获取指定列的数据   
                       columnLabel:写的是列名  
                           
  Object getObject(int columnIndex)->获取第几列的数据  
                   columnIndex:写的是第几列
                       
  Object getObject(String columnLabel)-> 获取指定列的数据 
                   columnLabel:写的是列名  

    /**
     * 查询功能
     */
    @Test
    public void query()throws Exception{
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接
        String url = "jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true";
        String name = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, name, password);

        //3.获取执行平台
        Statement st = connection.createStatement();

        //4.执行sql
        String sql = "select * from user";
        ResultSet rs = st.executeQuery(sql);

        //5.处理结果集
        while(rs.next()){
            //int uid = rs.getInt(1);
            //int uid = rs.getInt("uid");
            //System.out.println(uid);

            //String uid = rs.getString(1);
            //System.out.println(uid);
            //String username = rs.getString("username");
            //System.out.println(username);

            Object uid = rs.getObject("uid");
            Object username = rs.getObject("username");
            Object pwd = rs.getObject("password");
            System.out.println(uid+"..."+username+"..."+pwd);

        }

        //6.关闭资源
        rs.close();
        st.close();
        connection.close();
    }   

8.JDBC工具类使用

public class JDBCUtils {
    private static String url;
    private static String name;
    private static String password;


    /*
      由于注册驱动和初始化url username password参数
      应该最先执行,而且只执行一次即可
      所以我们应该把这些代码放到静态代码块中
     */
    static {
        //注册驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取连接
            url = "jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true";
            name = "root";
            password = "root";
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取连接
     */

    public static Connection getConn() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, name, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 关闭资源
     */
    public static void close(Connection connection, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


        if (st != null) {
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


}


public class Test03_JDBC {

    /**
     * 查询功能
     */
    @Test
    public void query()throws Exception{
        //2.获取连接
        Connection conn = JDBCUtils.getConn();

        //3.获取执行平台
        Statement st = conn.createStatement();

        //4.执行sql
        String sql = "select * from user";
        ResultSet rs = st.executeQuery(sql);

        //5.处理结果集
        while(rs.next()){
            //int uid = rs.getInt(1);
            //int uid = rs.getInt("uid");
            //System.out.println(uid);

            //String uid = rs.getString(1);
            //System.out.println(uid);
            //String username = rs.getString("username");
            //System.out.println(username);

            Object uid = rs.getObject("uid");
            Object username = rs.getObject("username");
            Object pwd = rs.getObject("password");
            System.out.println(uid+"..."+username+"..."+pwd);

        }

        //6.关闭资源
        JDBCUtils.close(conn,st,rs);
    }

    /**
     * 添加功能
     */

    @Test
    public void add() throws Exception {
       // 获取连接-> 一旦调用静态成员,类就会被加载到内存,静态代码块就要执行了
        Connection conn = JDBCUtils.getConn();
        //获取执行平台
        Statement st = conn.createStatement();
        //准备sql
        String sql = "insert into user(username,password) values ('有菜','8888')";
        //执行sql
        st.executeUpdate(sql);
        //关闭资源
        JDBCUtils.close(conn,st,null);
    }

}

第四章.PreparedStatement预处理对象

1.sql注入的问题以及解决方式(预处理对象)

public class Test01 {
    public static void main(String[] args) throws Exception {
        //1.创建Scanner对象,模拟用户输入
        Scanner sc = new Scanner(System.in);
        //2.输入用户名和密码
        System.out.println("请你输入用户名:");
        String username = sc.nextLine();
        System.out.println("请你输入密码:");
        String password = sc.nextLine();

        //3.获取连接
        Connection conn = JDBCUtils.getConn();

        //4.获取执行平台
        Statement st = conn.createStatement();

        //5.准备sql

        /*
          "select * from user where username = '" +username+  "' and password = '" +password+  "'"
         */
        String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";

        System.out.println(sql);
        //6.执行sql
        ResultSet rs = st.executeQuery(sql);

        //7.处理结果集
        if (rs.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        //8.关闭资源
        JDBCUtils.close(conn,st,rs);

    }
}


密码输入:345’ or ‘1’ = '1 以上程序不行了->sql注入

2.使用预处理对象(PreparedStatement)实现操作

1.概述:PreparedStatement 是一个接口  是Statement接口的子接口
2.获取:使用Connection接口中的方法:
  PreparedStatement prepareStatement(String sql)  -> 获取PreparedStatement对象,传递sql语句
      
3.特点:
  在执行sql的时候,sql语句支持使用占位符->   ?
  String sql = "select * from username = ? and password = ?";
  后面再对每一个?赋值
      
4.为占位符赋值:
  void setObject(int parameterIndex, Object x)  
                 parameterIndex:写的是第几个?
                 x:代表为?赋的值
                     
5.执行sql:PreparedStatement中的方法
  int executeUpdate()  
  ResultSet executeQuery()  

3.使用预处理对象(PreparedStatement)实现查询操作

public class Test02 {
    public static void main(String[] args) throws Exception {
        //1.创建Scanner对象,模拟用户输入
        Scanner sc = new Scanner(System.in);
        //2.输入用户名和密码
        System.out.println("请你输入用户名:");
        String username = sc.nextLine();
        System.out.println("请你输入密码:");
        String password = sc.nextLine();

        //3.获取连接
        Connection conn = JDBCUtils.getConn();

        String sql = "select * from user where username = ? and password = ?";

        //4.获取执行平台
        PreparedStatement pst = conn.prepareStatement(sql);

        //为?赋值
        pst.setObject(1,username);
        pst.setObject(2,password);

        //5.执行sql
        ResultSet rs = pst.executeQuery();

        //6.处理结果集
        if (rs.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        //8.关闭资源
        JDBCUtils.close(conn,pst,rs);

    }
}


不使用PreparedStatement:
  select * from user where username = '柳岩' and password = '345' or '1' = '1'
      
      
使用PreparedStatement:
  select * from user where username = '柳岩' and password = '345\' or \'1\' = \'1'
      
  经过PreparedStatement一处理,中间所有输入的' 都会变成普通的字符内容,mysql会认为345\' or \'1\' = \'都是密码内容,所以登录不上

    /**
     * 添加功能
     */
    @Test
    public void add()throws Exception{
        //获取连接
        Connection conn = JDBCUtils.getConn();
        //准备sql
        String sql = "insert into user(username,password) values (?,?)";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);
        //为?赋值
        pst.setObject(1,"杨幂");
        pst.setObject(2,"9999");

        //执行sql
        int i = pst.executeUpdate();

        //关闭资源
        JDBCUtils.close(conn,pst,null);

    }

 /**
     * 删除功能
     */
    @Test
    public void delete()throws Exception{
        //获取连接
        Connection conn = JDBCUtils.getConn();
        //准备sql
        String sql = "delete from user where uid = ?";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);
        //为?赋值
        pst.setObject(1,"1");

        //执行sql
        int i = pst.executeUpdate();

        //关闭资源
        JDBCUtils.close(conn,pst,null);

    }

    /**
     * 修改功能
     */
    @Test
    public void update()throws Exception{
        //获取连接
        Connection conn = JDBCUtils.getConn();
        //准备sql
        String sql = "update user set password = ? where username = ?";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);
        //为?赋值
        pst.setObject(1,"0000");
        pst.setObject(2,"有菜");

        //执行sql
        int i = pst.executeUpdate();

        //关闭资源
        JDBCUtils.close(conn,pst,null);
    }

    /**
     * 查询功能
     */

    @Test
    public void query()throws Exception{
        //获取连接
        Connection conn = JDBCUtils.getConn();
        //准备sql
        String sql = "select * from user";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);

        //执行sql
        ResultSet rs = pst.executeQuery();

        //处理结果集
        while(rs.next()){
            Object uid = rs.getObject("uid");
            Object username = rs.getObject("username");
            Object password = rs.getObject("password");
            System.out.println(uid+"..."+username+"..."+password);
        }
        //关闭资源
        JDBCUtils.close(conn,pst,rs);
}

第五章.Properties集合使用回顾

 1.Properties配合xxx.properties文件使用
 2.我们需要将properties配置文件放到src下或者resources资源包下(开发常用的)
 3.properties配置文件写法:
   a.key=value形式
   b.key和value默认都是String,但是不要加""
   c.不要有空格
   d.每个键值对写完,需要换行再写其他的键值对

public class Test04_Properties {
    @Test
    public void test01()throws Exception{
        Properties properties = new Properties();
        //利用类加载器读取配置文件
        InputStream in =
                Test04_Properties.class.getClassLoader().getResourceAsStream("jdbc.properties");

        properties.load(in);

        Set<String> set = properties.stringPropertyNames();
        for (String key : set) {
            String value = properties.getProperty(key);
            System.out.println(value);
        }
    }
}


image-20220407163936659

第六章.改造JDBC工具类_结合Properties文件

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/220227_java3?serverTimezone=UTC&rewriteBatchedStatements=true
username=root
password=root

/*
  读取配置文件方式的工具类
 */
public class JDBCUtils2 {
    private static String url;
    private static String name;
    private static String password;


    /*
      由于注册驱动和初始化url username password参数
      应该最先执行,而且只执行一次即可
      所以我们应该把这些代码放到静态代码块中
     */
    static {
        //注册驱动
        try {
           //创建Properties集合
            Properties properties = new Properties();
            //读取配置文件
            InputStream in = JDBCUtils2.class.getClassLoader().getResourceAsStream("jdbc.properties");
            //调用load方法,将流中的数据加载到集合中
            properties.load(in);

            //获取Properties集合职工的数据
            String driver = properties.getProperty("driver");
            Class.forName(driver);

            url = properties.getProperty("url");
            name = properties.getProperty("username");
            password = properties.getProperty("password");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取连接
     */

    public static Connection getConn() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, name, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 关闭资源
     */
    public static void close(Connection connection, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


        if (st != null) {
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


}


public class Test05 {
    /**
     * 添加功能
     */
    @Test
    public void add()throws Exception{
        //获取连接
        Connection conn = JDBCUtils2.getConn();
        //准备sql
        String sql = "insert into user(username,password) values (?,?)";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);
        //为?赋值
        pst.setObject(1,"明步");
        pst.setObject(2,"1234");

        //执行sql
        int i = pst.executeUpdate();

        //关闭资源
        JDBCUtils2.close(conn,pst,null);

    }

    /**
     * 删除功能
     */
    @Test
    public void delete()throws Exception{
        //获取连接
        Connection conn = JDBCUtils2.getConn();
        //准备sql
        String sql = "delete from user where uid = ?";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);
        //为?赋值
        pst.setObject(1,"6");

        //执行sql
        int i = pst.executeUpdate();

        //关闭资源
        JDBCUtils2.close(conn,pst,null);

    }

    /**
     * 修改功能
     */
    @Test
    public void update()throws Exception{
        //获取连接
        Connection conn = JDBCUtils2.getConn();
        //准备sql
        String sql = "update user set password = ? where username = ?";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);
        //为?赋值
        pst.setObject(1,"0000");
        pst.setObject(2,"明步");

        //执行sql
        int i = pst.executeUpdate();

        //关闭资源
        JDBCUtils2.close(conn,pst,null);

    }

    /**
     * 查询功能
     */

    @Test
    public void query()throws Exception{
        //获取连接
        Connection conn = JDBCUtils2.getConn();
        //准备sql
        String sql = "select * from user";
        //获取执行平台_预处理对象
        PreparedStatement pst = conn.prepareStatement(sql);

        //执行sql
        ResultSet rs = pst.executeQuery();

        //处理结果集
        while(rs.next()){
            Object uid = rs.getObject("uid");
            Object username = rs.getObject("username");
            Object password = rs.getObject("password");
            System.out.println(uid+"..."+username+"..."+password);
        }

        //关闭资源
        JDBCUtils2.close(conn,pst,rs);

    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于Oracle JDBC调用函数,可以按照以下步骤进行操作: 1. 导入必要的库:首先,确保您已经导入了Oracle JDBC驱动程序的相关库文件。 2. 创建数据库连接:使用JDBC连接字符串和凭据创建一个数据库连接。例如: ```java String url = "jdbc:oracle:thin:@localhost:1521:XE"; String username = "your_username"; String password = "your_password"; Connection conn = DriverManager.getConnection(url, username, password); ``` 3. 准备调用函数的SQL语句:使用带有函数名和参数的SQL语句准备一个CallableStatement对象。例如: ```java String sql = "{ ? = call your_function(?, ?) }"; CallableStatement cstmt = conn.prepareCall(sql); ``` 4. 设置输入参数:如果函数有输入参数,使用set方法为每个参数设置值。例如: ```java cstmt.setString(2, "input_value1"); cstmt.setInt(3, 123); ``` 5. 注册输出参数:如果函数有输出参数,使用registerOutParameter方法注册每个输出参数的类型。例如: ```java cstmt.registerOutParameter(1, Types.INTEGER); ``` 6. 执行函数调用:使用execute方法执行函数调用。例如: ```java cstmt.execute(); ``` 7. 获取输出结果:如果函数有输出参数,可以使用get方法获取每个输出参数的值。例如: ```java int outputValue = cstmt.getInt(1); ``` 8. 关闭连接和语句:最后,记得关闭CallableStatement对象和数据库连接。 ```java cstmt.close(); conn.close(); ``` 请注意,上述代码中的参数索引可能需要根据您的具体情况进行调整。另外,您需要根据实际情况替换代码中的数据库连接字符串、用户名、密码、函数名称和参数类型等信息。 希望以上信息对您有所帮助!如果您有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值