JDBC教程(2022-12-18)

第一章:JDBC概述和原理

1.javaSE与数据库复习

前置知识点:
Java:多态  接口  泛型  反射
import javax.management.AttributeList;
import java.util.ArrayList;
import java.util.LinkedList;

public class Review {


    /*
    * Java:回顾
    *           --多态:多种状态 子类对象的多种父累形态 父类类型的引用指向多种不同子类对象
                            含义:就是把子类状态动作某种父类类型的对象来使用*
   父类类型的引用指向多种不同的子类对象 含义就是父类引用指向了子类对象的不明确性
    * */

//    接口:对不同事物共同的行为的抽象  主要用于描述某种能力 或标准规范
//    把子类对象当做一个标准对象来使用 完成一系列操作 而不需要关心子类的细节




//    泛型:解决类型安全问题
    public void test(){

//        list<String>  这个就是集合被约束为只能处理String类型的对象
//        List<T>  表示一种不确定类型  某种类型
//        泛型和继承的关系:子类在继承泛型时 把泛型类型固话  优点:就是子类简单  并且也用到了泛型的好处

    }
    
//    ArrayList extends Object
    
    
    
//    反射:就是反着来
//    第一步:就是获取到;类对象  Class.forName()
    

}


SQL:
DDL:数据定义语言  创建数据库 表 视图  删除表.....
		
		创建数据库:create database if  not exists jdbc  charset utf8mb4;
		查看数据库中的表:show tables;
		创建表:create table if not exists Customer(
				id  int  auto_increment (---表示自增式住建)
				name varchar  notnull  非空约束
		) engine innodb  charset utf8mb3;  ---单独指定引擎
		查看表结构:desc 表名
		查看建表语句:show create table customer
		
DML:数据操作语言    删除  更新 表中数据
	insert into 表名称(字段一,字段二,字段三...) values('类型一','类型二','类型三'...)
	查询:select 字段一,字段二.. from 数据来自的表
	
	创建预编译:prepare
	必须设置用户变量 完成值的传递  字段一定要对应
例如:	set @name='李四' ,@gendr='男'
	
	执行预编译的时 要使用用户变量来传值
	执行预编译:execute 要编译的内容名字
	execute p1 using @name,@gender,@age...
	
	数据更新(update)的预编译语句
	 prepare p2 from 'update customer set name=? ,gender=? ,age=? ,salary=? ,phone=? where id=?'
		
		数据删除:
		prepare p3 from 'delete from customer  where id=?	';
		execute p3 using @id
		
		
		set @id=2;
		
DQL:数据查询语言 select(语句)
DCL:数据控制语言  commit(提交)  rollback(回滚)




2.数据库的连接

数据持久化:把数据保存到可掉点存储设备中以提供之后使用 数据持久化意味着将内存中的数据保存到硬盘上加以固化 持久化的实现过程大多需要通过各种关系数据库来完成
持久化主要应用是将内存中的数据存储在关系型数据库中 当然也可以存储在磁盘文件中 xml数据文件中 但是不太专业

在java中:数据库存取技术可以分为  :JDBC直接访问数据库 或者第三方O/R工具 如mybatis等
JDBC是Java访问数据库的基础

JDBC:是一个独立于特定数据库管理系统 通用的SQL数据库存取操作的公共接口 一组api
JDBC为访问不同的数据提供了一种统一的途径 为开发者屏蔽了一些细节问题

使用JDBC可以连接任何符合JDBC驱动程序的数据库


JDBC api是一系列的接口 他使得应用程序能够进行数据库连接 执行SQL语句 并且得到返回值

常见的Java中JDBC的类:
Driver(接口) :数据库驱动程序的标准
		也就是:java.sql.Driver是所有JDBC驱动程序需要实现的接口 这个接口是提供给数据库厂商使用的 不同数据库厂商提供不同的实现子类
		
		Drive常用的实现类名:
		Oracle的驱动:oracle.jdbc.driver.OracleDriver
		Mysql的驱动:com.mysql.cj.jdbc.Driver


	DriverManger(类) :用于统一管理所有的驱动程序  也就是驱动程序管理器
	Connection(接口):表示的是一个客户端连接的回话(session)
	Statement(接口):表示一个执行体  可以执行SQL
	PrepareStatement(接口):预编译执行体
			Resultset(接口):表示一个查询的结果集  有行有列
            
       驱动程序的导入:
       	创建一个lib文件 
       	
       	
       	
       	package test1;

import com.mysql.cj.jdbc.Driver;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class DriverTest {

    public void test1() throws SQLException {


//        URl :统一资源定位器    协议 主机地址:端口号   资源名
//        MySQL的URL:jdbc:mysql://127.0.0.1:3306/jdbc
//                      主协议:自子协议  主机地址  端口  数据库名
       Driver driver= new com.mysql.cj.jdbc.Driver();
       String url="jdbc:mysql://127.0.0.1:3306/jdbc";

        Properties info=new Properties();
        info.setProperty("user","root");
        info.setProperty("password","root");
        Connection connect = driver.connect(url, info);
        System.out.println(connect);
        System.out.println("连接成功");
//        记得释放资源
        connect.close();


//       info  用于描述和保存用户名密码信息


    }

    public static void main(String[] args) throws SQLException {


        DriverTest d=new DriverTest();
        d.test1();

    }
}


注意:连接之前 一定要把JDBC驱动导入工具库
         

3.连接数据库的最终版

package JDBC;


