A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 社会人 初级黑马   /  2018-12-10 11:56  /  793 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

第三天多表查询
  • 查询语法:select        列名列表from        表名列表where....
  • 准备sql
    创建部门表
    CREATE TABLE dept(        id INT PRIMARY KEY AUTO_INCREMENT,        NAME VARCHAR(20));INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
    创建员工表
    ​         ​                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ​        id INT PRIMARY KEY AUTO_INCREMENT,        NAME VARCHAR(10),        gender CHAR(1), -- 性别        salary DOUBLE, -- 工资        join_date DATE, -- 入职日期        dept_id INT,        FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键));INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);
  • 笛卡尔积:
    • 有两个集合A,B .取这两个集合的所有组成情况。
    • 要完成多表查询,需要消除无用的数据

  • 多表查询的分类:
    • 内连接查询:
      • 隐式内连接:使用where条件消除无用数据
        • 例子:-- 查询所有员工信息和对应的部门信息

        SELECT * FROM emp,dept WHERE emp.dept_id = dept.id`;
        -- 查询员工表的名称,性别。部门表的名称SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.dept_id= dept.id`;
        SELECT         t1.name, -- 员工表的姓名        t1.gender,-- 员工表的性别        t2.name -- 部门表的名称FROM        emp t1,        dept t2WHERE         t1.dept_id = t2.id`;
        • 显式内连接:
          • 语法: select 字段列表 from 表名1 [inner] join 表名2 on 条件
            • 例如:
              • SELECT * FROM emp INNER JOIN dept ON emp.dept_id = dept.id`;        SELECT * FROM emp JOIN dept ON emp.dept_id= dept.id`;       



          • 内连接查询:
            • 从哪些表中查询数据
            • 条件是什么
            • 查询哪些字段


        • 外链接查询:
          • 左外连接:
            • 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
            • 查询的是左表所有数据以及其交集部分。
            • 例子:-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称SELECT         t1.*,t2.name FROM emp t1 LEFT JOIN dept t2 ON t1.dept_id= t2.id`;

          • 右外连接:
            • 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
            • 查询的是右表所有数据以及其交集部分。
            • 例子:SELECT         * FROM dept t2 RIGHT JOIN emp t1 ON t1.dept_id = t2.id`;


        • 子查询:
          • 概念:查询中嵌套查询,称嵌套查询为子查询。-- 查询工资最高的员工信息-- 1 查询最高的工资是多少 9000SELECT MAX(salary) FROM emp;
            -- 2 查询员工信息,并且工资等于9000的SELECT * FROM emp WHERE emp.`salary = 9000;
            -- 一条sql就完成这个操作。子查询SELECT * FROM emp WHERE emp.salary` = (SELECT MAX(salary) FROM emp);
          • 子查询不同情况
            • 子查询的结果是单行单列的:
              • 子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =
              • -- 查询员工工资小于平均工资的人SELECT * FROM emp WHERE emp.salary < (SELECT A-;







事务
  • 事务的基本介绍
    • 概念:
      • 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。

    • 操作:
      • 开启事务: start transaction;
      • 回滚:rollback;
      • 提交:commit;

    • 例子:CREATE TABLE account (        id INT PRIMARY KEY AUTO_INCREMENT,        NAME VARCHAR(10),        balance DOUBLE);-- 添加数据INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);


SELECT * FROM account;UPDATE account SET balance = 1000;-- 张三给李四转账 500 元
-- 0. 开启事务START TRANSACTION;-- 1. 张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';-- 2. 李四账户 +500-- 出错了...UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 发现执行没有问题,提交事务COMMIT;
-- 发现出问题了,回滚事务ROLLBACK;
  • MySQL数据库中事务默认自动提交
    • 事务提交的两种方式:
      • 自动提交:
        • mysql就是自动提交的
        • 一条DML(增删改)语句会自动提交一次事务。

      • 手动提交:
        • Oracle 数据库默认是手动提交事务
        • 需要先开启事务,再提交


    • 修改事务的默认提交方式:
      • 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交  0 代表手动提交
      • 修改默认提交方式: set @@autocommit = 0;



  • 事务的四大特征:
    • 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
    • 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
    • 隔离性:多个事务之间。相互独立。
    • 一致性:事务操作前后,数据总量不变

  • 事务的隔离级别(了解)
    • 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
    • 存在问题:
      • 脏读:一个事务,读取到另一个事务中没有提交的数据
      • 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
      • 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。

    • 隔离级别:
      • read uncommitted:读未提交
        • 产生的问题:脏读、不可重复读、幻读

      • read committed:读已提交 (Oracle)
        • 产生的问题:不可重复读、幻读

      • repeatable read:可重复读 (MySQL默认)
        • 产生的问题:幻读

      • serializable:串行化
        • 可以解决所有的问题


      • 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
      • 数据库查询隔离级别:
        • select @@tx_isolation;

      • 数据库设置隔离级别:
        • set global transaction isolation level  级别字符串;


    • 演示:set global transaction isolation level read uncommitted;start transaction;-- 转账操作update account set balance = balance - 500 where id = 1;update account set balance = balance + 500 where id = 2;


DCL
SQL分类:        1. DDL:操作数据库和表        2. DML:增删改表中数据        3. DQL:查询表中数据        4. DCL:管理用户,授权
  • DBA:数据库管理员
  • DCL:管理用户,授权
    • 管理用户
      • 添加用户:
        • 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';

      • 删除用户:
        • 语法:DROP USER '用户名'@'主机名';

      • 修改用户密码:
        UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';
        SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');
        • mysql中忘记了root用户的密码?
          • cmd -- > net stop mysql 停止mysql服务
            • 需要管理员运行该cmd

          • 使用无验证方式启动mysql服务: mysqld --skip-grant-tables
          • 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功
          • use mysql;
          • update user set password = password('你的新密码') where user = 'root';
          • 关闭两个窗口
          • 打开任务管理器,手动结束mysqld.exe 的进程
          • 启动mysql服务
          • 使用新密码登录。


      • 查询用户:-- 1. 切换到mysql数据库USE myql;-- 2. 查询user表SELECT * FROM USER;
        • 通配符: % 表示可以在任意主机使用用户登录数据库


    • 权限管理:
      • 查询权限:-- 查询权限SHOW GRANTS FOR '用户名'@'主机名';SHOW GRANTS FOR 'lisi'@'%';
      • 授予权限:-- 授予权限grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';-- 给张三用户授予所有权限,在任意数据库任意表上
        GRANT ALL ON . TO 'zhangsan'@'localhost';
      • 撤销权限:-- 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';REVOKE UPDATE ON db3.account` FROM 'lisi'@'%';



