• JDBC基础学习笔记


    第一章:JDBC 概述

      第一节:JDBC 简介

        JDBC(Java Data Base Connectivity,java 数据库连接)是一种用于执行 SQL 语句的 JavaAPI,可以为多种关系 数据库提供统一访问,它由一组用 Java 语言编写的类和接口组成。JDBC 提供了一种基准,据此可以构建更高 级的工具和接口,使数据库开发人员能够编写数据库应用程序。

      第二节:JDBC 原理

        JDBC 原理:JDBC 是以前 SUN 公司定义的一套访问数据库的接口(没有具体实现),一套标准,具体的实现是由 各大数据库厂家去实现,每个数据库厂家都有自己的 JDBC 实现,也就是 JDBC 驱动实现类,Java 应用程序连接 指定数据库,需要使用厂家提供的 JDBC 驱动才能连接。(这里其实就是 java 多态的一种体现,一个接口可以有 很多具体的实现)

    第二章:JDBC 连接数据库

      第一节:JDBC 连接数据库步骤

        第一步:加载驱动;

           第二步:连接数据库;

        第三步:使用语句操作数据库;

        第四步:关闭数据库连接,释放资源;

      第二节:在项目里配置数据库驱动

        右击项目 -> Build Path -> Configure Build Path -> Add Exteranl JARs..

      第三节:加载数据驱动

        Mysql 驱动名:com.mysql.jdbc.Driver

        加载方式: Class.forName(驱动名);即Class.forName("com.mysql.jdbc.Driver");

      第四节:连接及关闭数据库

        1,DriverManager 驱动管理类,主要负责获取一个数据库的连接;

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

    例如Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_book", "root", "123456");

         2,MySQL 数据库的连接地址格式

     jdbc:mysql://IP 地址:端口号/数据库名称
    jdbc 协议:JDBC
    URL 中的协议总是 jdbc ;
    子协议:驱动程序名或数据库连接机制(这种机制可由一个或多个驱动程序支持)的名称,如 mysql; 子
    名称:一种标识数据库的方法。必须遵循“//主机名端口/子协议”的标准 URL 命名约定,如 //localhost:3306/db_book

        3,Connection 接口 与特定数据库的连接(会话)。

     void close() 立即释放此 Connection 对象的数据库和 JDBC 资源,而不是等待它们被自动释放

    第三章:使用 Statement 接口实现增,删,改操作

        作用:用于执行静态 SQL 语句并返回它所生成结果的对象。

        

    利用Statement stmt=con.createStatement(); 获取Statement对象。
    int executeUpdate(String sql) 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或DELETE 语句,或 者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
    void close() 立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。

        注:1.可以将Statemant与Connection的close写在一个方法中

          如:

    public void close(Statement stmt,Connection con)throws Exception{
    		if(stmt!=null){
    			stmt.close();
    			if(con!=null){
    				con.close();
    			}
    		}
    	}
    

          2.stmt.executeUpdate(sql);会返回一个int类型的result,可以用这个判断是否语句是否成功,成功的话会返回1。

    第四章:使用 PreparedStatement 接口实现增,删,改操作

      PreparedStatement 是 Statement 的子接口,属于预处理操作,与直接使用 Statement 不同的是,PreparedStatement 在操作时,是先在数据表中准备好了一条 SQL 语句,但是此 SQL 语句的具体内容暂时不设置,而是之后再进 行设置。

    (以后开发一般用 PreparedStatement,不用 Statement)

        写入数据时可以这么做

    	private static int addBook(Book book)throws Exception{
    		Connection con=dbUtil.getCon(); // 获取连接
    		String sql="insert into t_book values(null,?,?,?,?)";
    		PreparedStatement pstmt=con.prepareStatement(sql);
    		pstmt.setString(1, book.getBookName());  // 给第一个坑设置值
    		pstmt.setFloat(3, book.getPrice());  // 给第二个坑设置值
    		pstmt.setString(2, book.getAuthor()); // 给第三个坑设置值
    		pstmt.setInt(4, book.getBookTypeId());  // 给第四个坑设置值
    		int result=pstmt.executeUpdate();
    		dbUtil.close(pstmt, con);
    		return result;
    	}
    

        

     

    第五章: ResultSet 结果集

        第一节:ResultSet 结果集的引入

          当我们查询数据库时,返回的是一个二维的结果集,我们这时候需要使用 ResultSet 来遍历结果集,获取每一行 的数据。

        第二节:使用 ResultSet 遍历查询结果

    boolean next() 将光标从当前位置向前移一行。 String getString(int columnIndex) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列 的值。 String getString(String columnLabel) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指 定列的值。

        读取数据时可以分别以这三种形式:利用index,关键字,或者直接获取一个对象。

    private static void listBook() throws Exception {
            Connection con = dbUtil.getCon(); // 获取连接
            String sql = "select * from t_book";
            PreparedStatement pstmt = con.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery(); // 返回结果集ResultSet//默认在第0行
            while (rs.next()) {
                int id = rs.getInt(1); // 获取第一个列的值 编号id
                String bookName = rs.getString(2); // 获取第二个列的值 图书名称 bookName
                float price = rs.getFloat(4); // 获取第三列的值 图书价格 price
                String author = rs.getString(3); // 获取第四列的值 图书作者 author
                int bookTypeId = rs.getInt(5); // 获取第五列的值 图书类别id
                System.out.println("图书编号:" + id + " 图书名称:" + bookName + " 图书价格:"
                        + price + " 图书作者:" + author + " 图书类别id:" + bookTypeId);
                System.out
                        .println("=======================================================================");
    
            }
        }
    private static void listBook2() throws Exception {
            Connection con = dbUtil.getCon(); // 获取连接
            String sql = "select * from t_book";
            PreparedStatement pstmt = con.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery(); // 返回结果集ResultSet
            while (rs.next()) {
                int id = rs.getInt("id"); // 获取第一个列的值 编号id
                String bookName = rs.getString("bookName"); // 获取第二个列的值 图书名称 bookName
                float price = rs.getFloat("price"); // 获取第三列的值 图书价格 price
                String author = rs.getString("author"); // 获取第四列的值 图书作者 author
                int bookTypeId = rs.getInt("bookTypeId"); // 获取第五列的值 图书类别id
                System.out.println("图书编号:" + id + " 图书名称:" + bookName + " 图书价格:"
                        + price + " 图书作者:" + author + " 图书类别id:" + bookTypeId);
                System.out
                        .println("=======================================================================");
    
            }
        }
    private static List<Book> listBook3()throws Exception{
            List<Book> bookList=new ArrayList<Book>(); 
            Connection con = dbUtil.getCon(); // 获取连接
            String sql = "select * from t_book";
            PreparedStatement pstmt = con.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery(); // 返回结果集ResultSet
            while (rs.next()) {
                int id = rs.getInt("id"); // 获取第一个列的值 编号id
                String bookName = rs.getString("bookName"); // 获取第二个列的值 图书名称 bookName
                float price = rs.getFloat("price"); // 获取第三列的值 图书价格 price
                String author = rs.getString("author"); // 获取第四列的值 图书作者 author
                int bookTypeId = rs.getInt("bookTypeId"); // 获取第五列的值 图书类别id
                Book book=new Book(id, bookName, price, author, bookTypeId);
                bookList.add(book);
            }
            return bookList;
        }

    第六章: 处理大数据对象

    大数据对象处理主要有 CLOB(character large object)和 BLOB(binary large object)两种类型的字段;在 CLOB 中可以存储大字符数据对象,比如长篇小说;在 BLOB 中可以存放二进制大数据对象,比如图片,电影,音乐;

        第一节:处理 CLOB 数据

        

    package com.java1234.jdbc.chap06.sec01;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.sql.Clob;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    import com.java1234.jdbc.model.Book;
    import com.java1234.jdbc.util.DbUtil;
    
    public class Demo1 {
    
    private static DbUtil dbUtil=new DbUtil();
        
        /**
         * 添加图书
         * @param book
         * @return
         * @throws Exception
         */
        private static int addBook(Book book)throws Exception{
            Connection con=dbUtil.getCon(); // 获取连接
            String sql="insert into t_book values(null,?,?,?,?,?)";
            PreparedStatement pstmt=con.prepareStatement(sql);
            pstmt.setString(1, book.getBookName());  // 给第一个坑设置值
            pstmt.setFloat(3, book.getPrice());  // 给第二个坑设置值
            pstmt.setString(2, book.getAuthor()); // 给第三个坑设置值
            pstmt.setInt(4, book.getBookTypeId());  // 给第四个坑设置值
            File context=book.getContext(); // 获取文件
            InputStream inputStream=new FileInputStream(context);
    
            pstmt.setAsciiStream(5, inputStream,(int)context.length());  // 给第五个坑设置值
            int result=pstmt.executeUpdate();
            dbUtil.close(pstmt, con);
            return result;
        }
        
        public static void getBook(int id)throws Exception{
            Connection con=dbUtil.getCon();
            String sql="select * from t_book where id=?";
            PreparedStatement pstmt=con.prepareStatement(sql);
            pstmt.setInt(1, id);
            ResultSet rs=pstmt.executeQuery();
            if(rs.next()){
                String bookName=rs.getString("bookName");
                float price=rs.getFloat("price");
                String author=rs.getString("author");
                int bookTypeId=rs.getInt("bookTypeId");
                Clob c=rs.getClob("context");
                String context=c.getSubString(1, (int) c.length());
                System.out.println("图书名称:"+bookName);
                System.out.println("图书价格:"+price);
                System.out.println("图书作者:"+author);
                System.out.println("图书类型ID:"+bookTypeId);
                System.out.println("图书内容:"+context);
            }
            
            dbUtil.close(pstmt, con);
        }
        
        public static void main(String[] args)throws Exception {
    //        String str="C:\152.txt";  
    //        String location=str.replace("\\", "/");  
    //        File context=new File(location);
    //        System.out.println(location);
    //        Book book=new Book("helloWorld", 100, "小锋", 1,context);
    //        int result=addBook(book);
    //        if(result==1){
    //            System.out.println("添加成功!");
    //        }else{
    //            System.out.println("添加失败!");
    //        }
            getBook(6);
        }
    }

           第二节:处理 BLOG 数据

        

    package com.java1234.jdbc.chap06.sec02;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.sql.Blob;
    import java.sql.Clob;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    import com.java1234.jdbc.model.Book;
    import com.java1234.jdbc.util.DbUtil;
    
    public class Demo1 {
    
    private static DbUtil dbUtil=new DbUtil();
        
        /**
         * 添加图书
         * @param book
         * @return
         * @throws Exception
         */
        private static int addBook(Book book)throws Exception{
            Connection con=dbUtil.getCon(); // 获取连接
            String sql="insert into t_book values(null,?,?,?,?,?,?)";
            PreparedStatement pstmt=con.prepareStatement(sql);
            pstmt.setString(1, book.getBookName());  // 给第一个坑设置值
            pstmt.setFloat(3, book.getPrice());  // 给第二个坑设置值
            pstmt.setString(2, book.getAuthor()); // 给第三个坑设置值
            pstmt.setInt(4, book.getBookTypeId());  // 给第四个坑设置值
            File context=book.getContext(); // 获取文件
            InputStream inputStream=new FileInputStream(context);
            pstmt.setAsciiStream(5, inputStream,(int)context.length());  // 给第五个坑设置值
            
            File pic=book.getPic(); // 获取图片文件
            InputStream inputStream2=new FileInputStream(pic);
            pstmt.setBinaryStream(6, inputStream2, (int)pic.length()); // 给第六个坑设置值
            int result=pstmt.executeUpdate();
            dbUtil.close(pstmt, con);
            return result;
        }
        
        public static void getBook(int id)throws Exception{
            Connection con=dbUtil.getCon();
            String sql="select * from t_book where id=?";
            PreparedStatement pstmt=con.prepareStatement(sql);
            pstmt.setInt(1, id);
            ResultSet rs=pstmt.executeQuery();
            if(rs.next()){
                String bookName=rs.getString("bookName");
                float price=rs.getFloat("price");
                String author=rs.getString("author");
                int bookTypeId=rs.getInt("bookTypeId");
                Clob c=rs.getClob("context");
                String context=c.getSubString(1, (int)c.length());
                Blob b=rs.getBlob("pic");
                FileOutputStream out=new FileOutputStream(new File("d:/pic2.jpg"));
                out.write(b.getBytes(1, (int)b.length()));
                out.close();
                System.out.println("图书名称:"+bookName);
                System.out.println("图书价格:"+price);
                System.out.println("图书作者:"+author);
                System.out.println("图书类型ID:"+bookTypeId);
                System.out.println("图书内容:"+context);
            }
            dbUtil.close(pstmt, con);
        }
        
        public static void main(String[] args)throws Exception {
    //        String str="C:\152.txt";  
    //        String location=str.replace("\\", "/");  
    //        File context=new File(location);
    //        String str1="C:\123.jpg";
    //        String str2=str1.replace("\\", "/");  
    //        File pic=new File(str2);
    //        Book book=new Book("helloWorld", 100, "小锋", 1,context,pic);
    //        int result=addBook(book);
    //        if(result==1){
    //            System.out.println("添加成功!");
    //        }else{
    //            System.out.println("添加失败!");
    //        }
            getBook(11);
        }
    }

        注意:1.利用下面这种方式对文件进行读取,防止目录出现问题,一般出现问题,除了是文件名错误外,还有就是复制会带来额外的东西,我们需要手打。

    String str="C:\152.txt";  
    String location=str.replace("\\", "/");  
    File context=new File(location);
    

           2.写入数据时,注意第三行的第三个值要强转成int类型,而且对于CLOG数据,使用setAsciiStream,对于BLOG 数据,要使用setBinaryStream进行写入

    File context=book.getContext(); // 获取文件
    InputStream inputStream=new FileInputStream(context);
    pstmt.setAsciiStream(5, inputStream,(int)context.length()); 
    

          

    File context=book.getContext(); // 获取文件
    InputStream inputStream=new FileInputStream(context);
    pstmt.setAsciiStream(5, inputStream,(int)context.length());  // 给第五个坑设置值
    		
    File pic=book.getPic(); // 获取图片文件
    InputStream inputStream2=new FileInputStream(pic);
    pstmt.setBinaryStream(6, inputStream2, (int)pic.length()); // 给第六个坑设置值
    

          3.读取数据时,对于CLOG数据,用下面这种方法。

    Clob c=rs.getClob("context");
    String context=c.getSubString(1, (int) c.length());
    

                对于BLOG 数据,用接下来这种方法,也就是直接写成多媒体格式。    

    Blob b=rs.getBlob("pic");
    FileOutputStream out=new FileOutputStream(new File("d:/pic2.jpg"));
    out.write(b.getBytes(1, (int)b.length()));
    out.close();
    

      

    第七章: 使用 CallableStatement 接口调用存储过程

        CallableStatement 主要是调用数据库中的存储过程,CallableStatement 也是 PreparedStatement 接口的子接口。在使用 CallableStatement 时可以接收存储过程的返回值

        void registerOutParameter(int parameterIndex, int sqlType) 按顺序位置 parameterIndex 将 OUT 参数注册为 JDBC 类型 sqlType。

        

    private static String getBookNameById(int id)throws Exception{
    		Connection con=dbUtil.getCon();  // 获取数据库连接
    		String sql="{CALL pro_getBookNameById1(?,?)}";
    		CallableStatement cstmt=con.prepareCall(sql);
    		cstmt.setInt(1, id); // 设置第一个参数
    		cstmt.registerOutParameter(2, Types.VARCHAR);  // 设置返回类型
    		cstmt.execute();
    		String bookName=cstmt.getString(1);  // 获取返回值//这里不仅可以利用index,利用关键字也可以。
    		dbUtil.close(cstmt, con);
    		return bookName;
    	}
    	
    

      注意:sql语句外的大括号。

    第八章: 使用元数据分析数据库

        第一节:使用 DatabaseMetaData 获取数据库基本信息

          DatabaseMetaData 可以得到数据库的一些基本信息,包括数据库的名称、版本,以及得到表的信息。

          String getDatabaseProductName() 获取此数据库产品的名称。 int getDriverMajorVersion() 获取此 JDBC 驱动程序的主版本号。

          int getDriverMinorVersion() 获取此 JDBC 驱动程序的次版本号。

    public static void main(String[] args)throws Exception {
    		DbUtil dbUtil=new DbUtil();
    		Connection con=dbUtil.getCon();
    		DatabaseMetaData dmd=con.getMetaData(); // 获取元数据
    		System.out.println("数据库名称:"+dmd.getDatabaseProductName());
    		System.out.println("数据库版本:"+dmd.getDriverMajorVersion()+"."+dmd.getDriverMinorVersion());
    		
    	}
    

      

        第二节:使用 ResultSetMetaData 获取 ResultSet

          ResultSetMetaData 可获取关于 ResultSet 对象中列的基本信息;

          int getColumnCount() 返回此 ResultSet 对象中的列数。

          String getColumnName(int column) 获取指定列的名称。

          int getColumnTypeName(int column) 获取指定列的 SQL 类型名称。

    	public static void main(String[] args) throws Exception{
    		DbUtil dbUtil=new DbUtil();
    		Connection con=dbUtil.getCon();
    		String sql="select * from t_book";
    		PreparedStatement pstmt=con.prepareStatement(sql);
    		ResultSetMetaData rsmd=pstmt.getMetaData();
    		int num=rsmd.getColumnCount(); // 获取元数据列的总数
    		for(int i=1;i<=num;i++){
    			System.out.println(rsmd.getColumnName(i)+","+rsmd.getColumnTypeName(i));
    		}
    	}
    

      

    第九章: JDBC 事务处理

        第一节:事务的概念

          事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,事务 本身具有原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation)、持久性(Durability)4 个特 性,这 4 个特性也被称为 ACID 特征。

    原子性:原子性是事务最小的单元,是不可再分隔的单元,相当于一个个小的数据库操作,这些操作必须同时 成功,如果一个失败了,则一切的操作将全部失败。

    一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效 性,如果事务出现了错误,则回到最原始状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一 致状态。

    隔离性:多个事务可以同时进行且彼此之间无法访问,只有当事务完成最终操作时,才可以看到结果;

    持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。

    package com.java1234.jdbc.chap09.sec04;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.sql.Savepoint;
    
    import com.java1234.jdbc.util.DbUtil;
    
    public class Demo1 {
        
        private static DbUtil dbUtil=new DbUtil();
    
        /**
         * 转出
         * @param con
         * @param accountName
         * @param account
         * @throws Exception
         */
        private static void outCount(Connection con,String accountName,int account)throws Exception{
            String sql="update t_account set accountBalance=accountBalance-? where accountName=?";
            PreparedStatement pstmt=con.prepareStatement(sql);
            pstmt.setInt(1, account);
            pstmt.setString(2, accountName);
            pstmt.executeUpdate();
        }
        
        /**
         * 转入
         * @param con
         * @param accountName
         * @param account
         * @throws Exception
         */
        private static void inCount(Connection con,String accountName,int account)throws Exception{
            String sql="update t_account set account=accountBalance+? where accountName=?";
            PreparedStatement pstmt=con.prepareStatement(sql);
            pstmt.setInt(1, account);
            pstmt.setString(2, accountName);
            pstmt.executeUpdate();
        }
        
        
        public static void main(String[] args) {
            Connection con=null;
            Savepoint sp=null;
            try {
                con=dbUtil.getCon(); 
                con.setAutoCommit(false); // 取消自动提交
                System.out.println("张三开始向李四转账!");
                int account=500;
                outCount(con, "张三", account);
                //sp=con.setSavepoint(); // 设置一个保存点
                inCount(con, "李四", account);
                System.out.println("转账成功!");
            } catch (Exception e) {
                try {
                    con.rollback(); // 回滚到sp保存点
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    con.commit();  // 提交事务
                    con.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

        第二节:MySQL 对事务的支持

          

    只待江流汲海,万木朝东
  • 相关阅读:
    1-Java继承中多态情况特性下变量,方法,静态方法的访问
    3-表约束修改
    2-表结构修改
    持续运维与监控整理
    vscode markdown思维导图插件
    [Python][学习资料]Python学习资料整理
    [高效办公]使用synergy让多台电脑共用一套鼠标键盘
    vim代码片段插件ultisnips的使用
    matplotlib提示RuntimeWarning: Glyph 20998 missing from current font
    vscode使用anaconda的python环境提示“Can't connect to HTTPS URL because the SSL module is not available”
  • 原文地址:https://www.cnblogs.com/wanmudong/p/8127890.html
Copyright © 2020-2023  润新知