import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class DriverTest {

    public void test1() throws SQLException {


//        URl :统一资源定位器    协议 主机地址:端口号   资源名
//        MySQL的URL:jdbc:mysql://127.0.0.1:3306/jdbc
//                      主协议:自子协议  主机地址  端口  数据库名
        Driver driver=new com.mysql.cj.jdbc.Driver();
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";

        Properties info=new Properties();
        info.setProperty("user","root");
        info.setProperty("password","root");
        Connection connect = driver.connect(url, info);
        System.out.println(connect);
        System.out.println("连接成功");
//        记得释放资源
        connect.close();


//       info  用于描述和保存用户名密码信息


    }


    public void test2() throws SQLException {
//        连接数据库最终版
        Driver driver =new com.mysql.cj.jdbc.Driver();
//        注册给驱动程序管理器
        DriverManager.registerDriver(driver);//完成注册
        String url="jdbc:mysql://127.0.0.1/jdbc";
        String user="root";
        String password="root";

        Connection connection = DriverManager.getConnection(url, user, password);//这个方法就可以同时传递三个参数
        System.out.println(connection);
        System.out.println("最终版程序连接成功!");
        connection.close();//关闭资源

//        这个方法是最标准的做法

    }


    public void  test3(){

//        方式三:通过反射的方式去创建:
        try {

//在编写程序时 驱动类不一定能马上提供号
            Class clazz=Class.forName("com.mysql.cj.jdbc.Driver");
            Driver driver=(Driver) clazz.newInstance();
        DriverManager.registerDriver(driver);
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            Connection connection = DriverManager.getConnection(url, "root", "root");
            System.out.println(connection);
            System.out.println("第三种版本成功率!");
            connection.close();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


    }


    public static void main(String[] args) throws SQLException {


        DriverTest d=new DriverTest();
//        d.test1();
//        d.test2();
d.test3();
    }


}

package JDBC;


import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class DriverTest {

    public void test1() throws SQLException {


//        URl :统一资源定位器    协议 主机地址:端口号   资源名
//        MySQL的URL:jdbc:mysql://127.0.0.1:3306/jdbc
//                      主协议:自子协议  主机地址  端口  数据库名
        Driver driver=new com.mysql.cj.jdbc.Driver();
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";

        Properties info=new Properties();
        info.setProperty("user","root");
        info.setProperty("password","root");
        Connection connect = driver.connect(url, info);
        System.out.println(connect);
        System.out.println("连接成功");
//        记得释放资源
        connect.close();
//       info  用于描述和保存用户名密码信息

    }


    public void test2() throws SQLException {
//        连接数据库最终版
        Driver driver =new com.mysql.cj.jdbc.Driver();
//        注册给驱动程序管理器
        DriverManager.registerDriver(driver);//完成注册
        String url="jdbc:mysql://127.0.0.1/jdbc";
        String user="root";
        String password="root";

        Connection connection = DriverManager.getConnection(url, user, password);//这个方法就可以同时传递三个参数
        System.out.println(connection);
        System.out.println("最终版程序连接成功!");
        connection.close();//关闭资源

//        这个方法是最标准的做法

    }


    public void  test3(){

//        方式三:通过反射的方式去创建:
        try {

//在编写程序时 驱动类不一定能马上提供号
          /*  Class clazz=Class.forName("com.mysql.cj.jdbc.Driver");
            Driver driver=(Driver) clazz.newInstance();
        DriverManager.registerDriver(driver);
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            Connection connection = DriverManager.getConnection(url, "root", "root");
            System.out.println(connection);
            System.out.println("第三种版本成功率!");
            connection.close();*/

//            最终改版
          Class.forName("com.mysql.cj.jdbc.Driver");
           /* Driver driver=(Driver) clazz.newInstance();
            DriverManager.registerDriver(driver);*/
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            Connection connection = DriverManager.getConnection(url, "root", "root");
            System.out.println(connection);
            System.out.println("第三种版本成功率!");
            connection.close();


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }


    }


    public static void main(String[] args) throws SQLException {


        DriverTest d=new DriverTest();
//        d.test1();
//        d.test2();
d.test3();
    }


}

第二章:使用JDBC操作数据库

1.DML操作

执行SQL的步骤:
		注册驱动
		建立连接(Connection)
		准备好要执行的SQL
		创建执行的SQL执行体(PreparedStatement)
		执行预编译
		释放资源
	
1.DML操作
		在mysql客户端处理DML  使用预编译的方法去执行

--创建预编译
prepare p1 from 'insert into customer(name,gender,salary,phone)  values(?,?,?,?) ';

--创建用户变量来解决sql中的所有?
set @name='李四'  ,@genser='男'  ,@age='18'  ,@salary=4000
,@phone='12343'
--执行预编译:使用到用户变量  一定要一一对应
execute p1 using @name ,@gender,@age,@salary,@phone;
		
		代码示例:
		package JDBC;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DMLTest {


public void test1(){
//    准备工作:
    Connection connection=null;
    PreparedStatement preparedStatement=null;


//   这里的快捷键:Ctrl+alt+t可以快速生成异常语句
    try {
//        注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";
       connection=  DriverManager.getConnection(url,"root","root");

//       准备SQL语句
        String sql="insert into customer(name,gender,age,salary,phone) values(?,?,?,?,?)";

//创建执行SQL的执行体 PreparedStatement
  preparedStatement = connection.prepareStatement(sql);

//  执行预编译  必须解决完成 占位符后才能执行预编译语句
//        PrepareStatement.set  xxx()方法解决问号占位符
//        第一个占位符 使用setString()方法
        preparedStatement.setString(1,"吴邪");//这个语句读作第一个占位符填充的姓名字段是吴邪
//        第二个占位符
        preparedStatement.setString(2,"男");
//        第三个占位符
        preparedStatement.setInt(3,12);
//        第四个占位符
        preparedStatement.setInt(4,2000);
//        第五个占位符
        preparedStatement.setInt(5,1008611);

         int rows= preparedStatement.executeUpdate();//因为这里执行的语句是SQL的数据更新 因此选用update 内部已经绑定了SQL 因此参数就不需要传入SQL
//        因为有返回值 所以创建一个变量rows来接收   返回值返回的是DML语句执行完毕后影响了多少行
        System.out.println(rows+"rows");

    } catch (Exception e) {
        e.printStackTrace();
    } finally {

//    释放资源  :后产生的资源先关闭
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }


//    1.注册驱动



}

    public static void main(String[] args) {
        DMLTest x=new DMLTest();
        x.test1();
    }

}

		
		
		

2.DML数据插入改进

package JDBC;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DMLTest {


public void test1(){
//    准备工作:
    Connection connection=null;
    PreparedStatement preparedStatement=null;


//   这里的快捷键:Ctrl+alt+t可以快速生成异常语句
    try {
//        注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";
       connection=  DriverManager.getConnection(url,"root","root");

//       准备SQL语句
        String sql="insert into customer(name,gender,age,salary,phone) values(?,?,?,?,?)";

//创建执行SQL的执行体 PreparedStatement
  preparedStatement = connection.prepareStatement(sql);

//  执行预编译  必须解决完成 占位符后才能执行预编译语句
//        PrepareStatement.set  xxx()方法解决问号占位符
//        第一个占位符 使用setString()方法
        preparedStatement.setString(1,"吴邪");//这个语句读作第一个占位符填充的姓名字段是吴邪
//        第二个占位符
        preparedStatement.setString(2,"男");
//        第三个占位符
        preparedStatement.setInt(3,12);
//        第四个占位符
        preparedStatement.setInt(4,2000);
//        第五个占位符
        preparedStatement.setInt(5,1008611);

         int rows= preparedStatement.executeUpdate();//因为这里执行的语句是SQL的数据更新 因此选用update 内部已经绑定了SQL 因此参数就不需要传入SQL
//        因为有返回值 所以创建一个变量rows来接收   返回值返回的是DML语句执行完毕后影响了多少行
        System.out.println(rows+"rows");

    } catch (Exception e) {
        e.printStackTrace();
    } finally {

//    释放资源  :后产生的资源先关闭
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }


//    1.注册驱动



}


//    方式二:
public void test2()
    {
//    准备工作:
        Connection connection=null;
        PreparedStatement preparedStatement=null;


//   这里的快捷键:Ctrl+alt+t可以快速生成异常语句
        try {
//        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");

//       准备SQL语句
            String sql="insert into customer(name,gender,age,salary,phone) values(?,?,?,?,?)";

//创建执行SQL的执行体 PreparedStatement
            preparedStatement = connection.prepareStatement(sql);

//  执行预编译  必须解决完成 占位符后才能执行预编译语句

//            使用 PrepareStatement.setObject(?的索引,值)
//        第一个占位符 使用setString()方法

            /*考虑到批量插入的效率问题  所以使用Object数组
            *       为了统一管理所有的占位符  注意数据要一一对应
            * */
            Object[] arr={"王胖子","男",29,2000,10089};
            for (int i = 0; i < arr.length ; i++) {

                preparedStatement.setObject(i+1,arr[i]);


            }
        /*    使用循环来替换了以下内容
            preparedStatement.setObject(1,"张起灵");//这个语句读作第一个占位符填充的姓名字段是吴邪
//        第二个占位符
            preparedStatement.setObject(2,"男");
//        第三个占位符
            preparedStatement.setObject(3,12);
//        第四个占位符
            preparedStatement.setObject(4,2000);
//        第五个占位符
            preparedStatement.setObject(5,1008611);*/

            int rows= preparedStatement.executeUpdate();//因为这里执行的语句是SQL的数据更新 因此选用update 内部已经绑定了SQL 因此参数就不需要传入SQL
//        因为有返回值 所以创建一个变量rows来接收   返回值返回的是DML语句执行完毕后影响了多少行
            System.out.println(rows+"rows");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//    释放资源  :后产生的资源先关闭
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }


//    1.注册驱动



    }











    public static void main(String[] args) {
        DMLTest x=new DMLTest();
//        x.test1();

        x.test2();
    }



}
数据类型转换表:
Java类型								SQL类型
	byte									tinyint
	short									smallint
	long									bigint
	String									char varchar  long text
	byte									binary  varbinary
	date									date
	time									time
	timestamp								timestamp

3.DQL操作

在mysql客户端处理DQl

		prepare p2 from 'select id,name,gender,age,salary,phone from customer where id>?';
		set @id=1;
		execute p2 using @id; --where id>1
		
返回值是一个表格  因此在JDBC中使用Result来接收		

package JDBC;

import java.sql.*;
import java.util.Collection;
import java.util.Properties;

public class DQLTest {

    public void test1(){

//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {

//            注册驱动

//        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";

//            创建执行SQL的执行体
           preparedStatement= connection.prepareStatement(sql);


//            执行预编译  先解决占位符 才可以执行

//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);


            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

//            拿到结果集 后 处理结果集:使用游标  通过ResultSet对象的next()方法移动到下一行
            /*常用方法: Boolean next()方法  判断当前游标后面是否有行  如果有返回TRUE 并向下移动游标
            *           String getString()方法  提供列索引或列标签可以获取当前行
            *
            * */

//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)
//                第一列:
           int id=  resultSet.getInt(1);//把当前游标指向第一列数据取为int值

//                第二列
              String name=  resultSet.getString(2);//把当前游标指向第一列数据为字符串

//                第三列
                String gender =resultSet.getString(3);

//                第四列
                int age=  resultSet.getInt(4);


               int salary=  resultSet.getInt(5);


               int phone=  resultSet.getInt(6);


                System.out.println(id+"\t"+name+"\t"+gender+"\t"+age+"\t"+salary+"\t"+phone);

            }



        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }


    }


    public static void main(String[] args) {

        DQLTest d=new DQLTest();
        d.test1();

    }


}





		