第四天JDBC
  • 概念:Java DataBase Connectivity  Java 数据库连接, Java语言操作数据库
    • JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。

  • 快速入门:
    • 步骤:
      • 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下2.右键-->Add As Library
      • 注册驱动
      • 获取数据库连接对象 Connection
      • 定义sql
      • 获取执行sql语句的对象 Statement
      • 执行sql,接受返回结果
      • 处理结果
      • 释放资源

    • 代码实现://1. 导入驱动jar包   //2.注册驱动   Class.forName("com.mysql.jdbc.Driver");   //3.获取数据库连接对象   Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");   //4.定义sql语句   String sql = "update account set balance = 500 where id = 1";   //5.获取执行sql的对象 Statement   Statement stmt = conn.createStatement();   //6.执行sql   int count = stmt.executeUpdate(sql);   //7.处理结果   System.out.println(count);   //8.释放资源   stmt.close();   conn.close();

  • 详解各个对象:
    • DriverManager:驱动管理对象
      • 功能:
        • 注册驱动:告诉程序该使用哪一个数据库驱动jarstatic void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。 写代码使用:  Class.forName("com.mysql.jdbc.Driver");通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块 static {        try {            java.sql.DriverManager.registerDriver(new Driver());        } catch (SQLException E) {            throw new RuntimeException("Can't register driver!");        }        }
          注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
        • 获取数据库连接:
          • 方法:static Connection getConnection(String url, String user, String password)
          • 参数:
            • url:指定连接的路径
              • 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
              • 例子:jdbc:mysql://localhost:3306/db3
              • 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称

            • user:用户名
            • password:密码




    • Connection:数据库连接对象
      • 功能:
        • 获取执行sql 的对象
          • Statement createStatement()
          • PreparedStatement prepareStatement(String sql)  

        • 管理事务:
          • 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
          • 提交事务:commit()
          • 回滚事务:rollback()



    • Statement:执行sql的对象
      • 执行sql
        • boolean execute(String sql) :可以执行任意的sql 了解
        • int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
          • 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。

        • ResultSet executeQuery(String sql)  :执行DQL(select)语句

      • 练习:
        • account表 添加一条记录
        • account表 修改记录
        • account表 删除一条记录

        代码:        Statement stmt = null;      Connection conn = null;      try {          //1. 注册驱动          Class.forName("com.mysql.jdbc.Driver");          //2. 定义sql          String sql = "insert into account values(null,'王五',3000)";          //3.获取Connection对象          conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");          //4.获取执行sql的对象 Statement          stmt = conn.createStatement();          //5.执行sql          int count = stmt.executeUpdate(sql);//影响的行数          //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();  }finally {      //stmt.close();      //7. 释放资源      //避免空指针异常      if(stmt != null){          try {              stmt.close();          } catch (SQLException e) {              e.printStackTrace();          }      }
          if(conn != null){      try {          conn.close();      } catch (SQLException e) {          e.printStackTrace();      }  }
          }

    • ResultSet:结果集对象,封装查询结果
      • boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
      • getXxx(参数):获取数据
        • Xxx:代表数据类型   如: int getInt() ,        String getString()
        • 参数:
          • int:代表列的编号,从1开始   如: getString(1)
          • String:代表列名称。 如: getDouble("balance")


      • 注意:
        • 使用步骤:
          • 游标向下移动一行
          • 判断是否有数据
          • 获取数据

          //循环判断游标是否是最后一行末尾。      while(rs.next()){          //获取数据          //6.2 获取数据          int id = rs.getInt(1);          String name = rs.getString("name");          double balance = rs.getDouble(3);
          System.out.println(id + "---" + name + "---" + balance);                    }

      • 练习:
        • 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。
          • 定义Emp类
          • 定义方法 public List<Emp> findAll(){}
          • 实现方法 select * from emp;



    • PreparedStatement:执行sql的对象
      • SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
        • 输入用户随便,输入密码:a' or 'a' = 'a
        • sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'

      • 解决sql注入问题:使用PreparedStatement对象来解决
      • 预编译的SQL:参数使用?作为占位符
      • 步骤:
        • 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
        • 注册驱动
        • 获取数据库连接对象 Connection
        • 定义sql
          • 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;

        • 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql)
        • 给?赋值:
          • 方法: setXxx(参数1,参数2)
            • 参数1:?的位置编号 从1 开始
            • 参数2:?的值


        • 执行sql,接受返回结果,不需要传递sql语句
        • 处理结果
        • 释放资源

      • 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
        • 可以防止SQL注入
        • 效率更高




