一、JDBC

  JDBC的全称是java database connection java数据库连接。

  在java中需要对数据库进行一系列的操作,这时就需要使用JDBC。

  sun公司制定了关于数据库操作的组接口,数据库厂商需要按照这个接口编写对应的实现类。

  数据库厂商编写的实现类就称为数据库驱动。

  java访问数据库流程:

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

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

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

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

二、JDBC访问数据库

  为了便于查看和操作数据库可以下载数据库可视化软件(例如Navicat)。

  2.1准备工作:

    2.1.1 下载驱动

      首先我们需要下载数据库厂商提供的JDBC驱动。

       2.1.2 导入驱动

      由于这些驱动是数据库厂商实现的,并不在java本身的库中,所以需要从外部导入到项目中。

      鼠标右击项目名称--->Bulid Path-->Configure Build Path... --> Libraries  --> Add External JARs...

      -->-->-->

      然后找到下载的JDBC驱动所在文件夹,选择里面的mysql-connector-java-x.x.xx.jar,然后点击OK即可。

      

      添加完毕后项目显示添加的驱动。

      

 

  2.2加载驱动    

  1. public class TestJDBC{
  2. public static void main(String[] args){
  3. try {
  4. //加载驱动
  5. System.out.println(Class.forName("com.mysql.cj.jdbc.Driver"));
  6. //调用froName("x")会初始化名为x的类
  7. } catch (ClassNotFoundException e) {
  8. // TODO Auto-generated catch block
  9. e.printStackTrace();
  10. }
  11. }
  12. }
  1. 运行结果:
  2. class com.mysql.cj.jdbc.Driver

  这样就代表驱动已经加载好了,这里的“com.mysql.cj.jdbc”根据下载的JDBC版本不同可能会略有不同。

  一开始我写的是com.mysql.jdbc,运行后控制台提示:

  Loading class `com.mysql.jdbc.Driver'.
  This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'.

  后来修改为com.mysql.cj.jdbc.Driver就没有问题了,这个在网上查下就可以解决了。

    

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

    建立数据库连接首先我们需要了解一个类:DriverManager。

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

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

    

    主要方法:

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

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

    //user,password为用户名和密码。

    

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.SQLException;
  4.  
  5. public class TestJDBC{
  6. public static void main(String[] args){
  7. final String connectionUrl = "jdbc:mysql://localhost:3306/mybatis";
  8. String userName = "root";
  9. String passWord = "123456";
  10. try {
  11. //加载驱动
  12. System.out.println(Class.forName("com.mysql.cj.jdbc.Driver"));
  13. Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
  14. //调用froName("x")会初始化名为x的类
  15.  
  16. } catch (SQLException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. } catch (ClassNotFoundException e) {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. }
  24. }

运行后没有报错,代表基本的连接没有问题,报错的原因有很多,一般是url格式错误,或用户名密码错误。

  2.4SQL语句:执行相应SQL语句

    本例所用表结构: (数据库名:mybatis,表名:tadd)

  1. CREATE TABLE `tadd` (
  2. `id` varchar(50) NOT NULL,
  3. `tname` varchar(50) DEFAULT NULL,
  4. `tpwd` varchar(50) DEFAULT NULL,
  5. `tstudentnum` varchar(50) DEFAULT NULL,
  6. PRIMARY KEY (`id`)
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    上面通过getConnection()建立了连接,并且返回了一个Connection对象。

    我们来看下Connection对象的作用及方法。

    Connection:代表了一个与指定数据库的连接,执行SQL语句返回并在连接上下文中返回结果。

    主要方法:

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

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

    2.4.1 Statement

    Statement:主要用于执行静态的SQL语句,并返回其生成的结果对象。

    主要方法:

    boolean execute(String sql);执行给定的sql语句,可能返回多个结果。

   

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.SQLException;
  4. import java.sql.Statement;
  5.  
  6. public class TestJDBC{
  7. public static void main(String[] args){
  8. final String connectionUrl = "jdbc:mysql://localhost:3306/mybatis";
  9. String userName = "root";
  10. String passWord = "123456";
  11. try {
  12. //加载驱动
  13. System.out.println(Class.forName("com.mysql.cj.jdbc.Driver"));
  14. Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
  15. Statement sta = conn.createStatement();
  16. boolean b = sta.execute("INSERT INTO `mybatis`.`tadd`"
  17. + "(`id`, `tname`, `tpwd`, `tstudentnum`) "
  18. + "VALUES ('17', '17', '77', '777');");
  19.  
  20. System.out.println("执行成功");
  21. } catch (SQLException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. } catch (ClassNotFoundException e) {
  25. // TODO Auto-generated catch block
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  1. 运行结果:
  2. class com.mysql.cj.jdbc.Driver
  3. 执行成功

我们使用可视化软件查看,发现对应数据库(mybatis)中,对应的表(tadd)里面添加了一条记录。

Statement有个缺点,不能防止SQL注入。

例如:

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.SQLException;
  4. import java.sql.Statement;
  5.  
  6. public class TestJDBC{
  7. public static void main(String[] args){
  8. final String connectionUrl = "jdbc:mysql://localhost:3306/mybatis";
  9. String userName = "root";
  10. String passWord = "123456";
  11. try {
  12. //加载驱动
  13. System.out.println(Class.forName("com.mysql.cj.jdbc.Driver"));
            //建立连接
  14. Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
  15. // Statement sta = conn.createStatement();
  16. String sql = "delete from tadd where id = 1 or 1=1";
  17. Statement ps = conn.createStatement();//创建Statement对象
  18. ps.execute(sql);//执行SQL语句
  19. System.out.println("执行成功");
  20. } catch (SQLException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. } catch (ClassNotFoundException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  1. 运行结果:
  2. class com.mysql.cj.jdbc.Driver
  3. 执行成功

使用可视化软件我们可以看到整个表的信息都被删除了。

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

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

  2.4.2PreparedStatement

    上面我们是使用Statments来执行SQL语句,但它存在一定的缺点。

    这时我们可以使用PreparedStatement,它可以防止SQL注入。

    PreparedStatement:表示预编译SQL语句的对象。

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

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

    主要方法:

    void setObject(int parameterIndex, Object x);//给指定的参数索引设置指定对象x。

    使用Oject的话不用在意参数类型,比较方便。

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

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

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

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

    此处的参数索引代表占位符的位序,具体含义详见下列代码注释。

    boolean execute();执行SQL语句

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.SQLException;
  5.  
  6. public class TestJDBC{
  7. public static void main(String[] args){
  8. final String connectionUrl = "jdbc:mysql://localhost:3306/mybatis";
  9. String userName = "root";
  10. String passWord = "123456";
  11. try {
  12. //加载驱动
  13. System.out.println(Class.forName("com.mysql.cj.jdbc.Driver"));
  14. Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
  15. // Statement sta = conn.createStatement();
  16. String sql = "INSERT INTO `mybatis`.`tadd`"
  17. + "(`id`, `tname`, `tpwd`, `tstudentnum`) "
  18. + "VALUES (?, ?, ?, ?)";//?代表占位符, parameterIndex分别为1,2,3,4
  19. PreparedStatement ps = conn.prepareStatement(sql);
  20. ps.setObject(1, "p1");//此处的1代表第一个占位符,即sql语句中第一个问号
  21. ps.setObject(2, "p2");//第二个占位符,后面参数代表该占位符所代表的值
  22. ps.setObject(3, "p3");//可用setNString(3,"p3")代替
  23. ps.setObject(4, "p4");
  24. ps.execute();//执行sql语句
  25. System.out.println("执行成功");
  26. } catch (SQLException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. } catch (ClassNotFoundException e) {
  30. // TODO Auto-generated catch block
  31. e.printStackTrace();
  32. }
  33. }
  34. }
  1. 运行结果:
  2. class com.mysql.cj.jdbc.Driver
  3. 执行成功

可以将sql语句设置为 delete from tadd where id = ?

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

  2.5结果集:得到查询结果。

    boolean excute();返回类型是布尔,如果执行SQL语句返回的是结果集则为true,其他防护false;

    一般select语句才会返回结果集,所以执行select语句execute()返回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.

    

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6.  
  7. public class TestJDBC{
  8. public static void main(String[] args){
  9. final String connectionUrl = "jdbc:mysql://localhost:3306/mybatis";
  10. String userName = "root";
  11. String passWord = "123456";
  12. try {
  13. //加载驱动
  14. Class.forName("com.mysql.cj.jdbc.Driver");
  15. Connection conn = DriverManager.getConnection(connectionUrl,userName,passWord);
  16. // Statement sta = conn.createStatement();
  17. String sql = "select * from tadd where id = ?";
  18. PreparedStatement ps = conn.prepareStatement(sql);
  19. ps.setObject(1,"p1");
  20. ResultSet rs = ps.executeQuery();//返回一个结果集对象
  21. while(rs.next()){//判断是否有数据
  22. System.out.println("查询结果:" +//获取对应列数据
  23. rs.getString(1) + "---" +
  24. rs.getString(2) + "---" +
  25. rs.getString(3) + "---" +
  26. rs.getString(4));
  27. }
  28. System.out.println("执行成功");
  29. } catch (SQLException e) {
  30. // TODO Auto-generated catch block
  31. e.printStackTrace();
  32. } catch (ClassNotFoundException e) {
  33. // TODO Auto-generated catch block
  34. e.printStackTrace();
  35. }
  36. }
  37. }
  1. 运行结果:
  2. 查询结果:p1---p2---p3---p4
  3. 执行成功

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

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

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

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

三、批处理

  当我们需要大量(比如上万条)执行某一语句时,建议采用批处理这样可以提高执行效率。

  由于PreparedStatement预编译空间有限,当数据量较大时可能出现异常,所以建议使用Statement。

  基本操作和之前的没有太大区别,只是使用了几个方法。

  setAutoCommit(boolean autoCommit);设置自动提交,默认为true即自动提交,false不自动提交。

  addBatch(String sql);添加处理语句到批中。

  excuteBatch();提交批。

  commit();手动提交

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7.  
  8. public class TestJDBC{
  9. public static void main(String[] args){
  10. final String connectionUrl = "jdbc:mysql://localhost:3306/mybatis";
  11. String userName = "root";
  12. String passWord = "123456";
  13. Connection conn = null;
  14. Statement ps = null;
  15. ResultSet rs = null;
  16. try {
  17. //加载驱动
  18. Class.forName("com.mysql.cj.jdbc.Driver");
  19. //建立连接
  20. conn = DriverManager.getConnection(connectionUrl,userName,passWord);
  21. conn.setAutoCommit(false);//将自动提交设为false,即不进行自动提交
  22. String sql = "select * from tadd where id = ?";
  23. ps = conn.createStatement();
  24. //批处理
  25. for(int i = 0; i < 10000; i++){
  26. ps.addBatch("INSERT INTO `mybatis`.`tadd`"
  27. + "(`id`, `tname`, `tpwd`, `tstudentnum`) "
  28. + "VALUES ('"+i+"', 'p1', 'p2', 'p3');");
  29. }
  30. ps.executeBatch();
  31. conn.commit();//手动提交
  32.  
  33. System.out.println("执行成功");
  34. } catch (SQLException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. } catch (ClassNotFoundException e) {
  38. // TODO Auto-generated catch block
  39. e.printStackTrace();
  40. }finally{
  41. //依次关闭连接
  42. try {
  43. rs.close();
  44. } catch (Exception e) {
  45. // TODO: handle exception
  46. }
  47. try{
  48. ps.close();
  49. }catch(Exception e){
  50.  
  51. }
  52. try{
  53. conn.close();
  54. }catch(Exception e){
  55. }
  56. }
  57. }
  58. }
  1. 运行结果:
  2. 执行成功
  1. 查看数据库可以看到添加了10000条数据。
    批处理就相当于将一个批次的语句打包一起执行,这样比一条一条单独执行效率要高。

10.1(java学习笔记)JDBC基本操作(连接,执行SQL语句,获取结果集)的更多相关文章

  1. QtSQL学习笔记(3)- 执行SQL语句

    QSqlQuery类提供了一个用于执行SQL语句和浏览查询的结果集的接口. QSqlQueryModel和QSqlTableModel类提供了一个用于访问数据库的高级接口,这将在下一节介绍.如果你不熟 ...

  2. Java学习笔记--JDBC数据库的使用

    参考  hu_shengyang的专栏 : http://blog.csdn.net/hu_shengyang/article/details/6290029 一. JDBC API中提供的常用数据库 ...

  3. Java学习笔记——JDBC之PreparedStatement类中“预编译”的综合应用

    预编译 SQL 语句被预编译并存储在 PreparedStatement 对象中.然后可以使用此对象多次高效地执行该语句. 预编译的优点 1.PreparedStatement是预编译的,对于批量处理 ...

  4. Java学习笔记——JDBC之与数据库MySQL的连接以及增删改查等操作

    必须的准备工作 一.MySQL的安装.可以参考博文: http://blog.csdn.net/jueblog/article/details/9499245 二.下载 jdbc 驱动.可以从在官网上 ...

  5. JAVA学习笔记 -- JDBC及其应用

    一个.准备工作 1.开放SQL Server服务与支持TCP/IP  进一步确认TCPport watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjk ...

  6. SQLServer 学习笔记之超详细基础SQL语句 Part 10

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 9------------------- 删除约束的语法 ALTER T ...

  7. SQLServer 学习笔记之超详细基础SQL语句 Part 3

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 2------------------- 13. 使用compute对查 ...

  8. SQLServer 学习笔记之超详细基础SQL语句 Part 9

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 8------------------- 3 范式的概念 第一范式的目标 ...

  9. SQLServer 学习笔记之超详细基础SQL语句 Part 7

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 6------------------- 29 存储过程和触发器 存储过 ...

  10. SQLServer 学习笔记之超详细基础SQL语句 Part 4

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 3------------------- 17 带比较运算符的嵌套查询 ...

随机推荐

  1. 湖南大学第十四届ACM程序设计新生杯 Dandan's lunch

    Dandan's lunch Description: As everyone knows, there are now n people participating in the competiti ...

  2. 使用babel把es6代码转成es5代码

    第一步:创建一个web项目 使用命令:npm init 这个命令的目的是生成package.json. 执行第二步中的命令后生成的package.json的文件的内容是: { "name&q ...

  3. 用Hibernate实现分页查询

    分页查询就是把数据库中某张表的记录数进行分页查询,在做分页查询时会有一个Page类,下面是一个Page类,我对其做了详细的注解: package com.entity; /** * @author:秦 ...

  4. HTTP===http首部字段

    HTTP 首部字段 HTTP 首部字段是构成 HTTP 报文的要素之一.在客户端与服务器之间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用. 使 ...

  5. kernel 中 sscanf和sprintf()函数使用说明【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/8480695 在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望.由于s ...

  6. text-overflow的用法

    在平时的网页制作中一定碰到过内容溢出的问题,比如说文章列表很长,而其宽度又受到限制,此时超出宽度的内容就会以(...)显示.以前实现这样的效果都是由后台程序截取一定的字符数在前台输出,另外一种方法就是 ...

  7. python 如何将JSON数据原封不动的转为字符串(顺序不能变动)?

    最好是采用 OrderedDict + json.dumps方案 1. 在存储 content 的时候就使用 OrderedDict 而非用默认的 dict from collections impo ...

  8. log4j 输入不同日志文件

    log4j的强大功能无可置疑,但实际应用中免不了遇到某个功能需要输出独立的日志文件的情况,怎样才能把所需的内容从原有日志中分离,形成单独的日志文件呢?其实只要在现有的log4j基础上稍加配置即可轻松实 ...

  9. Linux下查看nginx、mysql、php的安装路径和编译参数

    一:查看安装路径: 1.nginx安装路径: ps  -ef | grep nginx 摁回车,将出现如下图片: master process 后面的就是 nginx的目录. 2.mysql安装路径: ...

  10. 使用python抓取并分析数据—链家网(requests+BeautifulSoup)(转)

    本篇文章是使用python抓取数据的第一篇,使用requests+BeautifulSoup的方法对页面进行抓取和数据提取.通过使用requests库对链家网二手房列表页进行抓取,通过Beautifu ...