3.DQl数据查询改进

package JDBC;

import java.sql.*;
import java.util.Collection;
import java.util.Properties;

public class DQLTest {

    public void test1(){

//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {

//            注册驱动

//        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";

//            创建执行SQL的执行体
           preparedStatement= connection.prepareStatement(sql);


//            执行预编译  先解决占位符 才可以执行

//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);


            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

//            拿到结果集 后 处理结果集:使用游标  通过ResultSet对象的next()方法移动到下一行
            /*常用方法: Boolean next()方法  判断当前游标后面是否有行  如果有返回TRUE 并向下移动游标
            *           String getString()方法  提供列索引或列标签可以获取当前行
            *
            * */

//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)
//                第一列:
           int id=  resultSet.getInt(1);//把当前游标指向第一列数据取为int值

//                第二列
              String name=  resultSet.getString(2);//把当前游标指向第一列数据为字符串

//                第三列
                String gender =resultSet.getString(3);

//                第四列
                int age=  resultSet.getInt(4);


               int salary=  resultSet.getInt(5);


               int phone=  resultSet.getInt(6);


                System.out.println(id+"\t"+name+"\t"+gender+"\t"+age+"\t"+salary+"\t"+phone);

            }



        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }


    }





    public void test2(){

//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {

//            注册驱动

//        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";

//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);


//            执行预编译  先解决占位符 才可以执行

//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);


            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

//            拿到结果集 后 处理结果集:使用游标  通过ResultSet对象的next()方法移动到下一行
            /*常用方法: Boolean next()方法  判断当前游标后面是否有行  如果有返回TRUE 并向下移动游标
             *           String getString()方法  提供列索引或列标签可以获取当前行
             *
             * */

//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

//                使用列标签来获取数据  这个方法就可以处理无序的列数据
//                xxx=resultSet.getXxx(列标签)

//                第一列:
                int id=  resultSet.getInt("id");//把列索引换位列索引

//                第二列
                String name=  resultSet.getString("name");//把当前游标指向第一列数据为字符串

//                第三列
                String gender =resultSet.getString("gender");

//                第四列
                int age=  resultSet.getInt("age");


                int salary=  resultSet.getInt("salary");


                int phone=  resultSet.getInt("phone");


                System.out.println(id+"\t"+name+"\t"+gender+"\t"+age+"\t"+salary+"\t"+phone);

            }



        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }


    }



    public static void main(String[] args) {

        DQLTest d=new DQLTest();
        d.test1();

    }


}

