5.表关系设计、范式、JDBC

    • 表关系设计
      • 外键:用于建立关系的字段称为外键
      • 1对1关系
        • 有AB两张表,A表中一条数据对应B表中一条数据,同时B表中一条数据也对应A表中的一条数据
        • 应用场景:为了提高查询效率,把原有的一张表查分成两张表,如:商品表和商品详情表,用户表和用户信息扩展表
      • 1对多关系
        • 有AB两张表,A表中一条数据对应B表中多条数据,同时B表中一条数据对应A表中的一条数据
        • 应用场景:员工表和部门表,商品表和商品分类表,用户表和地址表
      • 多对多关系
        • 有AB两张表,A表中一条数据对应B表中多条数据,同时B表中一条数据也对应A表中的多条数据
        • 应用场景:用户表和权限表,老师表和学生表
      • 如何建立关系:额外创建关系表,在关系表中添加两个外键指向另外两个表的主键
    • 数据库范式
      • 第一范式(1NF)
        • 字段唯一值唯一
        • 由基本类型构成,包括
          • 整型、实数、字符型、逻辑型、日期型、其他类型
      • 第二范式(2NF)
        • 数据库表满足第一范式
        • 数据库每张表均有主键
          • 单字段主键
          • 联合主键
            2个或2个以上的字段共同组成的注解
            • 不能存在联合主键中某个主键字段决定非主键字段的情况如:表中有A、B、C、D、E五个字段若A与B为联合主键(A,B)如有A决定C的情况(A>C)则不符合2NF
      • 第三范式(3FN)
        • 满足第二范式
        • 非主键字段不能决定其他非主键字段(没有依赖关系)
          如:表中有A、B、C、D、E五个字段;若A为主键,如有C决定D的情况(C——>D)则不符合3NF
      • 反三范式
        • 没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,提高读性能,就必须降低范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,减少了查询时的关联,提高查询效率,因为在数据库的操作中查询的比例要远远大于DML【(Data Manipulation Language)语句数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性的比例。】但是反范式化一定要适度,并且在原本已满足三范式的基础上再做调整的。
      • 还有其他范式,不一一说明,其他百度看吧
    • JDBC
      • jdbc全称是java数据库连接(Java Database Connectivity),是一套用于执行sql语句的java API。应用程序可通过这套API连接到关系型数据库,并使用sql语句
      • 作用
        • 相当于统一了各个数据库的接口,使得代码的通用性更强。5.表关系设计、范式、JDBC
      • JDBC常用API
        • 位于java.sql包中,该包定义了一系列访问数据库的接口和类
        • Drive接口
          • 是所有JDBC驱动程序必实现的接口,该接口提供给数据库厂商使用
        • 注意:编写JDBC程序时,必须要把所使用的数据库驱动程序或类库加载到项目的classpath中(这里指mysql驱动jar包).
        • DriverManager类
          • 用于加载JDBC驱动并且创建与数据库的连接
          • DriverManager类中有两个比较重要的静态方法
            • static void registerDriver(Driver)
              • 用于向DriverManager中注册给定的JDBC驱动程序;不建议用这种,因为Driver类的源码中,已经在静态代码块中完成了数据库驱动的注册。所以为了避免数据库被重复注册,只需在程序中使用Class.forName()方法加载驱动类即可。
            • static Connection getConnection(String url,String user,String pwd)
              • 用于建立和数据库的连接,并返回表示连接的Connection对象
        • Connection接口
          • 代表Java程序和数据库的连接,只有获得该连接对象后,才能访问数据库,操作数据库。
          • 常用方法
            • DatabaseMetaData_getMetaData()
              • 用于返回表示数据库的元数据的DatabaseMetaData对象
            • Satement createStatement()
              • 用于创建一个Statement对象将sql语句发送到 数据库
            • PrepareStatement prepareStatement(String sql)
              • 用于创建一个PreparedStatement对象来将参数化的sql语句发送到数据库
            • CallableStatement prepareCall(String sql)
              • 用于创建一个CallableStatement对象来调用数据库存储过程
        • Statement接口
          • 用于执行静态的sql语句,并返回一个结果对象。Statement接口对象可以通过Connection实例的createStatement()方法获得,该对象会把静态sql语句发送到数据库中编译执行,然后返回数据库的处理结果。
          • 常用方法
            • boolean execute(String sql)
              • 用于执行各种sql语句,改方法返回一个boolean类型的值,如果为true,表示所执行的sql语句有查询结果,可通过Statement的getResultSet()方法获得查询结果
            • int executeUpdate(String sql)
              • 用于执行sql中的insert、update和delete语句。该方法返回一个int类型的值,表示数据库中受该sql语句影响的记录条数
            • ResultSet executeQuery(String sql)
              • 用于执行sql中的select语句,该方法返回一个表示查询结果的ResultSet对象
        • PreparedStatement接口
          • 封装了JDBC执行SQL语句的方法,完成java程序执行SQL语句的操作。实际开发过程中往往将程序中变量作为SQL语句的查询条件,而使用Statement接口操作这些SQL语句过于繁琐,且存在安全问题,针对这一问题,JDBC提供扩展的PreparedStatement接口
          • 常用方法
            • int executeUpdate()
              • 在PreparedStatement对象中执行SQL语句,该语句必须是一个DML语句或者是无返回内容的SQL语句,如DDL语句
            • ResultSet executeQuery()
              • 在PreparedStatement对象中执行SQL查询,该方法返回的是ResultSet对象
            • void setlint(int parameterindex,int x)
              • 将指定参数设置为给定的int值
            • void setFloat(int parameterindex,float x)
              • 将指定参数设置为给定的float值
            • void setString(int parameterindex,String x)
              • 将指定参数设置为给定String值
            • void setDate(int parameterindex,Data x)
              • 将指定参数设置为给定的Date值
            • void addBatch()
              • 将一组参数添加到此PreparedStatement对象的批处理命令中
            • void setCharacterStream(int parameterindex,java.io.Reader reader,int length)
              • 将指定的输入流写入数据库的文本字段
            • void setBinaryStream(int parameterindex,java.io.inputStream x,int length)
              • 将二进制的输入流数据写入到二进制字段中
            • 注意:
              • setDate()方法可以设置日期内容,但参数Date的类型是java.sql.Date而不是java.util.Date。
              • 5.表关系设计、范式、JDBC
        • ResultSet接口
          • 用于保存JDBC执行查询时返回的结果集,该结果集封装在一个逻辑表格中。在ResultSet接口内部有一个指向表格数据行的游标(或指针)。ResultSet对象初始化时,游标在表格的第一行之前,调用next()方法可将游标移动到下一行。如果下一行没有数据则返回false。在应用程序中经常使用next()方法作为while循环的条件来迭代ResultSet结果集。
          • 常用方法
            • String getString(int columnindex)
              • 用于获取指定字段的String类型的值,参数columnindex代表字段的suoyin。
            • String getString(String columnName)
              • 用于获取指定字段的String类型的值,参数columnName代表字段的名称。
            • int getInt(int columnIndex)
              • 用于获取指定字段int类型的值,参数columIndex代表字段的索引
            • int getInt(String columnName)
              • 用于获取指定字段int类型的值,参数colunIndex代表字段的名称
            • Date getDate(int columnIndex)
              • 用于获取指定字段的Date类型的值,参数columnIndex代表字段的索引
            • Date getDate(String columnName)
              • 用于后去指定字段的Date类型的值,参数columnName代表字段的名称
            • boolean next()
              • 将游标从当前位置向下移一行
            • boolean absolute(int row)
              • 将游标移动到此 ResultSet对象的指定行
            • void afterLast()
              • 将游标移动到此ResultSet对象的末尾,即最后一行之后
            • void beforeFirst()
              • 将游标移动到此ResultSet对象的开头,即第一行之前
            • boolean previous()
              • 将游标移动到此ResultSet对象的上一行
            • boolean last()
              • 将游标移动到此ResultSet对象的最后一行
          • 注意
            • 字段的索引是从1开始编号的,程序既可以用字段名称来获取指定数据,也可以通过字段的索引获取。采用哪种getXxx()方法取决于字段的数据类型。
      • 实现一个JDBC程序
        • 1.加载并注册数据库驱动
          • Class.forName("DriverName);或者DriverManager.registerDriver(Driver driver);不建议用后者
        • 2.通过DriverManager类获取数据库连接
          • Connection conn=DriverManager.getConnection(String url,String user,String pwd);
          • url书写:jdbc:mysql://数据库主机地址:端口/数据库名
        • 3.通过Connection对象获取Statement对象
          • 以创建基本Statement对象为例:Statement stmt=conn.createStatement();
        • 4.使用Statement执行SQL语句
          • 例:ResultSet rs=stmt.executeQuery(sql);
            //执行SQL语句获得结果集
        • 5.操作ResultSet结果集
          • 如果执行的SQL语句是查询语句,执行结果将返回一个ResultSet对象,该对象保存了SQL语句查询的结果。可以通过该对象取出查询的结果。
        • 6.关闭连接,释放资源
          • 每次操作完数据库后都要关闭数据库连接,释放资源,包括关闭ResultSet、Statement和Connection等资源。
        • 注意:
          • 当数据库资源使用完毕后,一定要记得释放资源。把释放资源的操作应写在finally代码块中。
          • Class.forName有一个装载类对象的作用。装载就包括了初始化的操作。JDBC规范要求Driver类在使用前必须向DriverManger注册自己。注册过程在Driver类的静态类已经实现。也就是说只要类被加载,就完成了向驱动管理器的注册。
    • 代码练习

      •  1 package star;
         2 import java.sql.*;
         3 public class pres {
         4     public static void main(String[] args){
         5         Statement stem=null;
         6         ResultSet rs=null;
         7         Connection conn=null;
         8         try {
         9             //1.注册数据库驱动
        10             Class.forName("com.mysql.jdbc.Driver");
        11             //2.通过DriverManager获取数据库连接,语法jdbc:mysql://数据库地址:端口:数据库名。。?useSSL=false是出现警告信息时加的(不建议在没有服务器身份验证的情况下建立SSL连接)
        12             conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/star?useSSL=false","root","root");
        13             //3.通过Connection后去Statement对象
        14             stem = conn.createStatement();
        15             //用Statement的executeUpdate方法插入下数据试试//insert into users(name,password,email,birthday) values('ac','123456','ac@sina.com','1978-08-28')
        16             //delete from users where name='ac'
        17             int jieguo =stem.executeUpdate("delete from users where name='ac'");
        18             //因为上面那个方法返回int类型表示修改的条数,所以加个成功否判断
        19             if(jieguo!=0){
        20                 System.out.println("数据修改成功");
        21             }else {
        22                 System.out.println("数据修改失败");
        23             }
        24             //4.使用Statement执行sql语句
        25             String sql="select * from users";
        26             //执行select语句返回一个表示查询结果的ResultSet对象
        27             rs=stem.executeQuery(sql);
        28             if(rs!=null){
        29                 System.out.println("数据表查询成功");
        30             }else {
        31                 System.out.println("数据表查询失败");
        32             }
        33             //5.操作ResultSet结果集
        34             System.out.println("id| name | password"+"| email | birthday");
        35             while (rs.next()){
        36                 int id=rs.getInt("id");//通过列名获取指定字段的值
        37                 String name =rs.getString("name");
        38                 String psw=rs.getString("password");
        39                 String email=rs.getString("email");
        40                 Date birthday=rs.getDate("birthday");
        41                 System.out.println(id+"|"+name+"    |   "+psw+"     |    "+email+"  |   "+birthday);
        42             }
        43         }catch (Exception e){
        44             e.printStackTrace();
        45         }finally {
        46             {
        47                 //6.回收数据库资源
        48                 if(rs!=null){
        49                 try{
        50                    rs.close();
        51                 }catch(SQLException e){
        52                    e.printStackTrace();
        53             }
        54                 rs=null;
        55                 }
        56 
        57 
        58                 if(stem!=null){
        59                     try {
        60                         stem.close();
        61                     }catch (SQLException e){
        62                         e.printStackTrace();
        63                     }
        64                     stem=null;
        65                 }
        66                 if (conn!=null){
        67                     try{
        68                         conn.close();
        69                     }catch (SQLException e){e.printStackTrace();}
        70                     conn=null;
        71                 }
        72             }
        73         }
        74 
        75     }
        76 }

         


上一篇:题5 Statement,PreparedStatement和CallableStatement的区别


下一篇:JDBC学习笔记