JDBC

1.概念:

  • Java DataBase Connectivity 】,Java数据库连接
  • 即 ,JDBC的作用是:用Java语言操作数据库

2.本质:

  • 官方定义的一套操作所有关系型数据库的规则/规范( 即接口– API(Application Programming Interface ))

  • 且由关系型数据库厂商自己写JDBC的实现类,实现这套接口(数据库驱动)

  • 真正执行的代码是驱动jar包中的实现类

3.快速入门

步骤

  1. 导入驱动jar包

     图1--查看MySQL版本

    图2---到官网下载对应版本的jar包

    https://downloads.mysql.com/archives/c-j/ 是旧版本 页面有所不同

    MySQL :: Download Connector/J 附上最新版下载地址

     图3---直接下载无需登录注册Oracle官网账号
    • 在src中新建libs包

    • 复制mysql-connector-java-8.0.26.jar 到项目libs目录下

       图4.图5.图6--复制jar包并粘贴
    • 右键—>add as library(添加为库)

       图7--添加为库
  2. 注册驱动

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

注:需要抛出异常(如图)

使用throws Exception代替具体的异常类型(如throws ClassNotFoundException

  1. 获取数据库连接对象 Connection

    create database JDBC_study;use JDBC_study;create table account(idint auto_increment primary key ,namevarchar(10) null,balance doublenull);

    ​ 图8–提前准备的数据表

Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBC_study");//JDBC_study是我的数据库名

MySQL 8.0 以上版本的数据库连接:

  1. com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver

  2. jdbc:mysql://localhost:3306/数据库名更换为jdbc:mysql://localhost:3306/数据库名” />

  3. 定义sql语句

    String sql="update account set balance =500 where id=1";
  4. 获取执行sql语句的对象 statement

    Statement statement =connection.createStatement();
  5. 执行sql,接收返回结果

    int count=statement.executeUpdate(sql);
  6. 处理结果

    System.out.println(count);//
  7. 释放资源

    statement.close();connection.close();

完整代码:

/*JDBC快速入门*/public class jdbcDemo1 { public static void main(String[] args) throws Exception {//1. 导入驱动jar包(已完成)//2. 注册驱动 Class.forName("com.mysql.cj.jdbc.Driver");//可省略//3. 获取数据库连接对象 Connection//第二、三个参数是连接数据库的用户名和密码Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", "root", "Hky6600115");//4. 定义sql语句 String sql="update account set balance =500 where id=1";//5. 获取执行sql语句的对象 statement Statement statement =connection.createStatement();//6. 执行sql,接收返回结果 int count=statement.executeUpdate(sql);//7. 处理结果 System.out.println(count);//8. 释放资源 statement.close(); connection.close(); }}

运行检验:

 图9--控制台输出(暂时不解读)

 图10--刷新数据库可见数据已修改

详解各对象

1️⃣.DriverManager 驱动管理对象

【一个类】

功能:

  • 一、注册驱动:告诉程序应当使用哪一个数据库去驱动jar包

    • static void registerDriver(Driver driver) DriverManager 的方法

      上面快速入门的时候没有注册驱动 ,取而代之的是Class.forName(“com.mysql.jdbc.Driver”)也成功运行,原因如下:

    • 查看mysql.jdbc.Driver的源码可知

      //这是com.mysql.jdbc.Driver的静态代码块,只要使用这个类,就会执行这段代码//而Class.forName("com.mysql.jdbc.Driver")就正好使用到了这个类static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException E) {throw new RuntimeException("Can't register driver!");}}

      因此,我们是通过给forName指定了MySQL的驱动,它帮助我们注册驱动

    • 注意:MySQL5.0之后可以省略注册驱动的步骤

      在jar包中,存在一个java.sql.Driver配置文件,文件中指定了com.mysql.jdbc.Driver

  • 二、获取数据库连接

    • 方法:static Connection getConnection(String url, String user, String password); 带三个参数

    • 参数:

      • url:指定连接的路径

        • 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称【MySQL5.0写法】

        • 语法:jdbc:mysql://ip地址(域名):端口号/JDBC_study" />2️⃣. Connection 数据库连接对象

          功能:

          • 一、获取执行sql的对象

            • 获取普通执行者对象:Statement createStatement();
            • 获取预编译执行者对象:PreparedStatement prepareStatement(String sql);
          • 二、管理事务

            业务操作的多个步骤:要么同时成功,要么同时失败

            数据库可以:开启/提交/回滚事务,针对此有以下三个对应方法:

            • 开启事务:setAutoCommit(boolean autoCommit); 参数为false,则开启事务
            • 提交事务:commit();
            • 回滚事务:rollback();

          3️⃣.statement 执行sql的对象⭐

          功能:

          执行sql对象

          • boolean execute(String sql); 可以执行任意sql语句(了解即可)

          • int executeUpdate(String sql); 执行DML(insert、update、delete)语句以及DDL(create、alert、drop)

            • 返回值:影响的行数

            • eg. 前面运行过的,原先的表格经修改,id=1的balance由1000变成500,则这一行数据受到影响被改变返回值为1(见图9)

              idnamebalance
              1zhangsan1000-->500
              2lisi1000
            • 作用:可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功;反之,则失败

          • ResultSet executeQuery(String sql); 执行DQL(select)

          练习:基础

          1.accunt表 添加一条记录
          2.account表 修改记录
          3.account表 删除一条记录

          import java.sql.*;/*1.accunt表 添加一条记录 */public class jdbcDemo2 {public static void main(String[] args) throws Exception{Statement statement=null;Connection connection=null;try {//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.定义sqlString sql="insert into account values(null,'wangwu',3000)";//3.获取connection对象connection= DriverManager.getConnection("jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", "root", "Hky6600115");//4.获取执行sql的对象statementstatement=connection.createStatement();//5.执行sqlint count=statement.executeUpdate(sql);//影响行数【增加一行,应返回1】//6.处理结果System.out.println(count);if (count>0){System.out.println("执行成功");}else {System.out.println("执行失败");}}catch (ClassNotFoundException e){e.printStackTrace();}catch (SQLException e){e.printStackTrace();/*释放但因作用域问题报错-->因此提升作用域statement.close();connection.close(); */}finally {//7.释放资源//避免空指针异常if(statement!=null){try {statement.close();}catch (SQLException e){e.printStackTrace();}}if(connection!=null){try {connection.close();}catch (SQLException e){e.printStackTrace();}}}}}

          请仿造以上练习1的代码 ,完成练习2以及练习3

          4️⃣.ResultSet 结果集对象
          • boolean next()
            • 如果有数据返回true,且光标向下移动一行
            • 没有则返回false
          • XXX getXxx(列名/列编号)
            • XXX 表示数据类型 eg.int、String
            • 例如:int getInt(int)可以有 int getInt(1)或者int getInt("id")

          代码示例:

          import java.sql.*;public class jdbcDemo5 {public static void main(String[] args) {Connection connection=null;Statement statement=null;ResultSet resultSet=null;try {Class.forName("com.mysql.cj.jdbc.Driver");String sql="select * from account";connection= DriverManager.getConnection("jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","Hky6600115");statement=connection.createStatement();resultSet= statement.executeQuery(sql);//处理结果//1.让光标向下移动一行(默认在列名一行)resultSet.next();//2.获取数据int id=resultSet.getInt("id");String name=resultSet.getString("name");double balance=resultSet.getDouble("balance");//3.打印数据System.out.println(id+"---"+name+"---"+balance);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}finally {if(resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if(statement!=null){try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}}

          图--运行结果

          练习:遍历

          案例代码:

          其他步骤不变,仅改变数据处理过程

          //处理结果(输出全部数据)//1.判断游标是否为最后一行末尾while (resultSet.next()){//2.获取数据int id=resultSet.getInt("id");String name=resultSet.getString("name");double balance=resultSet.getDouble("balance");//3.打印数据System.out.println(id+"---"+name+"---"+balance);}

          练习:封装对象

          数据准备:

          insert into emp VALUES(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),(100,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),(1006,'宋江',2,1009, '2001-05-01','28500.00',NULL,30),(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);

          要求:定义一个方法,查询emp表中的数据并将其封装为对象,然后装载集合,返回

          步骤:

          1. 定义emp类
          2. 定义方法 public List findAll(){}
          3. 实现方法 select*from emp;

          代码实现:

          1. 配置文件jdbc.properties
          url="jdbc:mysql:///JDBC_study" />user=rootpassword=Hky6600115'driver=com.mysql.cj.jdbc.Driver
          1. JDBCUtils工具类
          public class JDBCUtils{private static String url;private static String user;private static }

          抽取JDBC工具类(JDBCUtils)
          • 目的:简化书写

          • 分析:

            1. 注册驱动

            2. 连接对象

              1. 需求:

                • 传递参数❌(太麻烦)

                • 保障工具类的通用性(MySQL5.0/MySQL8.0的url不同)

              2. 解决:配置文件jdbc.properties【在src下创建】

                url=“”

                user=“”

                password=“”

                driver=“”

          实现代码:

          import java.io.FileReader;import java.io.IOException;import java.net.URL;import java.sql.*;import java.util.Properties;/*JDBC工具类 */public class JDBCUtils {/*文件的读取只需要一次,便可以得到所有值利用【静态代码块】 */private static String url;private static String user;private static String password;private static String driver;static {//读取资源文件,获取值try {//1.创建properties集合类Properties properties=new Properties();//获取src路径下的文件的方式-->classLoader 类加载器ClassLoader classLoader = JDBCUtils.class.getClassLoader();URL resource= classLoader.getResource("jdbc.properties");String path = resource.getPath();//System.out.println(path);//2.加载文件//properties.load(new FileReader("jdbc.properties"));properties.load(new FileReader(path));//3.获取数据,赋值url=properties.getProperty("url");user=properties.getProperty("user");password=properties.getProperty("password");driver=properties.getProperty("driver");//4.注册驱动Class.forName(driver);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}//获取连接public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}//释放资源public static void close(ResultSet resultSet, Statement statement, Connection connection){if(resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if(statement!=null){try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}public static void close(PreparedStatement preparedStatement, Connection connection) {if(preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}

          工具类练习

          需求:

          1. 通过键盘录入用户名和密码
          2. 判断用户是否登录成功
            • select * from user where username=““and password =””;
            • 如果该sql语句有查询结果,则表示成功,反之则失败

          步骤:

          1. 创建数据表user

            create table user(id int primary key auto_increment,username varchar(32),password varchar(32));insert into user values (null,'zhangsan','123');insert into user values (null,'lisi','234');
          2. 编写登录方法

          代码实现:

          /*登录方法 */public boolean logion(String username,String password) {if(username==null||password==null){return false;}//连接数据库判断是否登录成功Connection connection=null;Statement statement=null;ResultSet resultSet=null;try {connection= JDBCUtils.getConnection();String sql="select * from user where username='"+username+"'and password='"+password+"' ";statement=connection.createStatement();resultSet=statement.executeQuery(sql);return resultSet.next();} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(resultSet,statement,connection);}return false;}

          5️⃣.PreparedStatement 执行sql的对象
          • sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题

            • 以上面的练习为例

              • 输入用户名:随机(eg.wangwu)

              • 输入密码:a ’ or ’ a ’ = ’ a

                • sql语句:select * from user where username =‘wangwu’ and password='a’or’a’=‘a’;
                • 原sql语句:“select * from user where username='”+username+“‘and password=’”+password+"’ "

                仔细对比观察

          • 经典例子:

          漫画中,该学生的姓名为“Robert’); DROP TABLE students;–”,导致students表被删除:

          • 解决:使用PreparedStatement 对象

          • 预编译sql:参数使用" />/*登录方法,使用PreparedStatement 对象 */public boolean logion(String username,String password) {if(username==null||password==null){return false;}//连接数据库判断是否登录成功Connection connection=null;ResultSet resultSet=null;PreparedStatement preparedStatement=null;try {connection= JDBCUtils.getConnection();String sql="select * from user where username=?and password=?";PreparedStatement=connection.preparedStatement(sql);preparedStatement.setString(1,username);preparedStatement.setString(2,password);resultSet=preparedStatement.executeQuery();return resultSet.next();} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(resultSet,preparedStatement,connection);}return false;}

            • 注意:后期改用 preparedStatement 来完成增删改查的操作
              • 优势:
                1. 防止sql注入
                2. 效率更高

            JDBC控制事务

            • 事务 :一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。

            • 操作:

              • 开启事务
              • 提交事务
              • 回滚事务
            • 使用connection对象来管理事务

              • 开启事务 setAutoCommit(boolean autoCommit) : 调用该方法设置参数为 false,即开启事务
                • 在执行sql之前开启事务
              • 提交事务 commit()
                • 当所有sql都执行完提交事务
              • 回滚事务 rollback()
                • 在catch中回滚事务
            练习:转账

            代码实现:

            import cn.itcast.util.JDBCUtils;import java.sql.*;/*事务操作 */public class jdbcDemo10 {/*转账方法 */public static void main(String[] args) throws Exception {Connection connection=null;PreparedStatement preparedStatement1=null;PreparedStatement preparedStatement2=null;ResultSet resultSet=null;try {//1.获取连接connection= JDBCUtils.getConnection();//开启事务connection.setAutoCommit(false);//2.定义sql//2.1. 张三-500//2.2. 李四+500String sql1="update account set balance = balance - ? where id = ?";String sql2="update account set balance = balance + ? where id = ?";//3.获取执行对象preparedStatement1=connection.prepareStatement(sql1);preparedStatement2=connection.prepareStatement(sql2);//4.设置参数preparedStatement1.setDouble(1,500);preparedStatement1.setInt(2,1);preparedStatement2.setDouble(1,500);preparedStatement2.setInt(2,2);//5.执行sqlpreparedStatement1.executeUpdate();preparedStatement2.executeUpdate();//提交事务connection.commit();} catch (Exception e) {//事务回滚try {if(connection!=null){connection.rollback();}}catch (SQLException e1){e1.printStackTrace();}e.printStackTrace();}finally {JDBCUtils.close(preparedStatement1,connection);JDBCUtils.close(preparedStatement2,null);}}}

            数据库与连接池

            1. 概念

            存放数据库连接的一个容器(集合)Connection

            当系统运行起来之后,这个连接池就被创建,在这个连接池当中,会申请一些对象,当有用户来访问数据库的时候,就从这个连接池当中获取连接对象,用户访问结束之后,连接池对象会归还给容器

            2.优点:

            • 节约资源
            • 用户访问高效

            3. 连接池实现:

            • java官方提供的数据库连接池规范(接口):DataSource (javax.sql包下)
              • 方法:【获取连接:getConnection();
              • 【归还连接池对象:conn.close();
            • 由数据库厂商为我们实现该接口
              • C3P0
              • Druid (阿里巴巴开发)

            4.C3P0

            步骤:
            1. 导入jar包

            官网:https://sourceforge.net/

            进入官网,搜索框中输入c3p0,并点击下面的提示


            点击下载即可


            解压后,在lib文件夹中,复制如下两个jar包到项目lib文件夹中(还有不能忘记数据库驱动jar包mysql-connector-java-8.0.26.jar


            右键libs添加为库

            2. 定义配置文件:
            • 文件命名为:c3p0.properties 或者 c3p0-config.xml
            • 位置:src目录下
            • 1.自定义的c3p0-config.xml
            <c3p0-config><default-config><property name="driverClass">com.mysql.cj.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_study</property><property name="user">root</property><property name="password">Hky6600115</property><property name="initialPoolSize">5</property><property name="maxPoolSize">10</property><property name="checkoutTimeout">3000</property></default-config><named-config name="otherc3p0"> <property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property><property name="user">root</property><property name="password">root</property><property name="initialPoolSize">5</property><property name="maxPoolSize">8</property><property name="checkoutTimeout">1000</property></named-config></c3p0-config>
            • 2.参数解释
              • initialPoolSize:初始化申请的连接数量
              • maxPoolSize:最大的连接数量
              • checkoutTimeout:超时时间
            3. 创建核心对象

            数据库连接池对象 ComboPooledDataSource

            4. 获取连接

            getConnection

            代码实现:

            import com.mchange.v2.c3p0.ComboPooledDataSource;import javax.sql.DataSource;import java.sql.Connection;/*c3p0的演示 */public class c3p0Demo1 {public static void main(String[] args) throws Exception {//1.创建数据库连接池对象DataSource dataSource=new ComboPooledDataSource();//2.获取连接对象Connection connection = dataSource.getConnection();//3.打印System.out.println(connection);}}

            参数检验:

            5

            10

            3000

            1. 检验最大连接数量
            public class c3p0Demo2 {public static void main(String[] args) throws Exception {DataSource dataSource=new ComboPooledDataSource();for (int i=1;i<=10;i++){Connection connection=dataSource.getConnection();System.out.println(i+":"+connection);}}}

            运行结果:(正常)

            2. 检验超时时间

            –> 运行有错误会等带一段时间再报错

             for (int i=1;i<=11;i++){Connection connection=dataSource.getConnection();System.out.println(i+":"+connection);}

            运行结果:(先输出正常部分,隔3秒报错)

            若中途归还对象,即可正常(重复使用)

            public static void main(String[] args) throws SQLException {DataSource dataSource=new ComboPooledDataSource();for (int i=1;i<=11;i++){Connection connection=dataSource.getConnection();System.out.println(i+":"+connection);if(i==5){connection.close();}}}
            注:
            • DataSource dataSource=new ComboPooledDataSource();表示使用默认配置
            • DataSource dataSource=new ComboPooledDataSource("otherc3p0");表示使用指定名称配置

            5.Druid

            步骤:
            1. 导入jar包

            官网下载地址:Central Repository: com/alibaba/druid (maven.org)

            (详见c3p0)

            2.定义配置文件
            • 是properties形式的
            • 可以叫任意名称,可以放在任意目录下
              • 不会自动加载,需要手动
            //示例 druid.propertiesdriverClassName=com.mysql.cj.jdbc.Driverurl=jdbc:mysql:///JDBC_study" />3. 获取数据库连接池对象 

            通过工厂类来获取 DruidDataSourceFactory

            4. 获取连接

            getConnection

            代码实现:
            import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.InputStream;import java.sql.Connection;import java.util.Properties;public class DruidDemo {public static void main(String[] args) throws Exception {//加载配置文件Properties properties=new Properties();InputStream inputStream=DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");properties.load(inputStream);//获取连接池对象DataSource dataSource =DruidDataSourceFactory.createDataSource(properties);//获取连接Connection connection=dataSource.getConnection();System.out.println(connection);}}

            定义工具类
            1. 定义一个类
            2. 静态代码块
            • 提供静态代码块加载配置文件,初始化连接池对象
            3. 提供方法
            • 获取连接方法;通过数据库连接池获取连接
            • 释放资源
            • 获取连接池的方法
            代码实现:
            import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.IOException;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;/*Druid连接池工具类 */public class JDBCUtils {private static DataSource dataSource;static {try {Properties properties=new Properties();properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));dataSource= DruidDataSourceFactory.createDataSource(properties);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*获取连接的方法 */public static Connection getConnection() throws SQLException {return dataSource.getConnection();}/*释放资源 */public static void close(ResultSet resultSet,Statement statement, Connection connection){if (resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement!=null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); }}if (connection!=null){try {connection.close();//归还连接} catch (SQLException e) {e.printStackTrace();}}}public static void close(Statement statement, Connection connection){close(null,statement,connection);}/*获取连接池 */public static DataSource getDataSource(){return dataSource;}}

            JDBCTemplate

            Spring框架对JDBC的简单封装,提供了一个JdbcTemplate对象,大大的简化了开发

            步骤

            1. 导入jar包

            以下是我的下载参考页面地址↓

            spring jar包 以及 jdbcTemplate 相关jar包下载_jdbctemplate的jar包-CSDN博客

            2.创建JdbcTemplate对象
            • 依赖于数据源DataSource

            JdbcTemplate template = new jdbcTemplate(dataSource);

            import cn.itcast.JDBC数据库与连接池.datasource.utils.JDBCUtils;import org.springframework.jdbc.core.JdbcTemplate;/*JDBCTemplateDemo1 入门 */public class JDBCTemplateDemo1 {public static void main(String[] args) {//1.导入jar包//2.创建JDBCTemplateJdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());//3.调用方法String sql="update account set balance=5000 wheretoken punctuation">;int count =template.update(sql,2);System.out.println(count);}}
            3. 调用JdbcTemplate的方法来完成CRUD的操作
            • update():执行DML语句。增、删、改语句
            • queryForMap():查询结果将结果集封装为map集合
            • queryForList():查询结果将结果集封装为list集合
            • query():查询结果,将结果封装为JavaBean对象
            • queryForobject:查询结果,将结果封装为对象
            4. 练习
            • 修改1号数据的 salary 为 10000
            • 添加一条记录
            • 删除刚才添加的记录
            • 查询id为1的记录,将其封装为Map集合
            • 查询所有记录,将其封装为List
            • 查询所有记录,将其封装为Emp对象的List集合
            • 查询总记录数