4.ORM对象关系映射

映射类与数据表中字段一一对应:
package javabean;

public class Customer {


    /*
    *  id int,
        name varchar(10),
        gender varchar(11110),
        age int,
        salary int,
        phone int
    * */

private int id;
private String name;
private String gender;
private int age;
private int salary;
private int phone;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public int getPhone() {
        return phone;
    }

    public void setPhone(int phone) {
        this.phone = phone;
    }

    public Customer(){

}

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", phone=" + phone +
                '}';
    }
}


package JDBC;

import javabean.Customer;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ORMTest {

    /*ORM--对象关系映射
    *
    *
    *
    * */


    public void test2(){

//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {

//            注册驱动

//        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";

//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);


//            执行预编译  先解决占位符 才可以执行

//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);


            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

//            创建一个集合
            List<Customer>  list=new ArrayList<>();


//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)



                Customer obj = new Customer();
//                第一列:
                int id=  resultSet.getInt("id");//把列索引换位列索引
                obj.setId(id);

//                第二列
                String name=  resultSet.getString("name");//把当前游标指向第一列数据为字符串
        obj.setName(name);
//                第三列
                String gender =resultSet.getString("gender");
obj.setGender(gender);
//                第四列
                int age=  resultSet.getInt("age");
obj.setAge(age);

                int salary=  resultSet.getInt("salary");
obj.setSalary(salary);

                int phone=  resultSet.getInt("phone");
obj.setPhone(phone);




//                只需要打印对象  就可以一一输出

//                把对象添加到集合中
                list.add(obj);
//                System.out.println(obj);

            }

//
//统一遍历集合

            for (Customer customer: list) {
                System.out.println(customer);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }


    }

    public static void main(String[] args) {


        ORMTest o=new ORMTest();
        o.test2();
    }
}

5.使用MetaData处理表结构

