gdbc操作MySql加载驱动及创建连接

         1、加载mysql的jdbc驱动

2、与数据库建立连接

3、执行sql

Connection的主要方法:

Statement:

PreparedStatement:

4、操作的结果集

5、关闭连接

6、拓展--批处理


  1.加载驱动:加载数据库厂商提供的实现类。

     2.建立连接:建立程序与数据库的连接

  3.SQL语句:执行相应SQL语句

  4.结果集:得到查询结果。

       5.关闭连接

1、加载mysql的jdbc驱动

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

前提:

mysql的mysql-connector-java依赖已经导入。否则程序运行会报错:

nested exception is java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

需要导入如下依赖:

<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql-connector-java.version}</version>
</dependency>

2、与数据库建立连接

DriverManager类

管理JDBC驱动的基本服务,作用于用户和驱动程序之间。

追踪可用的驱动程序,并在数据库和相关的驱动程序之间建立连接。

主要方法:

public static Connection getConnection(String url,String user, String password);

//根据url地址,尝试建立数据库连接。返回一个Connection对象。

//user,password为用户名和密码。
//url如jdbc:mysql://addr:3306/databaseName

3、执行sql

与数据库建立连接后拿到了Connection,Connection的作用:

代表了一个与指定数据库的连接。

执行SQL语句返回并在连接上下文中返回结果。

Connection的主要方法:

Statement createStatement();//创建将SQL语句发送到数据库的语句对象。

PreparedStatement(String sql);//创建PreparedStatement对象。

Statement:

主要用于执行静态的SQL语句,并返回其生成的结果对象。
Statement缺点,不能防止SQL注入。
主要方法:
boolean execute(String sql);执行给定的sql语句,可能返回多个结果。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class MyJDBC{
    public static void main(String[] args){
        final String connectionUrl = "jdbc:mysql://localhost:3306/learn";
        String userName = "root";
        String passWord = "root";
        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
            Statement sta = conn.createStatement();
            boolean b = sta.execute("INSERT INTO `learn`.`t_user`"
                    + "(`id`, `tname`, `tpwd`, `tstudentnum`) "
                    + "VALUES ('12', '11', '23', '101');");   
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

不能防止sql注入:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class MyJDBC{
    public static void main(String[] args){
        final String connectionUrl = "jdbc:mysql://localhost:3306/learn";
        String userName = "root";
        String passWord = "root";
        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
        //建立连接
            Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
        //    Statement sta = conn.createStatement();
            String sql = "delete from t_user where id = 1 or 1=1";
            Statement ps = conn.createStatement();//创建Statement对象
            ps.execute(sql);//执行SQL语句   
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

因为 where id = 1 or 1=1,关键就在后面的or 1=1,在满足id = 1 或者 1=1的条件下删除。

可1=1恒成立,加上两者又是or的关系,所以所有信息都满足删除都被删除了。

PreparedStatement:

表示预编译SQL语句的对象,可以防止SQL注入。

SQL语句预编译并存储在PreparedStatement对象中。然后可以使用此对象多次高效地执行此语句。

继承自Statement接口,用于发送一个或多个待输入参数的sql语句。

主要方法:

void setObject(int parameterIndex, Object x);//给指定的参数索引设置指定对象x,使用Oject的话不用在意参数类型,比较方便。

除了Object作为参数类型外,还有一些设置具体类型的函数。

void setNString(int parameterIndex, String value);给指定的参数索引设置指定的String类型的值。

void setXXX..(int parameterIndex, XXX x);设置对应类型的值,此处就不一一举例了,详见API。

boolean execute();执行SQL语句
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class MyJDBC{
    public static void main(String[] args){
        final String connectionUrl = "jdbc:mysql://localhost:3306/learn";
        String userName = "root";
        String passWord = "root";
        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
        //    Statement sta = conn.createStatement();
            String sql = "INSERT INTO `t_user`.`t_user`"
                    + "(`id`, `tname`, `tpwd`, `tstudentnum`) "
                    + "VALUES (?, ?, ?, ?)";//?代表占位符, parameterIndex分别为1,2,3,4
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setObject(1, "p1");//此处的1代表第一个占位符,即sql语句中第一个问号
            ps.setObject(2, "p2");//第二个占位符,后面参数代表该占位符所代表的值
            ps.setObject(3, "p3");//可用setNString(3,"p3")代替
            ps.setObject(4, "p4");
            ps.execute();//执行sql语句   
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

防止sql注入测试:

将sql语句设置为 delete from t_user where id = ?

再将?设置为 1 or 1= 1,可以发现表中数据并没有被全部删除。

4、操作的结果集

boolean excute();返回类型是布尔,如果执行SQL语句返回的是结果集则为true,其他防护false。
excuteQuery();返回结果集,主要用于运行select语句。
excuteUpdata():返回改变的行数,主要用于insert,update,delete语句。

根据执行的语句,选择合适的方法得到对应的返回值

Resultset:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。

主要方法:
boolean next();//将游标移动一行,判断当前移动后的一行是否有数据。
例如,返回的结果集有,3行(编号依次为1,2,3),游标初始值为0,
调用next()方法后移动到第一行,如果第一行有数据返回true,反之返回false.
String getString(int columnLabel);//将当前行中指定列的内容转换为字符串形式。
注意:这里的列从1开始计数,即数据库表中第一列数字为1,第二列数字为2.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MyJDBC{
    public static void main(String[] args){
        final String connectionUrl = "jdbc:mysql://localhost:3306/learn";
        String userName = "root";
        String passWord = "root";
        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
        //    Statement sta = conn.createStatement();
            String sql = "select * from t_user where id = ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setObject(1,"p1");
            ResultSet rs = ps.executeQuery();//返回一个结果集对象
            while(rs.next()){//判断是否有数据
                System.out.println("查询结果:" +//获取对应列数据
                                   rs.getString(1) + "---" + 
                                   rs.getString(2) + "---" +
                                   rs.getString(3) + "---" +
                                   rs.getString(4));
            }  
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

数据库查询完毕后要将创建的各个对象依次关闭,一般是先创立的后关闭。

以上述代码为例,关闭顺序应该是Resultset-->PreparedStatement-->Connection.

关闭时最好为每一个对象添加一个try catch语句,不要将三个对象的关闭放在一个try catch中,

避免关闭其中一个出现异常时,导致其它对象没有关闭。 

5、关闭连接

防止异常之后连接未关闭,站着茅坑不拉屎,耽误其他客户端连接。

try{

}finally{
 //依次关闭连接
 try {
     rs.close();
 } catch (Exception e) {
     // TODO: handle exception
 }
 try{
     ps.close();
 }catch(Exception e){          
 }
 try{
     conn.close();
 }catch(Exception e){
 }
}

6、拓展--批处理

当我们需要大量(比如上万条)执行某一语句时,可采用批处理来提高执行效率。
由于PreparedStatement预编译空间有限,当数据量较大时可能出现异常,所以建议使用Statement。
批量操作涉及方法:
setAutoCommit(boolean autoCommit)//设置自动提交,默认为true即自动提交,false不自动提交。
addBatch(String sql)//添加处理语句到批中。
excuteBatch()//提交批。
commit()//手动提交
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MyJDBC{
    public static void main(String[] args){
        final String connectionUrl = "jdbc:mysql://localhost:3306/learn";
        String userName = "root";
        String passWord = "root";
        Connection conn = null;
        Statement ps = null;
        ResultSet rs = null;
        try {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //建立连接
            conn = DriverManager.getConnection(connectionUrl,userName,passWord);
            conn.setAutoCommit(false);//将自动提交设为false,即不进行自动提交
            String sql = "select * from t_user where id = ?";
            ps = conn.createStatement();
            //批处理
            for(int i = 0; i < 10000; i++){
                ps.addBatch("INSERT INTO `learn`.`t_user`"
                        + "(`id`, `tname`, `tpwd`, `tstudentnum`) "
                        + "VALUES ('"+i+"', 'p1', 'p2', 'p3');");
            }
            ps.executeBatch();
            conn.commit();//手动提交   
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //依次关闭连接
            try {
                rs.close();
            } catch (Exception e) {
                // TODO: handle exception
            }
            try{
                ps.close();
            }catch(Exception e){
                
            }
            try{
                conn.close();
            }catch(Exception e){
            }
        }
    }
}
批处理就相当于将一个批次的语句打包一起执行,这样比一条一条单独执行效率要高。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值