java string 占位符_Java中JDBC的知识点

5be9a8d408c246e40ea950f31ace5781.png

fd3433e586ed0f570302282558dc54eb.gif    阅读本文约需要8分钟 

大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈)。上次老师跟大家分享了下再见,ELK的相关知识,今天跟大家分享Java中JDBC的知识点的知识。

1Java中JDBC的知识点

参考来源:https://blog.csdn.net/shang_0122/java/article/details/105937660

文章目录

一、JDBC基本知识

二、java中与JDBC相关的接口

三、JDBC编程的步骤

     1.步骤总览

     2.重点说下前三步

        2.1.注册驱动

        2.2.获取Connection连接:DriverManager.getConnection方法

        2.3.获取数据库操作对象:通过Connection接口中的方法创建对象

     3.JDBC完整的6步

四、封装工具类

五、总结

一、JDBC基本知识

是什么

  • 英文全称:Java DataBase Connectivity(java语言连接数据库)

  • 是sun公司制定一套规范,一套接口

为什么要有JDBC(接口)

因为每一个数据库的底层实现原理不一样,恰恰符合面向接口编程,下面解释

JDBC接口的调用者与实现者

调用者:java程序员,调用这个接口就可以连接数据库并进行操作,而不管连接的是哪一个数据库

实现者:各大数据库厂家,如:MySQL,SQL Sever,Oracle等等,该公司的程序员编写程序实现JDBC接口

一图搞懂JDBC接口

b69f82f613acc4cdad6481bf23f92128.png

驱动:各大数据库厂家实现JDBC接口的实现类也叫驱动,也就是jar包,需要java程序员到官网上下载

二、java中与JDBC相关的接口

相关的接口与类位于java.sql包下,

2f6c73e9b6a506fd3674e82bb8edba3a.png

java与数据库的连接与操作靠这几个接口(类)就可以实现,并且调用前一个接口的方法可以生成,下一个类的对象,是层层递进的关系

三、JDBC编程的步骤

1.步骤总览

143d7d5b5a4f32ad6ad286de305178d7.png

2.重点说下前三步

后三步的代码背后没有多少内容,所以先暂时放放

2.1注册驱动

告诉java程序,即将要连接的是哪个品牌的数据库

导入MySQL的jar包(驱动)

右击项目---->Open Module Settings

01ee656b1429b763241f5b5a20e2dc6b.png

找到jar包点击ok即可

代码注册驱动