//        ResultSetMetaData:可用于获取关于Result对象中列的类型和属性信息的对象
//        ResultSetMetaData meta=rs.getMetaData();
//        getColumnCount():返回对象中列数
//        getColumnLabel(int xxx)  获取指定列的别名
            public void test3(){
/*
* 因为可以起别名  因此列标签特指的是查询中的列的别名 所以列标签不等于列名
*
*
* */
//        1.进行准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        DriverManager driverManager=null;
        ResultSet resultSet=null;

        try {

//            准备好数据库的连接对象:
            //        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");




//            预备SQL
            String sql="select id, name, phone,age,gender ,salary from customer where id>?";

//            进行预编译
            preparedStatement= connection.prepareStatement(sql);
//            填写占位符
            Object[] args={1};
            for (int i = 0; i < args.length ; i++) {

                preparedStatement.setObject(i+1,args[i]);

            }

//            执行预编译 并且拿到结果集
           resultSet= preparedStatement.executeQuery();

//            处理结果集

            while (resultSet.next()){

              int id=  resultSet.getInt("id");
               String name= resultSet.getString("name");
                 String gender= resultSet.getString("gender");
               int salary= resultSet.getInt("salary");
              int age=  resultSet.getInt("age");
                int phone= resultSet.getInt("phone");
                System.out.println(id+name+gender+salary+age+phone);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }


    }
package JDBC;

import java.sql.*;

public class MetaDataTest {
    public void test1(){

        /*通过结果对象可以获取到metaData
        *
        * */

//        1.进行准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        DriverManager driverManager=null;
        ResultSet resultSet=null;
        try {
//            准备好数据库的连接对象:
            //        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");
//            预备SQL
            String sql="select id, name, phone,age,gender ,salary from customer where id>?";

//            进行预编译
            preparedStatement= connection.prepareStatement(sql);
//            填写占位符
            Object[] args={1};
            for (int i = 0; i < args.length ; i++) {

                preparedStatement.setObject(i+1,args[i]);

            }

//            执行预编译 并且拿到结果集
            resultSet= preparedStatement.executeQuery();
  ResultSetMetaData metaData= resultSet.getMetaData();//获取到元数据

            int columnCount = metaData.getColumnCount();//使用这个方法获取到表的列数
            System.out.println("列数"+columnCount);

//            拿到列相应的数据      可以使用循环来遍历
            /*String columnLabel1 = metaData.getColumnLabel(1);//获取到第一列的标签
            String columnLabel2 = metaData.getColumnLabel(2);//获取到第二列的标签
            String columnLabel3 = metaData.getColumnLabel(3);//获取到第三列的标签
            String columnLabel4 = metaData.getColumnLabel(4);//获取到第四列的标签
            String columnLabel5 = metaData.getColumnLabel(5);//获取到第一列的标签
            String columnLabel6 = metaData.getColumnLabel(6);//获取到第一列的标签*/
//             System.out.println(columnLabel1+"\t"+columnLabel2+"\t"+columnLabel3+"\t"+columnLabel4+"\t"+columnLabel5+"\t"+columnLabel6);//这个语句可以使用循环来代替

            for (int i = 0; i <columnCount ; i++) {
                String columnLabel = metaData.getColumnLabel(i + 1);
                System.out.print(columnLabel+"\t");
            }
//            处理结果集

            while (resultSet.next()){

                int id=  resultSet.getInt("id");
                String name= resultSet.getString("name");
                String gender= resultSet.getString("gender");
                int salary= resultSet.getInt("salary");
                int age=  resultSet.getInt("age");
                int phone= resultSet.getInt("phone");
                System.out.println(id+"\t"+name+"\t"+gender+"\t"+salary+"\t"+age+"\t"+phone);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }


    }
    public void test2(){

        /*通过结果对象可以获取到metaData
         *
         * */

//        1.进行准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        DriverManager driverManager=null;
        ResultSet resultSet=null;
        try {
//            准备好数据库的连接对象:
            //        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");
//            预备SQL
            String sql="select id, name, phone,age,gender ,salary from customer where id>?";

//            进行预编译
            preparedStatement= connection.prepareStatement(sql);
//            填写占位符
            Object[] args={1};
            for (int i = 0; i < args.length ; i++) {

                preparedStatement.setObject(i+1,args[i]);

            }

//            执行预编译 并且拿到结果集
            resultSet= preparedStatement.executeQuery();
            ResultSetMetaData metaData= resultSet.getMetaData();//获取到元数据

            int columnCount = metaData.getColumnCount();//使用这个方法获取到表的列数
            System.out.println("列数"+columnCount);


            for (int i = 0; i <columnCount ; i++) {
                String columnLabel = metaData.getColumnLabel(i + 1);
                System.out.print(columnLabel+"\t");
            }
//            处理结果集

            while (resultSet.next()){

//                使用对象类Object可以增强速率  resultSet.getObject(“列标签”)
                Object id=  resultSet.getObject("id");
                Object name= resultSet.getObject("name");
                Object gender= resultSet.getObject("gender");
                Object salary= resultSet.getObject("salary");
                Object age=  resultSet.getObject("age");
                Object phone= resultSet.getObject("phone");
                System.out.println(id+"\t"+name+"\t"+gender+"\t"+salary+"\t"+age+"\t"+phone);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }


    }
    public void test3(){

        /*通过结果对象可以获取到metaData
         *
         * */

//        1.进行准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        DriverManager driverManager=null;
        ResultSet resultSet=null;
        try {
//            准备好数据库的连接对象:
            //        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");
//            预备SQL
            String sql="select id, name, phone,age,gender ,salary from customer where id>?";

//            进行预编译
            preparedStatement= connection.prepareStatement(sql);
//            填写占位符
            Object[] args={1};
            for (int i = 0; i < args.length ; i++) {

                preparedStatement.setObject(i+1,args[i]);

            }

//            执行预编译 并且拿到结果集
            resultSet= preparedStatement.executeQuery();
            ResultSetMetaData metaData= resultSet.getMetaData();//获取到元数据

            int columnCount = metaData.getColumnCount();//使用这个方法获取到表的列数
            System.out.println("列数"+columnCount);


//            处理结果集

            while (resultSet.next()){

                for (int i = 0; i <columnCount ; i++) {
                    String columnLabel = metaData.getColumnLabel(i + 1);//获取列标签
                    Object value = resultSet.getObject(columnLabel);//获取列标签对应的数据值
                    System.out.println(value+"\t");
                }
                System.out.println();
//                使用对象类Object可以增强速率  resultSet.getObject(“列标签”)
               /* Object id=  resultSet.getObject("id");
                Object name= resultSet.getObject("name");
                Object gender= resultSet.getObject("gender");
                Object salary= resultSet.getObject("salary");
                Object age=  resultSet.getObject("age");
                Object phone= resultSet.getObject("phone");*/
//                System.out.println(id+"\t"+name+"\t"+gender+"\t"+salary+"\t"+age+"\t"+phone);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {

        MetaDataTest m=new MetaDataTest();
        m.test3();


    }
}

6.使用MetaData完成ORM的测试

package JDBC;

import javabean.Customer;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ORMTest {

    /*ORM--对象关系映射
    * */
    public void test2(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {
//            注册驱动
//        注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//        建立连接
            String url="jdbc:mysql://127.0.0.1:3306/jdbc";
            connection=  DriverManager.getConnection(url,"root","root");
//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<Customer>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                Customer obj = new Customer();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = Customer.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                   field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();
        /*
                Customer obj = new Customer();
//                第一列:
                int id=  resultSet.getInt("id");//把列索引换位列索引
                obj.setId(id);

//                第二列
                String name=  resultSet.getString("name");//把当前游标指向第一列数据为字符串
        obj.setName(name);
//                第三列
                String gender =resultSet.getString("gender");
obj.setGender(gender);
//                第四列
                int age=  resultSet.getInt("age");
obj.setAge(age);

                int salary=  resultSet.getInt("salary");
obj.setSalary(salary);

                int phone=  resultSet.getInt("phone");
obj.setPhone(phone);
*/
//                使用列标签来改进
//                只需要打印对象  就可以一一输出

//                把对象添加到集合中
                list.add(obj);
//                System.out.println(obj);

            }

//
//统一遍历集合
            for (Customer customer: list) {
                System.out.println(customer);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }


        }


    }

    public static void main(String[] args) {


        ORMTest o=new ORMTest();
        o.test2();
    }
}



第三章:封装为工具类

1.封装JDBCUtil

对于数据库连接对象Connection的获取操作会被频繁的使用到 使用封装一个工具类是一个不错的选择
使用资源的释放的操作也是频繁使用到 把这两个功能封装成一个类

jdbc工具类代码:
package util;

import java.sql.*;

public class jdbcutil {

    /*完成连接的获取和资源的释放
    *
    * */



//    1.获取数据库连接对象的方法
    public static Connection getConnection() throws ClassNotFoundException, SQLException {
        //        注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

//        建立连接
        String url="jdbc:mysql://127.0.0.1:3306/jdbc";
        Connection connection=  DriverManager.getConnection(url,"root","root");


return connection;
    }

//    用于释放资源的工具方法
    public static  void  close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){


        if (resultSet !=null){
//            释放资源的顺序是反着的
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }



        }

        if (preparedStatement !=null){


            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection !=null){

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

测试代码:
package JDBC;

import util.jdbcutil;

import java.sql.Connection;
import java.sql.SQLException;

public class JdbcUtilsTest {

    public void  test1(){

//        1.获取连接  调用util方法


        Connection connection=null;
        try {
            jdbcutil.getConnection();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcutil.close(connection,null,null);
        }

        System.out.println("测试成功!");
    }


    public static void main(String[] args) {
        JdbcUtilsTest j=new JdbcUtilsTest();
        j.test1();
    }
}

2.封装DAO–update

DAO:数据访问对象 使用面向对象的方式的思维去解决数据处理的问题

对于数据库表的DML操作可以封装为一个DAO对象中通用方法update 因为只有SQL和args是变化的可以设计为方法的参数

更新数据的工具代码:
package DAO;

/*
*
* 数据访问对象:
*       这个就是一个通用的update操作  可以访问DML
* 一个DML可以宝行?的  args是可变形参 调用方便
* */

这个工具类可以执行的操作是:DML DDL

import util.jdbcutil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JdbcDAo {
    
    public  int update(String sql,Object... args) throws SQLException, ClassNotFoundException {
//在这里调用工具连接方法
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            try {
              connection=jdbcutil.getConnection();
                preparedStatement = connection.prepareStatement(sql);

                for (int i = 0; i < args.length; i++) {
                    preparedStatement.setObject(i + 1, args[i]);
                }
          int rows= preparedStatement.executeUpdate();
                return rows;
            }finally {
//    释放资源  :后产生的资源先关闭
                jdbcutil.close(connection,preparedStatement,null);
            }
    }


}


创建表 ,更新数据的工具代码:

package DAO;

/*
*
* 数据访问对象:
*       这个就是一个通用的update操作  可以访问DML
* 一个DML可以宝行?的  args是可变形参 调用方便
* */

import util.jdbcutil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JdbcDAo {

    public  int update(String sql,Object... args) throws SQLException, ClassNotFoundException {
//在这里调用工具连接方法
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            try {
              connection=jdbcutil.getConnection();
                preparedStatement = connection.prepareStatement(sql);

                for (int i = 0; i < args.length; i++) {
                    preparedStatement.setObject(i + 1, args[i]);
                }
          int rows= preparedStatement.executeUpdate();
                return rows;
            }finally {
//    释放资源  :后产生的资源先关闭
                jdbcutil.close(connection,preparedStatement,null);
            }
    }


}

3.封装DAO-ORM2

DAO:Data Access Object 数据访问对象使用面向对象的思维来解决数据处理的问题

对于数据库表的DML操作可以封装为一个DAO对象中的方法

给教师表添加映射:
package DAO;

/*
*
* 数据访问对象:
*       这个就是一个通用的update操作  可以访问DML
* 一个DML可以宝行?的  args是可变形参 调用方便
* */

import javabean.Customer;
import javabean.teacher;
import util.jdbcutil;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcDAo {


//    方法一:数据的增删改查操作
    public  int update(String sql,Object... args) throws SQLException, ClassNotFoundException {
//在这里调用工具连接方法
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            try {
              connection=jdbcutil.getConnection();
                preparedStatement = connection.prepareStatement(sql);

                for (int i = 0; i < args.length; i++) {
                    preparedStatement.setObject(i + 1, args[i]);
                }
          int rows= preparedStatement.executeUpdate();
                return rows;
            }finally {
//    释放资源  :后产生的资源先关闭
                jdbcutil.close(connection,preparedStatement,null);
            }
    }


//    方法二:把数据表中的数据映射为一个列表
   /* public List<T>  getList(String sql,Object... args){

//        泛型T表示返回数据的类型

    }*/
    public void test1(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {


//            使用工具类
            connection=jdbcutil.getConnection();

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<Customer>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                Customer obj = new Customer();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = Customer.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);


            }

            for (Customer customer: list) {
                System.out.println(customer);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
//          使用工具类里面的释放资源

            jdbcutil.close(connection,preparedStatement,resultSet);


        }


    }


    public void test2(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {


//            使用工具类
            connection=jdbcutil.getConnection();

//            准备好要执行的SQL语句  变化
            String sql="select id,name,age,phone,email,address from teacherTest where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={2};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<teacher>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                teacher obj = new teacher();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = teacher.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);


            }

            for (teacher teacher: list) {
                System.out.println(teacher);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
//          使用工具类里面的释放资源

            jdbcutil.close(connection,preparedStatement,resultSet);

        }
    }

    public static void main(String[] args) {

        JdbcDAo j=new JdbcDAo();
        j.test2();
    }

4.封装DAO–getList1(getList方法)

package DAO;

/*
*
* 数据访问对象:
*       这个就是一个通用的update操作  可以访问DML
* 一个DML可以宝行?的  args是可变形参 调用方便
* */

import javabean.Customer;
import javabean.teacher;
import util.jdbcutil;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcDAo {


//    方法一:数据的增删改查操作
    public  int update(String sql,Object... args) throws SQLException, ClassNotFoundException {
//在这里调用工具连接方法
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            try {
              connection=jdbcutil.getConnection();
                preparedStatement = connection.prepareStatement(sql);

                for (int i = 0; i < args.length; i++) {
                    preparedStatement.setObject(i + 1, args[i]);
                }
          int rows= preparedStatement.executeUpdate();
                return rows;
            }finally {
//    释放资源  :后产生的资源先关闭
                jdbcutil.close(connection,preparedStatement,null);
            }
    }


//    方法二:把数据表中的数据映射为一个列表
   /* public List<T>  getList(String sql,Object... args){

//        泛型T表示返回数据的类型

    }*/
    public void test1(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {


//            使用工具类
            connection=jdbcutil.getConnection();

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<Customer>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                Customer obj = new Customer();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = Customer.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);


            }

            for (Customer customer: list) {
                System.out.println(customer);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
//          使用工具类里面的释放资源

            jdbcutil.close(connection,preparedStatement,resultSet);


        }


    }


    public void test2(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {


//            使用工具类
            connection=jdbcutil.getConnection();

//            准备好要执行的SQL语句  变化
            String sql="select id,name,age,phone,email,address from teacherTest where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={2};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<teacher>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                teacher obj = new teacher();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = teacher.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);


            }

            for (teacher teacher: list) {
                System.out.println(teacher);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
//          使用工具类里面的释放资源

            jdbcutil.close(connection,preparedStatement,resultSet);


        }


    }

//方法三:
//x在这里是方法的局部的泛型类型参数 通过参数来确定x的类型
    public <X>  List<X> getLisr(String sql ,Class<X> clazz,Object... args) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        /*把变化的值设置为参数:
        *       SQL
        *          args
        * */
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {
//            使用工具类
            connection=jdbcutil.getConnection();
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);

//            args要变化

            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<X>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

               X obj = clazz.newInstance();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = clazz.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);
            }
return list;

        } finally {

//            关闭资源
//          使用工具类里面的释放资源
            jdbcutil.close(connection,preparedStatement,resultSet);

        }
    }


    public static void main(String[] args) {

        JdbcDAo j=new JdbcDAo();
        try {
            j.getLisr("select *from customer",Customer.class);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

    }
}

5.封装DAO–getlist方法2

package DAO;

/*
*
* 数据访问对象:
*       这个就是一个通用的update操作  可以访问DML
* 一个DML可以宝行?的  args是可变形参 调用方便
* */

import javabean.Customer;
import javabean.teacher;
import util.jdbcutil;

import java.lang.reflect.Field;
import java.security.PublicKey;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

//整个泛型T表示某种类型  不确定 在这个类被使用时 才能被确定
public class JdbcDAo<T> {
    //升级整个工具类
//    直接把类对象声明为属性
    private Class<T> clazz;//这个是T类对象  用于处理反射  使用构造器来初始化

    public JdbcDAo(Class<T> clazz) {//强制必须传递类对象
        this.clazz = clazz;
    }

    public List<T> getList(String sql, Object... args)throws Exception {

        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {
//            使用工具类
            connection=jdbcutil.getConnection();
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);

//            args要变化

            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<T>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                T obj = clazz.newInstance();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = clazz.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);
            }
            return list;

        } finally {

//            关闭资源
//          使用工具类里面的释放资源
            jdbcutil.close(connection,preparedStatement,resultSet);

        }






    }


