JavaWeb学习十四(JDBC入门)

来源:互联网 发布:055大驱数据 编辑:程序博客网 时间:2024/05/22 11:49

一.JDBC概述

1.什么是JDBC

JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库,原来
我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句

我们先来操作操作Connection对象来实验实验

在连接数据库,获取Connection对象之前的导入mysql的驱动包

mysql驱动包是向下兼容的,大家可以放心下,不过高版本用起来注意一些东西,下面会说的

这里我给大家提供一个比较新的驱动包版本-6.0.5

mysql-connector-java-6.0.5.jar

public class Demo {    @Test    public void fun1() throws ClassNotFoundException, SQLException {               Class.forName("com.mysql.jdbc.Driver");               String username="root";//数据库用户名               String password="T471912619";//数据库密码               String url="jdbc:mysql://localhost:3306/test";//前缀是地址,test是数据库名               Connection connection=DriverManager.getConnection(url, username, password);               System.out.println(connection);    }}

大家如果导入5.x版本的mysql驱动包以上的代码就可以打印出Connection对象了,但是对于6.x版本的以上代码会报一个错误

这里写图片描述

在url后面加上这样一串就不会报错了serverTimezone=UTC

public class Demo {    @Test    public void fun1() throws ClassNotFoundException, SQLException {               Class.forName("com.mysql.jdbc.Driver");               String username="root";               String password="T471912619";               String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC";               Connection connection=DriverManager.getConnection(url, username, password);               System.out.println(connection);    }}

这里写图片描述

2.JDBC原理

早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。

这里写图片描述

我们来看看

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

的意思
加载com.mysql.jdbc.Driver类,打开源码查看
这里写图片描述
我们看到了这个类实现了同名的接口,但是这个接口是在java.sql包下的
而我们可以用API来查看这个接口
这里写图片描述

简单来说这句代码的意思就是加载驱动类(注册驱动),执行这一行代码相当于
DriverManager类的registerDriver(Driver driver) 方法
这里写图片描述
我们可以像如下面这样替换

public void fun1() throws ClassNotFoundException, SQLException {                   Driver driver=new Driver();                  DriverManager.registerDriver(driver);                   String username="root";                   String password="T471912619";                   String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC";                   Connection connection=DriverManager.getConnection(url, username, password);                   System.out.println(connection);    }
  • 所有的java.sql.Driver实现类,都提供了static块,块内的代码就是把自己注册到DriverManager中!

这里写图片描述

当然也可以去掉不写加载驱动的这行代码,不过仅限于jdbc4.0以上的版本,为了向下兼容,一般情况我们还是写上比较好

  • jdbc4.0之后,每个驱动jar包中,在META-INFservice目录下提供了一个名为java.sql.Driver的文件。文件的内容就是该接口的实现类名称!有这个就可以不用写加载驱动的那行代码了
    这里写图片描述

满足上面的情况下,即将这样写也是可以的(即去掉Class.forName…)

public void fun1() throws ClassNotFoundException, SQLException {                   String username="root";                   String password="T471912619";                   String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC";                   Connection connection=DriverManager.getConnection(url, username, password);                   System.out.println(connection);    }

二.对数据库增,删,改,查

对数据库增删改操作,需要以下几步操作

  • 获取Connection对象
  • 对数据库增,删,改
    • 通过Connection对象创建Statement
    • 调用它的int executeUpdate(String sql),它可以发送DML,DDL

1.增

public void fun1() throws ClassNotFoundException, SQLException {               Class.forName("com.mysql.jdbc.Driver");                   String username="root";                   String password="T471912619";                   String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";                   Connection connection=DriverManager.getConnection(url, username, password);                   Statement statement=connection.createStatement();                   String sql="INSERT INTO stu VALUES('st_002',12,'lisi','男')";                   statement.executeUpdate(sql);    }

运行以上代码没出错后在运行以下代码查询
这里写图片描述

没错,添加成功,查询出了两条记录

2.改

public void fun2() throws ClassNotFoundException, SQLException {               Class.forName("com.mysql.jdbc.Driver");                   String username="root";                   String password="T471912619";                   String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";                   Connection connection=DriverManager.getConnection(url, username, password);                  Statement statement=connection.createStatement();                  String sql="UPDATE stu SET age=14,name='wangwu',gender='女' WHERE number='st_002'";                  statement.executeUpdate(sql);    }

这里写图片描述

3.删

public void fun2() throws ClassNotFoundException, SQLException {               Class.forName("com.mysql.jdbc.Driver");                   String username="root";                   String password="T471912619";                   String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";                   Connection connection=DriverManager.getConnection(url, username, password);                  Statement statement=connection.createStatement();                  String sql="DELETE FROM stu";                  int t=statement.executeUpdate(sql);                  System.out.println(t);    }

运行后控制台打印了个2,为什么是2,因为删除了整个数据表中的数据,而数据表中一共有2组数据,所以打印的就是2

这里写图片描述

4.查(这个有点麻烦了,注意)

对数据库查询操作,需要以下几步操作

  • 获取Connection对象
  • 创建ResultSet对象
    • 通过Connection对象创建Statement
    • 调用Statement的ResultSet rs=executeQuery(String sql)
  • 解析ResultSet
    • 把行光标移动到第一行,可以调用next()方法完成
    • 把光标向下移动一行,并判断下一行是否存在
    • 通过列编号来获取该列的值
    • 通过列名称来获取该列的值
  • 关闭资源
    • 倒关
public void fun3() throws ClassNotFoundException, SQLException {               Class.forName("com.mysql.jdbc.Driver");                   String username="root";                   String password="T471912619";                   String url="jdbc:mysql://localhost:3306/douluo?serverTimezone=UTC";                   Connection connection=DriverManager.getConnection(url, username, password);                  Statement statement=connection.createStatement();                  String sql="SELECT *FROM emp";                  ResultSet rs=statement.executeQuery(sql);                  while(rs.next()) {                        int empno=rs.getInt("empno");                        String ename=rs.getString("ename");                        int esoul=rs.getInt("esoul");                        String edepartment=rs.getString(4);                        System.out.println(empno+","+ename+","+esoul+","+edepartment);                  }                  rs.close();                  statement.close();                  connection.close();//必须要关,不关就死 不关不知道哪次运行就会GG 因为服务器一般都是一直开启的,并没有停止,所以不会很少出现这种情况    }

控制台打印效果

1,唐舞麟,47,强攻系2,古月,57,控制系3,谢邂,57,敏攻系4,许小言,55,辅助系5,舞丝朵,53,强攻系6,舞长空,77,强攻系7,徐笠智,58,辅助系8,叶星澜,59,强攻系9,原恩夜辉,57,强攻系10,乐正宇,54,控制系11,娜儿,67,控制系12,浊世,99,强攻系

三.JDBC代码规范化

public void fun4() throws Exception{             Connection con=null;             Statement sts=null;             ResultSet rs=null;             try {                Class.forName("com.mysql.jdbc.Driver");                String url="jdbc:mysql://localhost:3306/douluo?serverTimezone=UTC";                String username="root";                String password="T471912619";                con=DriverManager.getConnection(url,username,password);//得到连接                sts=con.createStatement();//创建Statement                String sql="SELECT *FROM emp";                rs=sts.executeQuery(sql);                while(rs.next()) {//循环遍历                //getString和getObject是通用的                     int empno=rs.getInt("empno");                        String ename=rs.getString("ename");                        int esoul=rs.getInt("esoul");                        String edepartment=rs.getString(4);                        System.out.println(empno+","+ename+","+esoul+","+edepartment);                }            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            } finally {                  if(rs!=null)rs.close();                  if(sts!=null)sts.close();                  if(con!=null)con.close();            }    }

四.JDBC中出现类

1.DriverManager

  • 其实我们今后只需要会用DriverManager的getConnection方法即可
  • 对于DriverManager.registerDriver方法了解即可,因为我们今后注册驱动只会Class.forName,而不会使用这个方法

2.Connection

  • Connection最为重要的方法就是获取Statement:
    Statement stmt = con.createStatement();
  • 后面在学习ResultSet方法时,还要学习一下下面的方法
    Statement stmt=con.createStatement(int,int);

3.Statement

  • int executeUpdate(String sql):执行更新操作,即执行insert,update,delete语句,其实也可以执行
    create table,alter table,以及drop table等语句,但我们很少会使用JDBC来执行这些语句

  • ResultSet executeQuery(String sql):执行查询操作,执行查询操作会返回ResultSet,即结果集

  • boolean execute():了解
    Statement还有一个boolean execute()方法,这个方法可以用来执行增删改查所有SQL语句。改方法返

回的是boolean类型,表示SQL是否执行成功 如果使用execute()方法执行的是更新语句,那么还要调用int
getUpdateCount()来获取 insert,update,delete语句所影响的行数
如果使用execute()方法执行的是查询语句,那么还要调用ResultSet getResultSet()来获取 select
语句的查询结果

4.ResultSet之滚动结果集(了解)

下一行:默认只能使用它,其他的方法存在,但不能使用!默认的结果集不可滚动!forward_only
上一行
下N行
上N行
到N行

  • ResultSet表示结果集,它是一个二维的表格!ResultSet内部维护一个行光标(游标),ResultSet提供了
    一系列的方法来移动游标

    • void beforeFirst():把光标放到第一行的前面,这也是光标默认的位置
    • void afterLast():把光标放到最后一行的后面
    • boolean first():把光标放到第一行的位置上,返回值表示调控光标是否成功
    • boolean last():把光标放到最后一行的位置上
    • boolean isBeforeFirst():当前光标位置是否在第一行前面
    • boolean isAfterLast():当前光标位置是否在最后一行的后面
    • boolean isFirst():当前光标位置是否在第一行上
    • boolean isLast():当前光标位置是否在最后一行上
    • boolean previous():把光标向上挪一行
    • boolean next():把光标向下挪一行
    • boolean relative(int row):相对位移,当row为正数时,表示向下移动row行,为负数时表示向上移动row行
    • boolean absolute(int row):绝对位移,把光标移动到指定的行上
    • int getRow():返回当前光标所有行

上面方法分为两类,一类用来判断游标位置的,另一类是用来移动游标的如果结果集是不可滚动的,那
么只能使用next()方法来移动游标,而beforeFirst(),afterLast(),first(),last(),previous(),relative()方法都不能使用
结果集是否支持滚动,要从Connection类的createStatement()方法说起。也就是说创建的Statement
决定了使用Statement创建的ResultSet是否支持滚动

(1).获取结果集元数据

  • 得到元数据:rs.getMetaData(),返回值为ResultSetMetaData
  • 获取结果集列数:int getColumnCount()
  • 获取指定列的列名:String getColumnName(int collndex)
            int count=rs.getMetaData().getColumnCount();                   while(rs.next()) {//遍历行                    for(int i=1;i<=count;i++) {//遍历字段(列)                        System.out.print(rs.getString(i));                        if(i<count)                        System.out.print(", ");                    }                    System.out.println();                }

(2).结果集的特性

当使用Connection的createStatement时,已经确定了Statement生成的结果集是什么特性

  • 是否可滚动
  • 是否敏感
  • 是否可更新

  • con.createStatement:生成的结果集:不滚动,不敏感,不可更新!

  • con.createStatement(int,int)

    • 第一个参数

      • TYPE_FORWARD_ONLY:不滚动结果集
      • TYPE_SCROLL_INSENSITIVE:滚动结果集,但结果集数据不会再跟随数据库而变化
      • TYPE_SCROLL_SENSITIVE:滚动结果集,但结果集数据不会再跟随数据库而变化(没有数据库驱动会支持它)
    • 第二个参数:

      • CONCUR_READ_ONLY:结果集是只读的,不能通过修改结果集而反向影响数据库
      • CONCUR_UPDATABLE:结果集是可更新的,对结果集的更新可以反向影响数据库
      • *

5.ResultSet之获取列数据

  • String getString(int columnindex):获取指定列的String类型数据
  • in getInt(int columnindex):获取指定列的int类型数据
  • double getDouble(int columnindex):获取指定列的double类型数据
  • boolean getBoolean(int columnindex):获取指定列的boolean类型数据
  • Object getObject(int columnindex):获取指定列的Object类型数据
  • 注意,列索引从1开始,而不是0

String getString(String columnName):获取名称为
columnName的列的String数据
int getInt(String columnName):获取名称为
columnName的列的int数据
double getDouble(String columnName):获取名称为columnName的列的double数据
boolean getBoolean(String columnName):获取名称为columnName的列的boolean数据
Object getObject(String columnName):获取名称为columnName的列的Object数据