• 初识JDBC


    JDBC


    • idea第一次使用过程中会出现使用时区错误,设置时区后解决问题

    • 概念:JAVA DataBase Connectivity -java 数据库连接,java语言操作数据库

    • JDBC本质:sun公司定义的一套JAVA连接各种关系型数据库的规则(接口),并没有进行实现,而是由每个数据库厂商实现了这个接口,并且提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行代码的是驱动jar包中的实现类。

    • JDBC 快速入门

      
      package cn.learn.jdbc;
      
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      public class JdbcDemo01 {
          public static void main(String[] args) {
              //1.导入厂商jar包,复制包到新建文件夹lib,再add as Library
              /*
                  mysql厂商的jar包在5版本后里的META-INF中已经注册驱动,可 以不写
                  Class.forName("com.mysql.jdbc.Driver");
              */
              Statement statement = null;
              Connection conn = null;
              try {
                  //2.注册驱动,加载进内存
                  Class.forName("com.mysql.jdbc.Driver");
                  //3.获取数据库连接对象
                  conn = DriverManager.getConnection("jdbc:mysql://   localhost:3306/db1","root","123");
                  //4.定义SQL语句,语句不加分号
                  String sql = " insert into student(id,name) values  (8,'小白白') ";
                  //5.获取执行sql的对象,Statement
                  statement = conn.createStatement();
                  //6.执行SQL
                  int count = statement.executeUpdate(sql);
                  //7.处理结果,
                  if(count == 1){
                      System.out.println("处理成功");
                  }
              } catch (SQLException | ClassNotFoundException e) {
                  e.printStackTrace();
              }finally {
                  //8.释放资源,如果在第5步之前出现异常,执行进来statement 为空,则会出现空指针异常
                  if (statement != null) {
                      try {
                          statement.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
                  if(conn != null){
                      try {
                          conn.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
      
                  }
              }
          }
      }
      
      
      

    详解JDBC中的对象

    Connection -数据库连接对象


    • java.sql 接口 Connection

    • 功能

      1. 获取执行sql的对象,其中方法:

        • Statement createStatement()
          创建一个 Statement 对象来将 SQL 语句发送到数据库
        • PreparedStatement prepareStatement(String sql)
          创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
      2. 管理事务:

        • 开启事务方法:
          void setAutoCommit(boolean autoCommit)
          将此连接的自动提交模式设置为给定状态,参数false即为手动提交,开启事务

        • 提交事务:void commit()

        • 回滚事务:void rollback()

      3. 最后资源需要关闭,以免造成内存泄漏。

    DriverManager - 驱动管理对象


    • java.sql 类 DriverManager

    • 功能:

      1. 注册驱动

        • 方法:

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

          而Class.forName("com.mysql.jdbc.Driver");
          通过查看源码,在com.mysql.jdbc.Driver类中存在静态代码块

          
          public class Driver extends NonRegisteringDriver implements java.sql.Driver {
          //
          // Register ourselves with the DriverManager
          //
          static {
              try {
                  java.sql.DriverManager.registerDriver(new Driver());
              } catch (SQLException E) {
                  throw new RuntimeException("Can't register driver!");
              }
          }
          
          
      2. 获取数据库连接:

        • 静态方法:

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

        • 参数:
          1. URL:指定连接的路径
            • 语法:
              url:jdbc:mysql://ip地址(域名):端口号/数据库名称(本机默认端口是3306可简写为///数据库名称)
              user:用户名
              password: 密码

    Statement -执行sql对象


    • public interface Statement extends Wrapper

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

    • 执行sql

      1. int executeUpdate(String sql)
        执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
        注意:返回值int是影响的行数,可由此来判断是否执行成功
      2. ResultSet executeQuery(String sql)
        执行给定的DQL语句,返回ResultSet结果集对象。
      3. 资源需要关闭
      package cn.learn.jdbc;
      
      import java.sql.*;
      
      public class JdbcDemo01 {
          public static void main(String[] args) {
              //1.导入厂商jar包,复制包到新建文件夹lib,再add as Library
              /*
                  mysql厂商的jar包在5版本后里的META-INF中已经注册驱动,可 以不写
                  Class.forName("com.mysql.jdbc.Driver");
              */
              Statement statement = null;
              Connection conn = null;
              ResultSet count = null;
              try {
                  //2.注册驱动,加载进内存
                  Class.forName("com.mysql.jdbc.Driver");
                  //3.获取数据库连接对象
                  conn = DriverManager.getConnection("jdbc:mysql:///  db1","root","123");
                  //4.定义SQL语句,语句不加分号
                  String sql = " select * from student ";
                  //5.获取执行sql的对象,Statement
                  statement = conn.createStatement();
                  //6.执行SQL
                  count = statement.executeQuery(sql);
                  //7.处理结果,打印在控制台
                  //7.1 先让光标移动一行,进入数据区域
                  while(count.next()){
                      System.out.print(count.getInt(1)+"-----");
                      System.out.print(count.getString(2)+"-----");
                      System.out.print(count.getInt(3)+"-----");
                      System.out.print(count.getDouble(4)+"-----");
                      System.out.println(count.getDate(5));
                  }
      
      
              } catch (SQLException | ClassNotFoundException e) {
                  e.printStackTrace();
              }finally {
                  //8.释放资源,如果在第5步之前出现异常,执行进来statement 为空,则会出现空指针异常
                  if (statement != null) {
                      try {
                          statement.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                  }
                  if(conn != null){
                      try {
                          conn.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
      
                  }
                  if(count != null){
                      try {
                          count.close();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
      
                  }
              }
      
          }
      }
      
      /*
      
      1-----小白-----15-----85.6-----1996-02-03
      2-----小王-----13-----88.2-----null
      3-----as-----88-----89.2-----null
      8-----小白白-----0-----0.0-----null
      9-----小白-----15-----75.6-----1996-02-03
       */
      
      

    抽取JDBC工具类 : JDBCUtils


    • 目的:简化书写
    • 分析:
      1. 注册驱动也抽取
      2. 抽取一个方法获取连接对象
        • 需求:不想传递参数(麻烦),还得保证工具类的通用性。
        • 解决:配置文件
          jdbc.properties
          url=
          user=
          password=
      3. 抽取一个方法释放资源
    • 代码实现:
    
    	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);
                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();
                }
            }
        }
    
    }
    
    • 练习:
      • 需求:
        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');
        
        1. 代码实现:
        	public class JDBCDemo9 {
        	    public static void main(String[] args) {
        	        //1.键盘录入,接受用户名和密码
        	        Scanner sc = new Scanner(System.in);
        	        System.out.println("请输入用户名:");
        	        String username = sc.nextLine();
        	        System.out.println("请输入密码:");
        	        String password = sc.nextLine();
        	        //2.调用方法
        	        boolean flag = new JDBCDemo9().login(username, password);
        	        //3.判断结果,输出不同语句
        	        if(flag){
        	            //登录成功
        	            System.out.println("登录成功!");
        	        }else{
        	            System.out.println("用户名或密码错误!");
        	        }
        	
        	
        	    }
        	
        	
        	
        	    /**
        	     * 登录方法
        	     */
        	    public boolean login(String username ,String password){
        	        if(username == null || password == null){
        	            return false;
        	        }
        	        //连接数据库判断是否登录成功
        	        Connection conn = null;
        	        prepareStatement pstmt =  null;
        	        ResultSet rs = null;
        	        //1.获取连接
        	        try {
        	            conn =  JDBCUtils.getConnection();
        	            //2.定义sql
        	            String sql = "select * from user where username = ? and password = ?";
        	            //3.获取执行sql的对象
        	            pstmt = conn.prepareStatement(sql);
                        //设置通配符传给需要的对象
                        pstmt.setString(1,username);
                        pstmt.setString(2,password);
        	            //4.执行查询,不需要传参
        	            rs = pstmt.executeQuery();
        	            //5.判断
        	           /* if(rs.next()){//如果有下一行,则返回true
        	                return true;
        	            }else{
        	                return false;
        	            }*/
        	           return rs.next();//如果有下一行,则返回true
        	
        	        } catch (SQLException e) {
        	            e.printStackTrace();
        	        }finally {
        	            JDBCUtils.close(rs,pstmt,conn);
        	        }
        	
        	
        	        return false;
        	    }
        	}
        
        

    ResulSet -结果集对象


    • public interface ResultSet extends Wrapper
    • ResultSet:用来封装查询的结果集(表),内有以下方法获取查询结果的数据
      1. next(): 游标向下移动一行
      2. getXXX(参数):获取数据
        • XXX:为数据类型,如int,String...
        • 参数:
          1. 接收是Int型:代表列编号,从1开始
          2. 接收是String型:代表列名称
      3. 结果集是一个资源,需要关闭

    PreparedStatemnet -动态传参


    • PreparedStatement:执行sql的对象
      1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题,如下:
        1. 输入用户随便,输入密码:a' or 'a' = 'a
        2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
      2. 解决sql注入问题:使用PreparedStatement对象来解决
      3. 预编译的SQL:参数使用?作为占位符
      4. 步骤:
        1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
        2. 注册驱动
        3. 获取数据库连接对象 Connection
        4. 定义sql
          • 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
        5. 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
        6. 给?赋值:
          • 方法: setXxx(参数1,参数2)
            • 参数1:?的位置,编号 从1 开始
            • 参数2:?的值
        7. 执行sql,接受返回结果,不需要传递sql语句
        8. 处理结果
        9. 释放资源
      5. 后期都会使用PreparedStatement来完成增删改查的所有操作
        1. 可以防止SQL注入
        2. 效率更高

    JDBC控制事务:


    1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理则这多个步骤要么同时成功,要么同时失败。
    2. 操作:
      1. 开启事务
      2. 提交事务
      3. 回滚事务
    3. 使用Connection对象来管理事务
      • 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
        • 在执行sql之前开启事务
      • 提交事务:commit()
        • 当所有sql都执行完提交事务
      • 回滚事务:rollback()
        • 在catch中回滚事务
    4. 代码:
    
    	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 张三 - 500
    	            String sql1 = "update account set balance = balance - ? where id = ?";
    	            //2.2 李四 + 500
    	            String 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.执行sql
    	            pstmt1.executeUpdate();
    	            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);
    	        }
    	
    	
    	    }
    	
    	}
    
    

    JDBC实验

    • Java实验四 JDBC
      使用SQL Server数据库或者MySQL数据库各自的客户端工具,完成如下任务:
      1. 创建数据库students;
      2. 在数据students中创建表scores,包括如下字段:学号、姓名、性别、得分,字段类型自行定义。学号为主键。
    • 接着使用JDBC编写Java程序,完成如下任务:
      1. 在表格scores插入5条记录,代表5个学生,三位男生二位女生,各字段内容自定(“得分”字段填入自定分数);
      2. 显示5位学生的所有信息;
      3. 将三位男生的得分减去5分,将两位女生的成绩加上3分;
      4. 从键盘输入不同学号,根据学号显示相应学生的所有信息。

    sql语句

    CREATE DATABASE students;
    
    CREATE TABLE scores(
    id INT PRIMARY KEY,
    NAME VARCHAR(32) NOT NULL,
    sex VARCHAR(1),
    score DOUBLE(5,2)
    
    );
    
    INSERT INTO scores VALUES(201826501,'老王','男',88.2),(201826502,'老胡','男',99.3),(201826503,'老薛','男',100),(201826504,'老巴','女',89.3),(201826505,'老谢','女',95.6);
    UPDATE scores SET score = score-5 WHERE sex='男';
    SELECT * FROM scores WHERE id = 201826501;
    
    

    main方法


    
    package cn.work.demo.Jdbc;
    
    import java.sql.*;
    
    public class JdbcDemo01 {
        public static void main(String[] args)  {
            //导入厂商jar包,复制包到新建文件夹lib,再add as Library
            /*
                mysql厂商的jar包在5版本后里的META-INF中已经注册驱动,可以不写
                Class.forName("com.mysql.jdbc.Driver");
            */
            Connection conn = null;
    
            //获取数据库连接对象
            try {
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/students", "root", "123");
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
            //查询全部
            Query query = new Query(conn);
    
            //修改分数
            UpdateScores update = new UpdateScores(conn);
    
            //查询单一人员信息
            QueryOne onePerson = new QueryOne(conn);
    
            //主菜单
            Menu menu = new Menu(query,update,onePerson);
    
            //关闭连接
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
        }
    }
    
    

    主界面


    package cn.work.demo.Jdbc;
    
    import java.util.Scanner;
    
    public class Menu {
       private boolean flag = true;
       private Scanner scanner =null;
        public Menu(Query query, UpdateScores update, QueryOne onePerson) {
            System.out.println("
    
    			JDBC实验
    
    ");
            System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" );
            System.out.println("				1.查询全部人员信息
    ");
            System.out.println("				2.修改分数男生-5女生+3
    ");
            System.out.println("				3.查询某人信息
    ");
            System.out.println("				4.退出
    ");
            System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" );
            scanner = new Scanner(System.in);
            //菜单
            do{
                System.out.println("请输入要选择的数字:");
               int command = scanner.nextInt();
               switch (command){
                   case 1:
                       query.execute();
                       break;
                   case 2:
                       update.execute();
                       break;
                   case 3:
                       onePerson.execute();
                       break;
                   case 4:
                       flag=false;
                       break;
                   default:
                       System.out.println("输入错误请重新输入");
                       break;
               }
    
            }while (flag);
        }
    }
    
    

    查询全部信息并打印在控制台


    package cn.work.demo.Jdbc;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class Query {
    
        private Statement statement=null;
        private Connection conn;
        private ResultSet count=null;
    
        public Query( Connection conn) {
            this.conn = conn;
        }
    
        public void execute() {
            try {
                //定义查询SQL语句,语句不加分号
                String sql = " select * from scores ";
                //获取执行sql的对象,Connection里的方法返回Statement
                statement = conn.createStatement();
                //执行SQL,返回ResultSet
                count = statement.executeQuery(sql);
                //处理结果,打印在控制台
                //先让光标移动一行,进入数据区域进行打印输出
                while (count.next()) {
                    System.out.print(count.getInt(1) + "-----");
                    System.out.print(count.getString(2) + "-----");
                    System.out.print(count.getString(3) + "-----");
                    System.out.println(count.getDouble(4));
                }
    
    
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (count != null) {
                    try {
                        count.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    }
    
    

    修改表中数据


    package cn.work.demo.Jdbc;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class UpdateScores {
        private Statement statement=null;
        private Connection conn;
    
        public UpdateScores(Connection conn) {
            this.conn = conn;
        }
        public void execute() {
            try {
                //定义查询SQL语句
                String sqlMen = "UPDATE scores SET score = score-5 WHERE sex='男'";
                String sqlWonmen = "UPDATE scores SET score = score+3 WHERE sex='女'";
                //创建一个 Statement 对象来将 SQL 语句发送到数据库
                statement = conn.createStatement();
                //执行SQL
                statement.executeUpdate(sqlMen);
                statement.executeUpdate(sqlWonmen);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    

    prepareStatement动态查询


    package cn.work.demo.Jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Scanner;
    
    public class QueryOne {
        //PreparedStatement动态参数
        private PreparedStatement pstatement=null;
        private Connection conn;
        private ResultSet count=null;
        private Scanner scanner;
    
        public QueryOne(Connection conn) {
            scanner = new Scanner(System.in);
            this.conn = conn;
        }
        public void execute() {
            try {
                System.out.println("请输入要查询学号:");
                int id = Integer.parseInt(scanner.next());
                String sql = "SELECT * FROM scores WHERE id = ?";
                //获取SQL执行的对象
                pstatement = conn.prepareStatement(sql);
                //传递动态参数
                pstatement.setInt(1,id);
                //执行SQL
                count = pstatement.executeQuery();
                if (count.next()){
                    System.out.print(count.getInt(1) + "-----");
                    System.out.print(count.getString(2) + "-----");
                    System.out.print(count.getString(3) + "-----");
                    System.out.println(count.getDouble(4));
                } else
                    System.out.println("学号未找到!!!");
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if (pstatement != null) {
                    try {
                        pstatement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    

    数据库连接池


    1. 概念:其实就是一个容器(集合),存放数据库连接的容器。
      当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

    2. 好处:

      1. 节约资源
      2. 用户访问高效
    3. 实现:

      1. 标准接口:DataSource javax.sql包下的
        1. 方法:
          • 获取连接:getConnection()
          • 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
      2. 一般我们不去实现它,有数据库厂商来实现
        1. C3P0:数据库连接池技术
        2. Druid:数据库连接池实现技术,由阿里巴巴提供的
    4. C3P0:数据库连接池技术

      • 步骤:
        1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
          • 不要忘记导入数据库驱动jar包
        2. 定义配置文件:
          • 名称: c3p0.properties 或者 c3p0-config.xml
          • 路径:直接将文件放在src目录下即可。
        3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
        4. 获取连接: getConnection
      • 代码:
      	 //1.创建数据库连接池对象,不传参数则使用默认配置
          DataSource ds  = new ComboPooledDataSource();
          //2. 获取连接对象
          Connection conn = ds.getConnection();
      
    5. Druid:数据库连接池实现技术,由阿里巴巴提供的

      1. 步骤:
        1. 导入jar包 druid-1.0.9.jar
        2. 定义配置文件:
          • 是properties形式的
          • 可以叫任意名称,可以放在任意目录下
        3. 加载配置文件。Properties
        4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
        5. 获取连接: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();
      
      
      1. 定义工具类
        1. 定义一个类 JDBCUtils
        2. 提供静态代码块加载配置文件,初始化连接池对象
        3. 提供方法
          1. 获取连接方法:通过数据库连接池获取连接
          2. 释放资源
          3. 获取连接池的方法
      • 代码:
      
      	public class JDBCUtils {
      	    //1.定义成员变量 DataSource
      	    private 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的开发

    • 步骤:

      1. 导入jar包
      2. 创建JdbcTemplate对象。依赖于数据源DataSource
        • JdbcTemplate template = new JdbcTemplate(ds);
      3. 调用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:查询结果,将结果封装为对象
          • 一般用于聚合函数的查询
      4. 练习:
        • 需求:

          1. 修改1号数据的 salary 为 10000
          2. 添加一条记录
          3. 删除刚才添加的记录
          4. 查询id为1的记录,将其封装为Map集合
          5. 查询所有记录,将其封装为List
          6. 查询所有记录,将其封装为Emp对象的List集合
          7. 查询总记录数
        • 代码:

          
          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. 修改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);
              }
          
              /**
               * 2. 添加一条记录
               */
              @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.删除刚才添加的记录
               */
              @Test
              public void test3(){
                  String sql = "delete from emp where id = ?";
                  int count = template.update(sql, 1015);
                  System.out.println(count);
              }
          
              /**
               * 4.查询id为1001的记录,将其封装为Map集合
               * 注意:这个方法查询的结果集长度只能是1
               */
              @Test
              public 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}
          
              }
          
              /**
               * 5. 查询所有记录,将其封装为List
               */
              @Test
              public 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);
                  }
              }
          
              /**
               * 6. 查询所有记录,将其封装为Emp对象的List集合
               */
          
              @Test
              public void test6(){
                  String sql = "select * from emp";
                  List<Emp> list = template.query(sql, new RowMapper<Emp>() {
          
                      @Override
                      public 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);
                  }
              }
          
              /**
               * 6. 查询所有记录,将其封装为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);
                  }
              }
          
              /**
               * 7. 查询总记录数
               */
          
              @Test
              public void test7(){
                  String sql = "select count(id) from emp";
                  Long total = template.queryForObject(sql, Long.class);
                  System.out.println(total);
              }
          
          }
          
          
  • 相关阅读:
    老树新芽,在ES6下使用Express
    Swift3翻天覆地的改变
    NodeJs回调操作Promise化
    Node的关系型数据库ORM库:bookshelf
    基于Node的PetShop,RESTful API以及认证
    基于Node的PetShop,oauth2认证RESTful API
    Mongoose轻松搞定MongoDB,不要回调!
    Thymeleaf常用语法:表达式语法之运算符
    Thymeleaf对象的使用:日期对象
    Thymeleaf对象的使用:字符串对象
  • 原文地址:https://www.cnblogs.com/huxiaobai/p/11871425.html
Copyright © 2020-2023  润新知