//    方法一:数据的增删改查操作
    public  int update(String sql,Object... args) throws SQLException, ClassNotFoundException {
//在这里调用工具连接方法
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            try {
              connection=jdbcutil.getConnection();
                preparedStatement = connection.prepareStatement(sql);

                for (int i = 0; i < args.length; i++) {
                    preparedStatement.setObject(i + 1, args[i]);
                }
          int rows= preparedStatement.executeUpdate();
                return rows;
            }finally {
//    释放资源  :后产生的资源先关闭
                jdbcutil.close(connection,preparedStatement,null);
            }
    }
//    方法二:把数据表中的数据映射为一个列表
   /* public List<T>  getList(String sql,Object... args){

//        泛型T表示返回数据的类型

    }*/
    public void test1(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {


//            使用工具类
            connection=jdbcutil.getConnection();

//            准备好要执行的SQL语句
            String sql="select id,name,gender,age,salary,phone from customer where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={1};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<Customer>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                Customer obj = new Customer();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = Customer.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);


            }

            for (Customer customer: list) {
                System.out.println(customer);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
//          使用工具类里面的释放资源

            jdbcutil.close(connection,preparedStatement,resultSet);


        }


    }
    public void test2(){
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {


//            使用工具类
            connection=jdbcutil.getConnection();

//            准备好要执行的SQL语句  变化
            String sql="select id,name,age,phone,email,address from teacherTest where id>?";
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);
//            执行预编译  先解决占位符 才可以执行
//            解决问号
            Object[] args={2};  //因为 where  id>1
            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<teacher>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

                teacher obj = new teacher();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = teacher.class.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);


            }

            for (teacher teacher: list) {
                System.out.println(teacher);

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

//            关闭资源
//          使用工具类里面的释放资源

            jdbcutil.close(connection,preparedStatement,resultSet);


        }


    }