抽取JDBC工具类:JDBCUtils
  • 目的:简化书写
  • 分析:
    • 注册驱动也抽取
    • 抽取一个方法获取连接对象
      • 需求:不想传递参数(麻烦),还得保证工具类的通用性。
      • 解决:配置文件jdbc.properties        url=        user=        password=



  • 抽取一个方法释放资源

  • 代码实现:public class JDBCUtils {  private static String url;  private static String user;  private static String password;  private static String driver;  /**
    • 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块*/  static{

    //读取资源文件,获取值。
      try {      //1. 创建Properties集合类。      Properties pro = new Properties();
      //获取src路径下的文件的方式--->ClassLoader 类加载器  ClassLoader classLoader = JDBCUtils.class.getClassLoader();  URL res  = classLoader.getResource("jdbc.properties");  String path = res.getPath();  System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties  //2. 加载文件 // pro.load(new FileReader("D:\IdeaProjects\itcast\day04_jdbc\src\jdbc.properties"));  pro.load(new FileReader(path));
      //3. 获取数据,赋值  url = pro.getProperty("url");  user = pro.getProperty("user");  password = pro.getProperty("password");  driver = pro.getProperty("driver");  //4. 注册驱动  Class.forName(driver);
      } catch (IOException e) {      e.printStackTrace();  } catch (ClassNotFoundException e) {      e.printStackTrace();  }
      }

/**
  • 获取连接
  • @return 连接对象*/public static Connection getConnection() throws SQLException {
    return DriverManager.getConnection(url, user, password);}

/**
  • 释放资源
  • @param stmt
  • @param conn*/public static void close(Statement stmt,Connection conn){if( stmt != null){    try {        stmt.close();    } catch (SQLException e) {        e.printStackTrace();    }}
    if( conn != null){    try {        conn.close();    } catch (SQLException e) {        e.printStackTrace();    }}}

/**
  • 释放资源
  • @param stmt
  • @param conn*/public static void close(ResultSet rs,Statement stmt, Connection conn){if( rs != null){    try {        rs.close();    } catch (SQLException e) {        e.printStackTrace();    }}
    if( stmt != null){    try {        stmt.close();    } catch (SQLException e) {        e.printStackTrace();    }}
    if( conn != null){    try {        conn.close();    } catch (SQLException e) {        e.printStackTrace();    }}}

}
JDBC控制事务:
  • 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
  • 操作:
    • 开启事务
    • 提交事务
    • 回滚事务

  • 使用Connection对象来管理事务
    • 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
      • 在执行sql之前开启事务

    • 提交事务:commit()
      • 当所有sql都执行完提交事务

    • 回滚事务:rollback()
      • 在catch中回滚事务


  • 代码:public class JDBCDemo10 {
    public static void main(String[] args) {    Connection conn = null;    PreparedStatement pstmt1 = null;    PreparedStatement pstmt2 = null;
    try {    //1.获取连接    conn = JDBCUtils.getConnection();    //开启事务    conn.setAutoCommit(false);
    //2.定义sql//2.1 张三 - 500String sql1 = "update account set balance = balance - ? where id = ?";//2.2 李四 + 500String sql2 = "update account set balance = balance + ? where id = ?";//3.获取执行sql对象pstmt1 = conn.prepareStatement(sql1);pstmt2 = conn.prepareStatement(sql2);//4. 设置参数pstmt1.setDouble(1,500);pstmt1.setInt(2,1);
    pstmt2.setDouble(1,500);pstmt2.setInt(2,2);//5.执行sqlpstmt1.executeUpdate();// 手动制造异常int i = 3/0;
    pstmt2.executeUpdate();//提交事务conn.commit();
    } catch (Exception e) {    //事务回滚    try {        if(conn != null) {            conn.rollback();        }    } catch (SQLException e1) {        e1.printStackTrace();    }    e.printStackTrace();}finally {    JDBCUtils.close(pstmt1,conn);    JDBCUtils.close(pstmt2,null);}
    }}
    }

