JDBC(连接MySQL)基础复习总结

什么是JDBC?

JDBC:即为 Java DataBase Connectivity (java语言连接数据库)

JDBC的本质: 其实是SUN公司制定的一套接口(inferace),一套面向各类数据库的接口。而接口都有调用者和实现者

为什么SUN指定一套JDBC接口?

 因为每一个数据库的底层实现原理都不一样。Oracle数据库,mysql数据库等数据库产品都有自己不同的实现原理。

谁是实现者?谁是调用者?

这里的实现者就是各大数据库厂商,例如Oracle、MySQL、SQL Server、PostgrcSQL、 DB2.........他们去实现这套接口,供调用者能去使用,从而能从中赚取利益(不然干这活干嘛)。

这里的调用者就是我们这些数据库的使用者(各大公司呀,大厂之类的)。实现接口的活有人干了的话,我们就能够根据他们实现接口的这一套来使用了。

面向接口调用,面向接口写实现类,这都属于面向接口编程。为什么要面向接口编程?

     解耦合:降低程序的耦合度,提高程序的扩展力。(多态机制就是面向抽象编程)


此处主要是介绍MySQL数据库与java的连接

JDBC编程六步

第一步:注册驱动(告诉java程序,即将要连接的是那个品牌的数据库)

第二步:获取连接(表示jvm的进程与数据库进程之间的通道打开了,这是属于进程之间的通信,重量级的,使用完之后一定要关闭。)

第三步:获取数据库操作对象(专门执行sql语句的对象)

第四步:执行sql语句(DQL,DML............)

第五步:处理查询结果(只有当第四步执行的select语句的时候,才有这第五步处理查询结果集)

第六步:释放资源(使用完资源后,一定要关闭资源。Java和数据库属于进程间的通信,,开启之后一定要关闭)

1.注册驱动

 //1.注册驱动
       //第一种方式
       Driver driver=new com.mysql.cj.jdbc.Driver();  //多态,父类型引用指向子类型对象
       DriverManager.registerDriver(driver);
           

      /*第二种方式:
       更常用,因为参数是一个字符串,字符串可以写到xxx.properties文件中。
       且以下方式不需要接受返回值,因为我们只想用他的类加载动作,类加载后静态代码块执行, 
       静态代码块中完成注册驱动*/
         Class.forName("com.mysql.cj.jdbc.Driver");

2.获取连接

  //2.获取连接
    Connection conn=null;      
    String url="jdbc:mysql://localhost:3306/mydb";    //指定你已创建好的数据库
    String user="root";                      //指定账户,此处为root账户
    String password="213215";                //指定你登录MySQL所设置的密码
    conn=DriverManager.getConnection(url,user,password);

     //直接在参数中指定
    //conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","213215");
    
     System.out.println("数据库连接对象为"+conn);

3.获取数据库操作对象

  //3.获取数据库操作对象
      Statement stmt=null;
      stmt=conn.createStatement();   //Statement专门执行sql语句的

4.执行SQL语句

例1:DML语句

   //4.执行sql语句
      String sql="insert into mytable(name,sex) values('zs','nan')";
      int count=stmt.executeUpdate(sql);   //返回值是“影响数据库中的记录条数”
      System.out.println(count==1?"保存成功":"保存失败");

 例2:DQL语句

//4.执行sql语句
   ResultSet rs = null;
   String sql = "selete * from mytable";
   //专门执行DQL语句的方法。rs就相当于是查询结果的一张表
   rs = stmt.executeQuery(sql);     

5.处理查询结果集(DQL语句才有查询结果集)

 //5.处理查询结果集
            //上面的rs就相当于是查询结果的一张表
            while (rs.next()) {
            /*
            以列的下标获取,jdbc中所有的下标从1开始,不是从0开始
                String empno=rs.getString(1);
                String ename=rs.getString(2);
                String sal=rs.getString(3);
                System.out.println(empno+","+ename+","+sal);
             */


            //以列的名字获取
                String name=rs.getString("name");    //注意:列名称不是表中的列名称,是查询结果的列名称
                String sex=rs.getString("sex");
                System.out.println(name+","+sex);


                /*
                指定特定类型取出
                int empno = rs.getInt("empmo");
                String ename = rs.getString("ename");
                double sal = rs.getDouble("sal");
                System.out.println(empno + "," + ename + "," + (sal + 100));
                */

6.释放资源(放在finally语句中,以保证一定释放资源)

 //6.释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (stmt != null) {
                try {
                    stmt.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


关于SQL注入问题

//思考:输入这样的账号和密码能登录成功吗?
//账号:'zs' OR '1'='1'
//密码:'123'OR '1'='1'
SELECT * FROM Users WHERE Username='zs' OR '1'='1' AND Password='123'OR '1'='1'

结果是可以登录成功,这种现象被称为Sql注入(存在安全隐患)。 

根本原因:

用户输入的信息含有SQL语句关键字,并且这些关键字进入编译过程,导致SQL语句原意被扭曲,进而产生一些危险的信息安全隐患。 

解决方案 :

可以推测,解决 SQL注入关键就是,让用户提供的信息中即使含有SQL语句关键字,但这些关键字没有参与编译的话,就不会起到扭曲原意的作用。于是可以想到,那为什么不先对语句进行编译,再由用户输入进行传值呢?

如何才能做到先编译呢?(使用PerparedStatement代替Statement)

 想要用户提供的信息不参与编译,则需要使用java.sql.PerparedStatement。

PerparedStatement接口继承了java.sql.Statement,属于预编译的数据库操作对象,它可以编译一次,从而执行多次。

PerparedStatement原理就是预先对sql语句的框架进行编译,然后再给SQL语句传值。

执行过程: 


    //Sql语句框子。其中一个?表示一个占位符,一个?接受一个“值”,注意,占位符不能用单引号括来。
    //第一步:写SQL语句
       String sql = "selete * from mytable where name=? and sex=? ";
     //程序执行到此处,会发送sql语句框子给DBMS,然后DBMS进行sql语句的预先编译

      //第二步,获取预编译对象pstmt
       pstmt = conn.prepareStatement(sql);

          
      //第三步,给占位符?传值(第一个问号下标是1,第二个问号下标是2,jDBC中,所有下标从1 开始)
       pstmt.setString(1,张三);
       pstmt.setString(2,男);

     //第四步,执行sql
      rs = pstmt.executeQuery(sql);    

需要注意的是:并不是说有了预编译的使用,那么Statement是不是就可以彻底抛弃了呢?

显然这样的观点是错误的?

对于只执行一次的SQL语句(不需要考虑SQL注入时)选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的.因为相比Statement,PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行.

最后,关于以上JDBC的基本使用,还可以自己去编写一个JDBC的工具类来方便自己使用

public class DBUtil {
    //工具类中的构造方法都是私有的,因为工具类中的方法都是静态的,不需要new对象,直接采用类名调用
    private DBUtil() {
    }

    //静态代码块在类加载时执行,并且只执行一次。
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获取数据库连接对象,返回值为连接对象
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "213215");
    }



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

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

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

    }


}

以上就是我本人(新手菜鸟一个)对自己学到的JDBC的简单内容的简单总结,主要是拿来利于后面的复习,也是我发的第一篇博客,如有错误,希望大家指出,定然接受并及时改正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值