//方法三:查看任意表的方法
//x在这里是方法的局部的泛型类型参数 通过参数来确定x的类型
    public  static   <X>  List<X> getLisr(String sql ,Class<X> clazz,Object... args) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        /*把变化的值设置为参数:
        *       SQL
        *          args
        * */
//        1.准备工作
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
//使用快捷键快速生成异常代码块   ctrl + alt+t
        try {
//            使用工具类
            connection=jdbcutil.getConnection();
//            创建执行SQL的执行体
            preparedStatement= connection.prepareStatement(sql);

//            args要变化

            for (int i = 0; i<args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

//            因为执行的DQl语句  查询  使用要使用executeQuery()方法
            resultSet= preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            创建一个集合
            List<X>  list=new ArrayList<>();
//            开始处理结果集:
            while (resultSet.next()){//判断当前游标后面是否有数据行  有返回TRUE  没有就返回FALSE 布尔值来控制循环
//                获取当前游标指向的所有列的数据
//               xxx= resultSet.getxxx(列索引)

               X obj = clazz.newInstance();
                for (int i = 0; i <columnCount ; i++) {

                    String columnLabel = metaData.getColumnLabel(i + 1);//从元数据中获取列标签  列标签和类中的属性名一致
                    Object value = resultSet.getObject(columnLabel);//获取终端列标签的数据值
                    System.out.print(value+"\t");
//                    通过反射方式对obj对象的columnLabel属性赋值
                    Field field = clazz.getDeclaredField(columnLabel);//因为列标签是属性名 使用直接以列标签为参数 获取相对应的属性对象
                    field.setAccessible(true);//属性永远可以访问
                    field.set(obj,value);//私有属性不能直接赋值 必须暴力反射


                }
                System.out.println();

                list.add(obj);
            }
return list;

        } finally {

//            关闭资源
//          使用工具类里面的释放资源
            jdbcutil.close(connection,preparedStatement,resultSet);

        }
    }
    

    public static void main(String[] args) {


        JdbcDAo j=new JdbcDAo<>(Customer.class);
        List<Customer> list=null;

        try {
            list = j.getList("select *from customer");
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (Customer Customer:list
             ) {
            System.out.println(Customer);
        }

    }
}