第五天数据库线程池
  • 概念:其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
  • 好处:
    • 节约资源
    • 用户访问高效

  • 实现:
    • 标准接口:DataSource   javax.sql包下的
      • 方法:
        • 获取连接:getConnection()
        • 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接


    • 一般我们不去实现它,有数据库厂商来实现
      • C3P0:数据库连接池技术
      • Druid:数据库连接池实现技术,由阿里巴巴提供的



  • C3P0:数据库连接池技术
    • 步骤:
      • 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
        • 不要忘记导入数据库驱动jar包

      • 定义配置文件:
        • 名称: c3p0.properties 或者 c3p0-config.xml
        • 路径:直接将文件放在src目录下即可。

      • 创建核心对象 数据库连接池对象 ComboPooledDataSource
      • 获取连接: getConnection

    • 代码://1.创建数据库连接池对象   DataSource ds  = new ComboPooledDataSource();   //2. 获取连接对象   Connection conn = ds.getConnection();

  • Druid:数据库连接池实现技术,由阿里巴巴提供的
    • 步骤:
      • 导入jar包 druid-1.0.9.jar
      • 定义配置文件:
        • 是properties形式的
        • 可以叫任意名称,可以放在任意目录下

      • 加载配置文件。Properties
      • 获取数据库连接池对象:通过工厂来来获取  DruidDataSourceFactory
      • 获取连接:getConnection


    • 代码://3.加载配置文件   Properties pro = new Properties();   InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");   pro.load(is);   //4.获取连接池对象   DataSource ds = DruidDataSourceFactory.createDataSource(pro);   //5.获取连接   Connection conn = ds.getConnection();

    • 定义工具类
      • 定义一个类 JDBCUtils
      • 提供静态代码块加载配置文件,初始化连接池对象
      • 提供方法
        • 获取连接方法:通过数据库连接池获取连接
        • 释放资源
        • 获取连接池的方法




  • 代码:public class JDBCUtils {
    //1.定义成员变量 DataSourceprivate static DataSource ds ;
    static{    try {        //1.加载配置文件        Properties pro = new Properties();        pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));        //2.获取DataSource        ds = DruidDataSourceFactory.createDataSource(pro);    } catch (IOException e) {        e.printStackTrace();    } catch (Exception e) {        e.printStackTrace();    }}
    /**
    • 获取连接*/public static Connection getConnection() throws SQLException {return ds.getConnection();}

    /**
    • 释放资源*/public static void close(Statement stmt,Connection conn){   /* if(stmt != null){    try {        stmt.close();    } catch (SQLException e) {        e.printStackTrace();    }}
      if(conn != null){    try {        conn.close();//归还连接    } catch (SQLException e) {        e.printStackTrace();    }}*/

       close(null,stmt,conn);}

  public static void close(ResultSet rs , Statement stmt, Connection conn){
  if(rs != null){      try {          rs.close();      } catch (SQLException e) {          e.printStackTrace();      }  }
  if(stmt != null){      try {          stmt.close();      } catch (SQLException e) {          e.printStackTrace();      }  }
  if(conn != null){      try {          conn.close();//归还连接      } catch (SQLException e) {          e.printStackTrace();      }  }
  }
  /**
  • 获取连接池方法*/

  public static DataSource getDataSource(){      return  ds;  }
  }
Spring JDBC
  • Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
  • 步骤:
    • 导入jar包
    • 创建JdbcTemplate对象。依赖于数据源DataSource
      • JdbcTemplate template = new JdbcTemplate(ds);

    • 调用JdbcTemplate的方法来完成CRUD的操作
      • update():执行DML语句。增、删、改语句
      • queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
        • 注意:这个方法查询的结果集长度只能是1

      • queryForList():查询结果将结果集封装为list集合
        • 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中

      • query():查询结果,将结果封装为JavaBean对象
        • query的参数:RowMapper
          • 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
          • new BeanPropertyRowMapper<类型>(类型.class)


      • queryForObject:查询结果,将结果封装为对象
        • 一般用于聚合函数的查询


    • 练习:
      • 需求:
        • 修改1号数据的 salary 为 10000
        • 添加一条记录
        • 删除刚才添加的记录
        • 查询id为1的记录,将其封装为Map集合
        • 查询所有记录,将其封装为List
        • 查询所有记录,将其封装为Emp对象的List集合
        • 查询总记录数

      • 代码:
        import cn.itcast.domain.Emp;import cn.itcast.utils.JDBCUtils;import org.junit.Test;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;
        import java.sql.Date;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import java.util.Map;
        public class JdbcTemplateDemo2 {
        //Junit单元测试,可以让方法独立执行



  //1. 获取JDBCTemplate对象  private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());  /**
    • 修改1号数据的 salary 为 10000


*/   @Test   public void test1(){
  //2. 定义sql  String sql = "update emp set salary = 10000 where id = 1001";  //3. 执行sql  int count = template.update(sql);  System.out.println(count);}
  /**
    • 添加一条记录*/  @Test  public void test2(){    String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";    int count = template.update(sql, 1015, "郭靖", 10);    System.out.println(count);

    }
    /**
    • 3.删除刚才添加的记录*/@Testpublic void test3(){String sql = "delete from emp where id = ?";int count = template.update(sql, 1015);System.out.println(count);}

    /**
    • 4.查询id为1001的记录,将其封装为Map集合
    • 注意:这个方法查询的结果集长度只能是1*/@Testpublic void test4(){String sql = "select * from emp where id = ? or id = ?";Map<String, Object> map = template.queryForMap(sql, 1001,1002);System.out.println(map);//{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}

    }
    /**
      • 查询所有记录,将其封装为List*/@Testpublic void test5(){  String sql = "select * from emp";  List<Map<String, Object>> list = template.queryForList(sql);

        for (Map<String, Object> stringObjectMap : list) {      System.out.println(stringObjectMap);  }  }

    /**
      • 查询所有记录,将其封装为Emp对象的List集合*/


    @Testpublic void test6(){    String sql = "select * from emp";    List<Emp> list = template.query(sql, new RowMapper<Emp>() {
    @Overridepublic Emp mapRow(ResultSet rs, int i) throws SQLException {    Emp emp = new Emp();    int id = rs.getInt("id");    String ename = rs.getString("ename");    int job_id = rs.getInt("job_id");    int mgr = rs.getInt("mgr");    Date joindate = rs.getDate("joindate");    double salary = rs.getDouble("salary");    double bonus = rs.getDouble("bonus");    int dept_id = rs.getInt("dept_id");
    emp.setId(id);emp.setEname(ename);emp.setJob_id(job_id);emp.setMgr(mgr);emp.setJoindate(joindate);emp.setSalary(salary);emp.setBonus(bonus);emp.setDept_id(dept_id);
    return emp;
    }
    });

  for (Emp emp : list) {      System.out.println(emp);  }
  }
  /**
    • 查询所有记录,将其封装为Emp对象的List集合


*/
  @Test  public void test6_2(){      String sql = "select * from emp";      List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));      for (Emp emp : list) {          System.out.println(emp);      }  }
  /**
    • 查询总记录数*/

    @Testpublic void test7(){    String sql = "select count(id) from emp";    Long total = template.queryForObject(sql, Long.class);    System.out.println(total);}
    }





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马