zoukankan      html  css  js  c++  java
  • JAVA企业级开发-jdbc入门(09)

    一、 jdbc介绍

    JDBC全称为:Java DataBase Connectivity(java数据库连接)。

    SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。

    没有jdbc

    有jdbc之后

    二、 JDBC API 常用类与接口

    jdbc的api在java.sql 以及 javax.sql的两个包下,以后同学们导包的时候要注意。

    图中是几个核心类的关系。

    DriverManager:数据库驱动管理类。

    Connection:接口,建立数据库连接的一个接口。

    Statement,preparedStatment,CallableStatment:接口:向数据库发送sql,并且得到数据库返回的信息。

    ResultSet:结果集,Statement执行完sql---select之后,会返回结果,结果给了ResultSet

    三、 JDBC 入门案例----重要

    1、要连接mysql数据库。有一个mysql的数据库,并且要启动

    2、创建一个数据库,创建一个表,把表添加一些数据。

    3、找到msyql的驱动(jdbc的实现类),并且拷贝到工程中。build-path

    4、书写java代码

    5. 编程步骤

    四、   jdbc-api详解

    1. DriverManager 介绍

    注意:这里只需要掌握 Class.forName(“com.mysql.jdbc.Driver”); 并且知道怎么来的

    DriverManager驱动管理类。

    static void

    registerDriver(Driver driver)
              向 DriverManager 注册给定驱动程序。

    参数:Driver---来自于你要连接的数据库(如果连接orcale,来自于oracle如果要连接mysql,来自于mysql)

    registerDriver(new com.mysql.jdbc.Driver() );

    不足:

    1、对驱动api依赖性太高。

    2、驱动会注册两次。(因为在mysql中的Driver中有静态代码块,已经注册了。)

    com.mysql.jdbc.Driver 里面会静态代码块 加载两次

    改进:

    以后我们会使用Class.forname(“com.mysql.jdbc.Driver”); ---会把com.mysql.jdbc.Driver中的静态代码块执行一次。会实现驱动的注册。

    jdbc提供的规范(要求驱动类中的静态代码块注册自己)。

    java注册驱动的时候:

    static Connection

    getConnection(String url, String user, String password)
              试图建立到给定数据库 URL 的连接。

     反射:把class文件加载,会执行类中的静态代码块

    3. 建立与数据库的连接;

    url:连接到某一个具体的数据库包括了 ip以及端口

    user:数据库的用户名

    password:数据库用户名对应的密码。

    具体的调用方式:Connetion conn= DriverManager.getConnection()

    3.a、 url介绍:指定一个具体的数据库

    jdbc:mysql:///day07 ======jdbc:mysql://localhost:3306/day07?userUnicode=true&characterEncoding=utf8

    jdbc:mysql:///sid ===== jdbc:mysql://localhost:3306/sid

    要求是localhost,并且端口是3306才可以进行简写

    前面是后面的简写。

    jdbc:mysql://localhost:3306?key=value

    url后面可以跟参数去解决数据库的乱码问题。

    2、 Connection详解

    需要注意的方法:

    conn. prepareStatement (); 有待讲解

    conn.createStatement();

    2.a  Connection详解

    与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。

    如果想要发送sql到数据库,一定要通过这个连接。

    Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法

    Statement

    createStatement()
              创建一个 Statement 对象来将 SQL 语句发送到数据库。

    与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。

    如果想要发送sql到数据库,一定要通过这个连接。

    Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法:

     

     PreparedStatement

    prepareStatement(String sql)
              创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。

    PreparedStatment预编译的sql。

    prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象

    ---下午内容

    PreparedStatment 继承 statement。

    preparedStatement向数据库发送sql的。

     CallableStatement

    prepareCall(String sql)
              创建一个 CallableStatement 对象来调用数据库存储过程。

    prepareCall(sql):创建执行存储过程的callableStatement对象。仍然是statement对象的子接口。

    --- 存储过程 ---oracle中

    ----明天内容

     void

    setAutoCommit(boolean autoCommit)
              将此连接的自动提交模式设置为给定状态。

    开启事务

    setAutoCommit(boolean autoCommit):设置事务是否自动提交。--开启事务

     void

    commit()
              使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁。

    commit() :在链接上提交事务。 ---与事务相关!!

     void

    rollback()
              取消在当前事务中进行的所有更改,并释放此 Connection 对象当前持有的所有数据库锁。

    rollback() :在此链接上回滚事务。

    3. Statement 详解

    需要掌握的方法:

    stmt.executeUpdate(sql);

    stmt.executeQuery(sql);

    Statement:向数据发送sql的对象,并且得到执行sql之后的结果。 接口

    Jdbc程序中的Statement对象用于向数据库发送SQL语句, Statement对象常用方法:

    ResultSet

    executeQuery(String sql)  用于查询的sql
              执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。

    resultSet = executeQuery(String sql) :用于向数据发送查询语句。select * from 表名

    resultSet结果集。

     int

    executeUpdate(String sql)
              执行给定 SQL 语句,该语句可能为 INSERTUPDATEDELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。

    返回值说明:表示的是 sql语句执行之后,所改变的行数,影响的行数。

    代码:

     boolean

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

    执行任意的sql语句。既可以执行insert,delete,update,还可以执行select。

    返回值说明:

    true:当执行select的时候返回true ---- 数据库返回来的内容是 resultSet

    false:执行insert,update,,delete或者其他sql的时候返回false 数据库返回的内容是影响的行数。

    如果执行的是 insert update delete 语句,程序希望获取影响的行数,可以通过getUpdateCount();获取影响的行数

     int

    getUpdateCount()
              以更新计数的形式获取当前结果;如果结果为 ResultSet 对象或没有更多结果,则返回 -1。

    如果执行的是select 语句:我们需要处理select语句执行之后获取的结果集

    可以通过stmt.getResultSet(); 获取当前sql 执行之后得到的结果集

     

     ResultSet

    getResultSet()
              以 ResultSet 对象的形式获取当前结果。

     

    -----明天

    addBatch(String sql) :把多条sql语句放到一个批处理中。

    executeBatch():向数据库发送一批sql语句执行。

    statement对象中的重要方法

    executeUpdate(); ---update insert delete

    executeQuery();---select

    4、 ResultSet 详解

    结果集:我们执行select 语句的时候,得到结果集

     

     boolean

    absolute(int row)
              将光标移动到此 ResultSet 对象的给定行编号。

    从1开始计数。

     void

    afterLast()
              将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。

     void

    beforeFirst()
              将光标移动到此 ResultSet 对象的开头,正好位于第一行之前。

    boolean

    previous()
              将光标移动到此 ResultSet 对象的上一行。

    光标向上滚动

     

    5. 滚动结果集---了解

    结果集是如何获取到的---statement对象。

    statement 如何获取到的:conn.createStatment();

    结果集:Statement.executeQuery();

    设置结果集的类型,conn.createStatment(参数。);

    参数的值:ResultSet

    结果集类型

    ResultSet.TYPE_FORWARD_ONLY       只能向前,只能调用next 不能向回滚动

    ResultSet.TYPE_SCROLL_INSENSITIVE  支持结果集向回滚动,不能查看修改结果

    ResultSet.TYPE_SCROLL_SENSITIVE    支持结果集向回滚动,查看修改结果

    结果集并发策略

    ResultSet.CONCUR_READ_ONLY 只读

    ResultSet.CONCUR_UPDATABLE 支持修改

    常见三种组合

    ResultSet.TYPE_FORWARD_ONLY 和 ResultSet.CONCUR_READ_ONLY  (默认) 只读不支持向回滚动

    ResultSet.TYPE_SCROLL_INSENSITIVE 和 ResultSet.CONCUR_READ_ONLY  只读,支持向回滚动

    ResultSet.TYPE_SCROLL_SENSITIVE 和 ResultSet.CONCUR_UPDATABLE 支持向回滚动,支持对数据修改

    rs提供了updateXXX( int , object);

                   XXX表示的数据类型。

                  第一个参数。表示列顺序,object具体的值

                  updateXXX(String,object);

                  第一个参数:列名

                  第二个参数:要修改的值。

     void

    updateRow()
              用此 ResultSet 对象的当前行的新内容更新底层数据库。

    通过updateXX() 更改数据库中某一列的值。

    不长使用:

    1、遍历结果集的时候,我们通常值遍历一次。

    2、我们查询的时候,只想获得数据,不希望去此时修改数据。

    如果修改数据采用update 语句修改数据

     

    6、 资源释放

    连接资源是珍贵的,是有数目限制的。如果只有打开没有关闭,那么当达到一个限定之后,其他人将无法继续连接数据库。所以需要关闭连接。

    五、   JDBC CRUD 操作

      1. insert

       2. update

    全部代码:

     1 @Test
     2     public void update() throws ClassNotFoundException{
     3 //        1、加载驱动
     4         Class.forName("com.mysql.jdbc.Driver");
     5 //        2、建立链接
     6         String url = "jdbc:mysql://localhost:3306/day07";
     7         String user = "root";
     8         String password = "123456";
     9         Connection conn = null;
    10         Statement stmt = null;
    11         
    12         try {
    13             conn = DriverManager.getConnection(url, user, password);
    14     //        3、获取statement对象
    15             stmt = conn.createStatement();
    16     //        4、执行sql
    17             String sql = " update tb_user set age=20 where id = 1 ";
    18             int resnum = stmt.executeUpdate(sql);
    19             System.out.println("您成功修改了"+resnum+"条数据");
    20     //        5、关闭链接
    21         } catch (SQLException e) {
    22             // TODO Auto-generated catch block
    23             e.printStackTrace();
    24         }finally{
    25             try {
    26                 if(stmt != null){
    27                     stmt.close();
    28                     stmt = null;
    29                 }
    30             } catch (SQLException e) {
    31                 e.printStackTrace();
    32             }
    33             try {
    34                 if(conn != null){
    35                     conn.close();
    36                     conn = null;
    37                 }
    38             } catch (SQLException e) {
    39                 e.printStackTrace();
    40             }
    41         }
    42     }
    43 
    44 
    

      3. delete

    重点部分:

     

      4. select

     2 @Test
     3     public void select() throws ClassNotFoundException{
     4         
     5 //        加载驱动
     6         Class.forName("com.mysql.jdbc.Driver");
     7         String url = "jdbc:mysql://localhost:3306/day07";
     8         String user = "root";
     9         String password = "123456";
    10         Connection conn = null;
    11         Statement stmt = null;
    12         ResultSet rs = null;
    13         
    14 //        定义一个list 存放所有用户信息
    15         List<User> userList = new  ArrayList<User>();
    16         
    17         try {
    18             conn = DriverManager.getConnection(url, user, password);
    19 //            获取stmt对象
    20             stmt = conn.createStatement();
    21 //            定义一个sql
    22             String sql = " select * from tb_user ";
    23 //            执行sql
    24             rs = stmt.executeQuery(sql);
    25 //            对结果集进行遍历
    26             while(rs.next()){
    27                 int id = rs.getInt("id");
    28                 String username = rs.getString("username");
    29                 int age = rs.getInt("age");
    30                 String sex = rs.getString("sex");
    31                 //会把查询出来的内容进行封装, 封装成我们java中的对象
    32                 User u = new User();
    33                 u.setAge(age);
    34                 u.setId(id);
    35                 u.setSex(sex);
    36                 u.setUsername(username);
    37 //                把u放入到集合中
    38                 userList.add(u);
    39                 
    40 //                System.out.println(id + username + age + sex);
    41             }
    42         } catch (SQLException e) {
    43             // TODO Auto-generated catch block
    44             e.printStackTrace();
    45         }finally{
    46             try {
    47                 if(rs != null){
    48                     rs.close();
    49                     rs = null;
    50                 }
    51             } catch (SQLException e) {
    52                 e.printStackTrace();
    53             }finally{
    54                 
    55             }
    56             ///
    57             try {
    58                 if(stmt != null){
    59                     stmt.close();
    60                     stmt = null;
    61                 }
    62             } catch (SQLException e) {
    63                 e.printStackTrace();
    64             }
    65             try {
    66                 if(conn != null){
    67                     conn.close();
    68                     conn = null;
    69                 }
    70             } catch (SQLException e) {
    71                 e.printStackTrace();
    72             }
    73         }
    74         
    75         for(User u : userList){
    76             System.out.println(u);
    77         }
    78     }

    六、 JDBC 工具(JdbcUtil)类抽取

      1. 在src目录下创建jdbc.properties 文件

      2、 jdbc.properties文件里面的内容注意书写属性 的时候,不要书写 双引号和空格。

    properties是配置文件L:里面已KEY=VALUE的形式保存

    url=jdbc:mysql://localhost:3306/day07

    user=root

    password=123456

    driverClass=com.mysql.jdbc.Driver

      3. jdbc工具类:

      a.  全局静态变量

      b.  静态块

    静态块中完成的功能:

    1、读取外部的配置文件(读取properties)

    2、把properties的内容 赋值 到 当前变量 例如  url = prop.getProperty(“url”);

    3、加载驱动

    new fileImputStream(默认在根目录下)

       c、  获取连接方法:

      d、 释放资源方法:

    七、   三层介绍

    八、jdbc案例(登录)

    ----建表语句

    create table user(

           id int primary key auto_increment,

           username varchar(30) unique not null,

           password varchar(30) not null

    );

    insert into user(id,username,password) values(null,'zhangsan','123456');

    创建一个User这个对象。 通常会把放到一个固定的包里面 entity bean domain

    要属性一个业务。 登录。 一个查询数据库的过程。所以 在dao层提供一个查询数据库的方法。

    没一层的方法写好之后,要进行单独的测试。

    整体包的分类

    包介绍

      2. dao的接口和实现

        a.  接口:

     

      b.  接口的实现:

       3. servcie层代码

         a. 接口:

        b.  实现:

      4.web层的实现

          username 和 pwd 是对应页面上input标签上name属性所对应text中填写的值 这就为什么如果你要写form标签必须要有name属性,方便传给web层

    request 和 response 这个在后面会讲到

      5. 页面代码:

    九、 sql注入问题

    sql注入:在页面中输入sql的片段。达到串改程序中sql语句。

    正常情况:

    select * from user where username='zhangsan' and password = '123456';

    当sql被注入之后的语句:

    select * from user where username='zhangsan' and password = '' or '1'='1'

    造成系统的不安全不保密。

     

     十、 PreparedStatement解决sql注入

     

    对sql进行预编译处理,sql的格式固定。可以防止预编译。

    PrepareStatment 进行了预编译的处理,当下次执行相同格式的sql的时候,sql不会在进行编译。比statement的效率高。

    statement每执行一次sql进行一次编译。

    通过Connection

    PreparedStatement

    prepareStatement(String sql)
              创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。

    注意:sql提前创建好的。sql语句中需要参数。使用?进行站位。

    举例:

    select *from user where username=zhangsan and password = 123456;

    使用?进行站位

     select * from user where username=? and password=?

    1、conn.prepareStatement(sql); -----需要你事先传递sql。如果sql需要参数,使用?进行占位。

    2、设置参数(执行sql之前):prepStmt.setXXX(int index, 要放入的值) -----根据不同类型的数据进行方法的选择。第一个参数表示的是?出现的位置。从1开始计数

    有几个问号,就需要传递接个参数。

    方法的参数说明:

    第一个参数:int index ;表示的是问号出现的位置。 问号是从1开始计数

    第二个参数:要问号的位置传入的值。

    3、执行,不需要在传递sql了。

       prepStmt.executeQuery();---执行select

       prepStmt.executeUpdate();---执行insert,delete,update

    为什么用preparestatement就可以防止SQL注入?

    如果进行sql注入后 会把 ‘进行转义

      1. PreparedStatement优点

    l  PreparedStatement是Statement的子接口,它的实例对象可以通过调用Connection.preparedStatement(sql)方法获得,相对于Statement对象而言:

    • PreperedStatement可以避免SQL注入的问题。
    • Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。
    • 并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。方便阅读。

              使代码的可读性更高。

     以后在企业中几乎都是用PreparedStatement

    十一、  JDBC批处理

     业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。

     实现批处理有两种方式,第一种方式:

    • Statement.addBatch(sql)
    • 执行批处理SQL语句
    • executeBatch()方法:执行批处理命令
    • clearBatch()方法:清除批处理命令

      1. 批处理介绍和优点

      2. statement 批处理

    Statement.addBatch(sql)

    执行批处理SQL语句

    executeBatch()方法:执行批处理命令

    clearBatch()方法:清除批处理命令

    采用Statement.addBatch(sql)方式实现批处理:

    优点:可以向数据库发送多条不同的sql语句。

    缺点: SQL语句没有预编译。当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:

                  Insert into user(name,password) values(‘aa’,’111’);

                  Insert into user(name,password) values(‘bb’,’222’);

                  Insert into user(name,password) values(‘cc’,’333’);

                  Insert into user(name,password) values(‘dd’,’444’);

     

      3. preparestatement 批处理

      4.两种批处理比较

    statement

    就是可以发送不同格式的SQL

    preparedStatement

     

  • 相关阅读:
    NYOJ 118:修路方案
    Black and White
    运算放大器【五】---全功率带宽和增益带宽积
    运算放大器[四]
    运算放大器[三]
    电路基础【一】
    运算放大器[二] -----基础
    运算放大器【一】
    关于----正弦信号整形为方波【第一帖】
    明天改写------
  • 原文地址:https://www.cnblogs.com/Kubility123/p/7748372.html
Copyright © 2011-2022 走看看