6.封装DAO–之泛型和子类


package DAO;

import javabean.teacher;

import java.util.List;

public class TeacherDAO  extends JdbcDAo<teacher> {



    public TeacherDAO(){

     super(teacher.class);

    }
    
    public static void main(String[] args) {


        TeacherDAO t=new TeacherDAO();
        try {
            List<teacher> list = t.getList("select *from teacherTest");
            for (teacher teacher:list
                 ) {
                System.out.println(teacher);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}


7.JDBC中API总结

Java.sql.DriverManger:用来装载驱动程序 获取数据库连接
java.sql.Connection:用来代表某一指定数据库的连接
java.sql.PreparedStatement:在一个给定的连接中作为SQL执行声明的容器 可用于执行预编译的SQL声明
java.sql.ResultSet:用来代表一个查询的数据的结果集
java.sql.ResultSetMetaData:通过结果集对象调用方法获取getMetaData()

两种实现:面向对象  面向接口



Driver(接口):表示驱动程序
com.mysql.cj.jdbc.Driver(类) :mysql的实现子类
DriverManger(类) :驱动程序的管理器
使用语法:
Driver driver=new  com.mysql.cj.jdbc.Driver();
DriverManager.registerDriver(driver);
Connection connection=DriverManager.getConnection(url,user,password);

Connection(接口):表示数据库的连接会话


String sql="....."
PreparedStatement ps=connection.prepareStatement(sql)
执行;
ps.executeUpdate();这个是执行DDl或DMl
ps.executeQuery()执行DQl查询
		PreparedStatement(接口):表示一个预编译执行体  内部绑定了SQL

执行完以上语句后:就拿到了一个结果集

ResultSet resultSet=ps.executeQuery();  执行了SQL并且返回了一个结果集

处理表结构还需要:
 ResultSetMetaData metaData= resultSet.getMetaData();

		ResultSet(接口):表示一个结果集


第四章:数据库事务

1.数据库事务介绍1

事务:一组逻辑操作单元 使数据从一种状态变为另一种状态
	将一个数据处理执行步骤的结合作为一个单元来处理 执行这些步骤就好像是执行一个单个的命令一样

默认的数据库数据操作是无事物执行的
事务性执行:
无事务执行:	
	
事务处理(事务操作):保证所有的事务都作为一个工作单元来执行 即使出现了故障 都不能改变这种执行方式 当在一个事物中执行多个操作时 要么所有的事物都被提交(commit)  那么这些修改就被永久的保存下来 要么数据库管理系统将发起所做的所有修改 这个事务回滚(rollback)到最初状态


为确保数据库中数据的一致性 数据的操作应当是离散的成组的逻辑单元 当他全部完成时 数据的一致性可以保持 而当这个单元中的一部分操作失败 这个事务应全部视为错误 所有从起点以后的操作应该全部回退到开始状态


事务的ACID属性:
	1.原子性(A):
	事物中的多个DML或DQL是一个整体 要么全成功 要么全失败
	原子性是指事物是一个不可分割的工作单位事物中的操作要么都发生 要么都不发生
	2.一致性(C):一致性。数据在事物前和事物后是一致的 没有数据丢失或增加
		3.隔离性(I):事物之间不可以随意的干扰
		4.持久性:事物有点那个提交 所有会话都能看到提交后的结果	

事务的三个阶段:
1.启动事务:
		set @@autocommit=off
组成事务(DML h和DQL)
	dml dql
结束事务:
	commit(提交):提交 所有的事务都成功
	rollback(回滚):回滚:所有的事务都失败


	

2.数据库事物2

当一个连接对象被创建时  默认情况下是自动提交事物 每一次执行一个sql语句时 如果执行成功 就会向数据库自动提交 而不能回滚


为了让多个SQL语句具作为一个事务:
			1.调用Connection对象的setAutoCommit(false)
			2.在所有的sql语句都成功执行后 就调用commit()提交事务
			3.在出现异常时 调用rollback()回滚事务
			3,最终调用Connection对象的setAutoCommit(true)恢复其自动提交状态
注意:1,确认表的存储引擎为innodb 课使用show create table '表名'查看
2.所有的SQL语句
框架代码:
package JDBC;

import util.jdbcutil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TransactionTest {
    public void  test1(){
//        数据库的事务
//1.先获取到数据库的连接
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            connection=jdbcutil.getConnection();
//        调用Connect对象的setAutoCommit(false) 以取消自动提交事务
            connection.setAutoCommit(false);
//            在所有的SQL语句都执行成功后 调用commit() 提交事务
            String sql="delete from customer where id> ?";
             preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,2);
            int i = preparedStatement.executeUpdate();

            System.out.println(i);

            sql="select *from customer";
             preparedStatement = connection.prepareStatement(sql);
             resultSet = preparedStatement.executeQuery();
                while (resultSet.next()){

                    for (int j = 0; j <6 ; j++) {

                        Object object = resultSet.getObject(i + 1);
                        System.out.print(object);

                    }
                    System.out.println();
                }

//                这里弄一个错误的SQL  来导致错误

            sql="xxxx";
             preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();

//            在所有的SQL语句成功执行后 调用commit提交事物
            connection.commit();

        } catch (Exception e) {
            e.printStackTrace();

//            自出现异常的时候回滚事务
            try {
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

        } finally {

//            在最终的时候还原事物
            try {
                connection.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            jdbcutil.close(connection,preparedStatement,resultSet);
        }


    }


    public static void main(String[] args) {

        TransactionTest t=new TransactionTest();

t.test1();
    }

}

第五章:数据库连接池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值