/** * @author Think-Coder * @data 2020/5/5 15:11 */import java.sql.*;public class JDBCTest03{  public static void main(String[] args){    try{      //1.注册驱动常用方式      //为什么常用:因为参数是一个字符串,字符串可以写道xxx.properties文件中      Class.forName("com.mysql.jdbc.Driver");    }catch(Exception e){      e.printStackTrace();    }  }}

com.mysql.jdbc.Driver类源码

public class Driver extends NonRegisteringDriver implements java.sql.Driver {    public Driver() throws SQLException {}        static {        try {          //这个方法是注册MySQL驱动的            DriverManager.registerDriver(new Driver());        } catch (SQLException var1) {            throw new RuntimeException("Can't register driver!");        }    }}

整个注册驱动方法驱动在static静态代码块中,当执行Class.forName(“com.mysql.jdbc.Driver”);时会加载com.mysql.jdbc.Driver类,此时static静态代码块执行,便会注册驱动了

2.2.获取Connection连接:DriverManager.getConnection方法

  • 表示JVM的进程和数据库进程之间的通道打开了

  • 进程通信,重量级的,使用完一定要关闭

方法参数需要提供

url(统一资源定位符)      如:jdbc:mysql://127.0.0.1:3306/selfproj      jdbc:mysql:// 协议      127.0.0.1      IP地址      3306           端口号      selfproj       数据库名  账号:root  密码:123456

代码如下:

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?characterEncod

getConnection方法中是三个字符串参数,可以放在外部配置文件中

当更改数据库时,只要更改外部配置文件就搞定,不需要重新启动服务,这个很重要

咱们记住一条规律,只要参数是字符串,用户需要动态变化的,都可以写在外部配置文件中

2.3.获取数据库操作对象:通过Connection接口中的方法创建对象

创建Statement对象,通过Connection接口的createStatement()方法

try {      //1.注册驱动      Class.forName("com.mysql.jdbc.Driver");      //2.获取链接      conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?useUnicode=true&characterEncoding=utf8","root","123456");           //3.获取数据库操作对象      stmt = conn.createStatement();      //4.执行sql      //存在sql注入问题      //假如此时userName="张三",userPwd="张三'or'1'='1"      //通过字符串拼接将sql关键字or拼接进去      //String sql="select * from user where name='张三' and pwd ='张三'or'1'='1'"      //不需要正确的用户名及密码就能此时就能进入系统      String sql = "select * from user where name='"+userName+"'and pwd ='"+userPwd+"'";            //以上正好完成了sql语句的拼接      //以下代码的含义是,发送sql语句给DBMS,DBMS进行sql编译      rs = stmt.executeQuery(sql);      if(rs.next()){          loginSucess = true;      }  }catch (Exception e) {      e.printStackTrace();  }

因为存在SQL注入问题,平时开发基本不用Statement对象,所以没有贴完整得代码

3.JDBC完整的6步

接下来会写一个用户登录完整的代码,将JDBC的6步完全融合进去,使用了PreparedStatement对象,操作数据库,是开发中最常用的。

5be9a8d408c246e40ea950f31ace5781.png

public class JDBCTest08 {    public static void main(String[] args) {        //初始化一个界面        Map<String,String> userLoginInfo = initUI();        //验证用户名和密码        boolean loginSucess = false;        try {            loginSucess = login(userLoginInfo);        } catch (Exception e) {            e.printStackTrace();        }        System.out.println(loginSucess?"登录成功":"登录失败");    }        //用户登录的方法    public static boolean login(Map<String,String> userLoginInfo){        //打标记        boolean loginSucess = false;        Connection conn = null;        PreparedStatement ps = null;        ResultSet rs = null;        //单独定义变量        String userName = userLoginInfo.get("loginName");        String userPwd = userLoginInfo.get("loginPwd");        try {            //1.注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取链接            conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT", "root", "123456");                        //3.获取数据库预编译PreparedStatement对象            //sql语句框子,一个?代表一个占位符                        String sql = "select * from test where id=? and pwd=?";            //程序执行到此,会发送sql语句框子给DBMS,然后DBMS进行sql语句的预先编译            //此时sql语句中没有用户输入的值,很好的解决了sql注入问题            ps = conn.prepareStatement(sql);            //给?占位符传值            ps.setString(1, userName);            ps.setString(2, userPwd);            //4.执行sql            rs = ps.executeQuery();                        //5.处理返回的结果集            // rs为返回的结果集            if (rs.next()) {                loginSucess = true;            }        }catch (Exception e){            e.printStackTrace();        } finally {            //6.释放资源            if (rs != null) {                try {                    rs.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if (ps != null) {                try {                    ps.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if (conn != null) {                try {                    conn.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }        return loginSucess;    }    //用户输入的方法    private static Map<String, String> initUI() {        Scanner s = new Scanner(System.in);        System.out.println("用户名:");        String loginName = s.nextLine();        System.out.println("密码:");        String loginPwd = s.nextLine();        Map<String,String> userLoginInfo = new HashMap<>();        userLoginInfo.put("loginName",loginName);        userLoginInfo.put("loginPwd",loginPwd);        return userLoginInfo;    }}

解释说明

  • 完整的JDBC编程6步就写完了,JDBC编程6步是针对于查询的

  • 对于增删改的,是不需要第5步的,因为没有返回查询结果集

  • 使用增删改时,只需将第4步ps.executeQuery()变为ps.executeUpdate()就可以了,代码我就不写了,哈哈

下面对比Statement对象和PreparedStatement对象

    1.Statement存在sql注入问题,PreparedStatement解决了sql注入问题。

    2.PreparedStatement执行效率高,编译一次执行多次,因为相同的sql语句不会再编译,而Statement编译一次执行一次,因为基本上sql语句不会相同

    3.PreparedStatement会在编译阶段做类型检查

总结:开发场景中99%使用PreparedStatement对象,在需要SQL注入的业务场景中使用Statement

四.封装工具类

注册驱动、连接数据库和释放连接经常使用可以封装到工具类中

public class DBUtil {    /*    * 工具类中的构造方法都是私有的    * 因为工具类当中的方法是静态的,不需要new对象,直接采用类名调用    * */    private DBUtil(){}    //静态代码块在类加载时执行,并且只执行一次    static {        try {            Class.forName("com.mysql.jdbc.Driver");        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    /*    * 获取数据库连接对象    * */    public static Connection getConnection()throws Exception{        return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/selfproj?useUnicode=true&characterEncoding=utf8","root","123456");    }    /*    * 关闭资源    * */    public static void close(Connection conn, Statement ps, ResultSet rs){        if (rs != null) {            try {                rs.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (ps != null) {            try {                ps.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (conn != null) {            try {                conn.close();            } catch (SQLException e) {                e.printStackTrace();            }        }    }}

使用工具类,实现模糊查询

public static void main(String[] args) {        Connection conn = null;        PreparedStatement ps = null;        ResultSet rs = null;        try {            //使用工具类获取连接            conn=DBUtil.getConnection();                        //获取预编译的数据库操作对象            String sql = "select * from user where pwd like ?";            ps = conn.prepareStatement(sql);                        //实现查询密码第二位是2的            ps.setString(1,"_2%");            rs=ps.executeQuery();            while(rs.next()){                System.out.println(rs.getString("pwd"));            }        } catch (Exception e) {            e.printStackTrace();        }finally {            //使用工具类释放资源            DBUtil.close(conn,ps,rs);        }    }

五、总结

JDBC是一套让各个数据库厂家实现的接口,通过调用这些接口,实现java程序连接数据库,很好体现面向接口编程的特点

今天就分享这么多,于Java中JDBC的知识点会了多少欢迎在留言区评论,对于有价值的留言,我们都会一一回复的。如果觉得文章对你有一丢丢帮助,请点右下角【在看】,让更多人看到该文章。

5be9a8d408c246e40ea950f31ace5781.png

     c8b9c61cea66f640c97e03243490371d.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值