JAVA网络爬虫
HttpClient

导航

 

JDBC

  1. 概念: Java DataBase Connerctivity Java 数据库连接, Java语言操作数据库

    JDBC本质: 启示是官方(sun公司)定义的一套操作所有关系型数据库的规则, 即接口. 各个数据库厂商去实现这套接口, 提供数据库驱动jar包. 我们可以使用这套接口(JDBC)编程, 真正执行的代码是驱动jar包中的实现类
    
  2. JDBC操作步骤

    * 步骤:
    		0. 去官网下载对应版本的数据库jar包
    		1. 导入驱动jar包: mysql-connector-java-8.0.16.jar
    				1. 复制mysql-connector-java-8.0.16.jar到项目的libs目录下
    				2. 右键libs目录-->Add as Library
    				
    		2. 注册驱动
    				1. 老版本:
    						Class.forName("com.mysql.jdbc.Driver");
    				2. 新版本:
    						Class.forName("com.mysql.cj.jdbc.Driver");
    		3. 获取数据库连接对象 Connection
    				Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
    		4. 定义sql
    				String sql = "update account set balance = 1000 where id = 2";
    		5. 获取执行sql语句的对象 Statement
    				Statement stmt = conn.createStatement();
    		6. 执行sql, 接受返回结果
    				int count = stmt.executeUpdate(sql);
    		7. 处理结果
    				System.out.println(count);
    		8. 释放资源
    				stmt.close();
           			conn.close();
    
    * 代码实现:
    	package cn.xiaoge.jdbc;
    
        import javax.swing.plaf.nimbus.State;
        import java.sql.Connection;
        import java.sql.DriverManager;
        import java.sql.SQLException;
        import java.sql.Statement;
    
        /**
         *  JDBC 快速入门
         */
    
        public class JdbcDemo1 {
    
            public static void main(String[] args) throws Exception {
                // 1. 导入数据库驱动jar包
    
    
                // 2. 注册驱动
                Class.forName("com.mysql.cj.jdbc.Driver"); // 把com.mysql.jdbc.Driver加载进内存
    
                // 3. 获取数据库连接对象Connection
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
    
                // 4. 定义sql
                String sql = "update account set balance = 1000 where id = 2";
    
                // 5. 获取执行sql语句的对象, Statement
                Statement stmt = conn.createStatement();
    
                // 6. 执行sql, 接受返回结果
                int count = stmt.executeUpdate(sql);
    
                // 7. 处理结果
                System.out.println(count);
    
                // 8. 释放资源
                stmt.close();
                conn.close();
            }
    
        }
    
  3. 详解各个对象

    1. DriverManager: 驱动管理对象
    		* 功能:
    				1. 注册驱动: 告诉程序该使用那一个数据库驱动jar
    						static void registerDriver(Driver driver): 注册与给定的驱动程序 DriverManager
    						写代码使用: Class.forName("com.mysql.cj.jdbc.Driver");
    						com.mysql.cj.jdbc.Driver--->Driver类源码中的静态代码块:
    								static {
     			                       try {
     			                           DriverManager.registerDriver(new Driver());
     			                       } catch (SQLException var1) {
     			                           throw new RuntimeException("Can't register driver!");
     			                       }
     			                   }
    						注意: mysql5之后的驱动jar包可以省略注册驱动的步骤.
            
                  
     	           2. 获取数据库连接:
     	   			* 方法: static Connection getConnection(String url, String user, String password)
     	               * 参数:
     						* url: 指定链接的路径
     								* 语法: jdbc:mysql://ip地址(域名):port(端口号)/数据库名称
     								* 例子: jdbc:mysql://localhost:3306/test3"
     								* 细节: 如果链接的是本机mysql服务器, 并且mysql服务默认端口是3306, 则url可以简写为: jdbc:mysql:///数据库名称
     						* user: 用户名
     						* password: 密码
    2. Connection: 数据库连接对象
    		1. 功能:
    			1. 获取执行sql的对象
    				* Statement createStatement()
                	* PreparedStatement prepareStatement(String sql)
               
              	2. 管理实事务:
     				* 开启事务:void setAutoCommit(boolean autoCommit): 调用该方法设置参数为false, 即开启事务
     				* 提交事务: void commit()
     				* 回滚事务: void rollback()
    
    3. Statement: 执行sql的对象
    	1. 执行sql
    		1. boolean execute(String sql): 可以执行任意的sql (了解)
      
    		2. int executeUpdate(String sql): 执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
    			* 返回值: 影响的行数、可以通过这个影响的行数判断DML语句是否成功 返回值>0的则执行成功, 反之, 则失败.
                  
            3. ResultSet executeQuery(String sql): 执行DQL(select)语句
            		
        2. 案列:
    		1. account表  添加一条记录
    			package cn.xiaoge.jdbc;
    
                import java.sql.Connection;
                import java.sql.DriverManager;
                import java.sql.SQLException;
                import java.sql.Statement;
    
                /**
                 *  account表  添加一条记录 insert 语句
                 */
    
                public class JdbcDemo2 {
    
                    public static void main(String[] args) {
    
                        Connection conn = null;
                        Statement statement = null;
    
                        try{
                            // 1. 注册驱动
                            Class.forName("com.mysql.cj.jdbc.Driver");
    
                            // 2. 获取connection对象
                            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
    
                            // 3. 定义sql
                            String sql = "insert into account values(null, 'zhangsan', 1000)";
    
                            // 4. 获取执行sql对象
                            statement = conn.createStatement();
    
                            // 5. 执行sql
                            int count = statement.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{
                            // statement.close();
    
                            // 7. 释放资源
                            // 避免空指针异常
                            if (statement != null) {
                                try {
                                    statement.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
    
                            if (conn != null) {
                                try {
                                    conn.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
    
                }
    
    		2. account表  修改一条记录
    			package cn.xiaoge.jdbc;
    
                import java.sql.Connection;
                import java.sql.DriverManager;
                import java.sql.SQLException;
                import java.sql.Statement;
    
                /**
                 *  account表  修改一条记录 update 语句
                 */
    
                public class JdbcDemo3 {
    
                    public static void main(String[] args) {
    
                        Connection conn = null;
                        Statement statement = null;
    
                        try {
                            // 1. 注册数据库驱动
                            Class.forName("com.mysql.cj.jdbc.Driver");
    
                            // 2. 获取connection对象
                            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
    
                            // 3. 获取执行sql语句对象
                            statement = conn.createStatement();
    
                            // 4. 定义sql
                            String sql = "update account set balance = 1500 where id = 3";
    
                            // 5. 执行sql
                            int count = statement.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 {
                            // 避免空指针异常
                            if (statement != null) {
                                try {
                                    statement.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
    
                            if (conn != null) {
                                try {
                                    conn.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
    
                }
    
    				
    		3. account表  删除一条记录
    			package cn.xiaoge.jdbc;
    
                import java.sql.Connection;
                import java.sql.DriverManager;
                import java.sql.SQLException;
                import java.sql.Statement;
    
                /**
                 * account表 删除一条记录
                 */
    
                public class JdbcDemo4 {
    
                    public static void main(String[] args) {
    
                        Connection conn = null;
                        Statement statement = null;
    
                        try {
                            // 1. 注册数据库驱动
                            Class.forName("com.mysql.cj.jdbc.Driver");
    
                            // 2. 获取connection对象
                            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
    
                            // 3. 获取执行sql语句对象
                            statement = conn.createStatement();
    
                            // 4. 定义sql
                            String sql = "delete from account where id = 3";
    
                            // 5. 执行sql
                            int count = statement.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 {
                            // 避免空指针异常
                            if (statement != null) {
                                try {
                                    statement.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
    
                            if (conn != null) {
                                try {
                                    conn.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
    
                }
    
    				
    		4. 创建student表
    			package cn.xiaoge.jdbc;
    
                import java.sql.Connection;
                import java.sql.DriverManager;
                import java.sql.SQLException;
                import java.sql.Statement;
    
                /**
                 *  创建表, DDL操作executeUpdate  返回0
                 */
    
                public class JdbcDemo5 {
                    public static void main(String[] args) {
    
                        Connection conn = null;
                        Statement statement = null;
    
                        try {
                            // 1. 注册数据库驱动
                            Class.forName("com.mysql.cj.jdbc.Driver");
    
                            // 2. 获取connection对象
                            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
    
                            // 3. 获取执行sql语句对象
                            statement = conn.createStatement();
    
                            // 4. 定义sql
                            String sql = "create table student(id int, name varchar(20))";
    
                            // 5. 执行sql
                            int count = statement.executeUpdate(sql);
    
                            // 6. 处理结果
                            System.out.println(count);
    
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        } finally {
                            // 避免空指针异常
                            if (statement != null) {
                                try {
                                    statement.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
    
                            if (conn != null) {
                                try {
                                    conn.close();
                                } catch (SQLException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
    
    				
    4. ResultSet: 结果集对象, 封装查询结果
    		* boolean next(): 游标向下移动一行, 判断当前行是否是最后一行末尾(是否有数据), 如果是, 则返回false, 如果不是则返回true
    		* getXxx(参数): 获取数据
    				* Xxx: 代表数据类型		如: int getInt(), String getString()
            * 参数: 
    			1. int: 代表列的编号,1开始	如: getString(1)
                2. String: 代表列名称.: getDouble("balance");
    
    		* 注意:
     			使用步骤:				          	              
     			      1. 游标向下移动一行
     				  2. 判断是否有数据
     				  3. 获取数据
     				
     			案例:
     				  package cn.xiaoge.jdbc;
    
                      import java.sql.*;
        
                      /**
                       *  遍历结果集
                       */
        
                      public class JdbcDemo7 {
                          public static void main(String[] args) {
        
                              Connection conn = null;
                              Statement statement = null;
                              ResultSet resultSet = null;
        
                              try {
                                  // 1. 注册数据库驱动
                                  Class.forName("com.mysql.cj.jdbc.Driver");
        
                                  // 2. 获取connection对象
                                  conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "123456");
        
                                  // 3. 获取执行sql语句对象
                                  statement = conn.createStatement();
        
                                  // 4. 定义sql
                                  String sql = "select * from account";
        
                                  // 5. 执行sql
                                  resultSet = statement.executeQuery(sql);
        
                                  // 6. 处理结果
                                  // 循环判断游标是否是最后一行默认, true还没到最后一行末尾, false到了最后一行末尾
                                  while (resultSet.next()) {
                                      // 获取数据
                                      int id = resultSet.getInt(1);
                                      String name = resultSet.getString("name");
                                      double balance = resultSet.getDouble(3);
                                      System.out.println("id: " + id + " name: " + name + " balance: " + 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 (conn != null) {
                                      try {
                                          conn.close();
                                      } catch (SQLException e) {
                                          e.printStackTrace();
                                      }
                                  }
                              }
                          }
                      }
    
    		* 案列:
    			* 定义一个方法, 查询emp表的数据将其封装为对象, 然后装在集合, 返回.
              	1. 定义Emp类--->根据数据库表emp的字段一一对应着定义属性
              	   package cn.xiaoge.domain;
    
                  import java.util.Date;
    
                  /**
                *  封装Emp表数据的JavaBean
                   */
    
                  public class Emp {
    
                      private int id;
                      private String ename;
                      private int job_id;
                      private int mgr;
                      private Date joindate;
                      private double salary;
                      private double bonus;
                      private int dept_id;
    
                      public int getId() {
                          return id;
                      }
    
                      public void setId(int id) {
                          this.id = id;
                      }
    
                      public String getEname() {
                          return ename;
                      }
    
                      public void setEname(String ename) {
                          this.ename = ename;
                      }
    
                      public int getJob_id() {
                          return job_id;
                      }
    
                      public void setJob_id(int job_id) {
                          this.job_id = job_id;
                      }
    
                      public int getMgr() {
                          return mgr;
                      }
    
                      public void setMgr(int mgr) {
                          this.mgr = mgr;
                      }
    
                      public Date getJoindate() {
                          return joindate;
                      }
    
                      public void setJoindate(Date joindate) {
                          this.joindate = joindate;
                      }
    
                      public double getSalary() {
                          return salary;
                      }
    
                      public void setSalary(double salary) {
                          this.salary = salary;
                      }
    
                      public double getBonus() {
                          return bonus;
                      }
    
                      public void setBonus(double bonus) {
                          this.bonus = bonus;
                      }
    
                      public int getDept_id() {
                          return dept_id;
                      }
    
                      public void setDept_id(int dept_id) {
                          this.dept_id = dept_id;
                      }
    
                      @Override
                      public String toString() {
                          return "Emp{" +
                                  "id=" + id +
                                  ", ename='" + ename + '\'' +
                                  ", job_id=" + job_id +
                                  ", mgr=" + mgr +
                                  ", joindate=" + joindate +
                                  ", salary=" + salary +
                                  ", bonus=" + bonus +
                                  ", dept_id=" + dept_id +
                                  '}';
                      }
                  }
    
              	2. 定义方法 public List<Emp> findAll(){}
    			  package cn.xiaoge.jdbc;
    
                  import cn.xiaoge.domain.Emp;
                  import jdk.management.resource.internal.inst.FileOutputStreamRMHooks;
    
                  import java.sql.*;
                  import java.util.ArrayList;
                  import java.util.Collections;
                  import java.util.List;
    
                  /**
                   *  定义一个方法, 查询emp表数据将其封装成对象, 然后装在集合, 返回.
                   */
    
                  public class JdbcDemo8 {
    
                      public static void main(String[] args) {
                          // 因为findAll不是静态方法, 所以要用对象调用
                          List<Emp> list = new JdbcDemo8().findAll();
                          System.out.println(list);
                          System.out.println(list.size());
                      }
    
                      /**
                       *  查询所偶遇emp对象
                       *
                       *  @return
                       */
    
                      public List<Emp> findAll(){
    
                          Connection con = null;
                          Statement s = null;
                          ResultSet resultSet = null;
                          List<Emp> list = null;
                          try {
                              // 1. 注册驱动
                              Class.forName("com.mysql.cj.jdbc.Driver");
    
                              // 2. 链接数据库
                              con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test2", "root", "123456");
    
                              // 3. 获取执行sql语句的对象
                              s = con.createStatement();
    
                              // 4. 定义sql
                              String sql = "select * from emp";
    
                              // 5. 执行sql, 返回结果集
                              resultSet = s.executeQuery(sql);
    
                              // 6. 创建集合
                              list = new ArrayList<>();
    
                              // 这样是让他, 不要创建多个引用, 来浪费内存
                              Emp emp = null;
    
                              // 7. 遍历结果集, 封装对象, 装在集合
                              while(resultSet.next()) {
                                  // 获取数据
                                  int id = resultSet.getInt("id");
                                  String ename = resultSet.getString("ename");
                                  int job_id = resultSet.getInt("job_id");
                                  int mgr = resultSet.getInt("mgr");
                                  Date joindate = resultSet.getDate("joindate");
                                  double salary = resultSet.getDouble("salary");
                                  double bonus = resultSet.getDouble("bonus");
                                  int dept_id = resultSet.getInt("dept_id");
    
                                  // 创建emp对象, 并赋值
                                  emp = new Emp();
                                  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);
    
                                  // 装在集合
                                  list.add(emp);
                              }
    
                          } catch (ClassNotFoundException e) {
                              e.printStackTrace();
                          } catch (SQLException e) {
                              e.printStackTrace();
                          } finally {
                              if (resultSet != null) {
                                  try {
                                      resultSet.close();
                                  } catch (SQLException e) {
                                      e.printStackTrace();
                                  }
                              }
    
                              if (s != null) {
                                  try {
                                      s.close();
                                  } catch (SQLException e) {
                                      e.printStackTrace();
                                  }
                              }
    
                              if (con != null) {
                                  try {
                                      con.close();
                                  } catch (SQLException e) {
                                      e.printStackTrace();
                                  }
                              }
                          }
    
                          return list;
                      }
    
                  }
    
              	3. 实现方法: select * from emp;
    
    5. PreparedStatement: 执行sql的对象
    		1. SQL注入问题: 在拼接sql时, 有一些sql的特殊关键字参与字符串的拼接. 会造成安全性问题
    				1. 输入用户随便, 输入密码: 'a' or 'a' = 'a
            		2. sql: select * from user where username = 'adwaf' and password = 'a' or 'a' = 'a' 
            2. 解决sql注入问题: 使用PreparedStatement对象来解决
            3. 预编译的SQL: 参数使用?作为占位符
            4. 步骤:
    			   0. 去官网下载对应版本的数据库jar包
     	           1. 导入驱动jar包: mysql-connector-java-8.0.16.jar
     	           2. 注册驱动
     	           3. 获取数据库连接对象 Connection
     	           4. 定义sql
     	               * 注意: sql的参数使用?作为占位符.: select * from user where username = ? and password = ?; 
     	           5. 获取执行sql语句的对象 PreparedStatement Connection.preparedStatement(String sql)
     	           6.?去赋值:		   					
     	   					* 方法: setXxx(参数1, 参数2)
     	                 	* 参数1: ?的位置编号 从1 开始
     	                 	* 参数2: ?的值
     	           7. 执行sql, 接受返回结果, 不需要传递sql语句
     	           8. 处理结果
     	           9. 释放资源
        5. 注意: 后期都会使用PreparedStatement来完成增删改查的所有操作
        		1. 可以防止SQL注入
        		2. 效率更高
        
        6. 代码:
     		1. 差UN个以按数据库表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. 配置文件jdbc.properties:
     			  url = jdbc:mysql://localhost:3306/test2
                  user = root
                  password = 123456
                  driver = com.mysql.cj.jdbc.Driver
    
     		3. JDBCUtils:
     		  	  package cn.xiaoge.util;
    
                  import java.io.*;
                  import java.net.URL;
                  import java.sql.*;
                  import java.util.Properties;
    
                  /**
                   *  JDBC 工具类  (工具类里面都是静态方法 列 Arrays工具类)
                   */
    
                  public class JDBCUtils {
    
                      // 只有静态的变量, 才能被静态代码块访问, 才能被静态方法所访问
                      private static String url;
                      private static String user;
                      private static String password;
                      private static String driver;
    
                      /**
                       *  文件的读取, 只需要读取一次即可拿到这些值, 使用静态代码块
                       */
                      static{
    
                          try {
                              // 读取资源文件, 获取值
                              // 1. 创建Properties集合类.
                              Properties prop = new Properties();
    
                              // 获取src路径下的文件的方式--->ClassLoader 类加载器 (以src作为跟目录)
                              ClassLoader classLoader = JDBCUtils.class.getClassLoader();
                              URL reSource = classLoader.getResource("jdbc.properties");
                              // 获取文件路径
                              String path = reSource.getPath();
                              // System.out.println(path);
    
                              // 2. 加载文件
                              prop.load(new FileReader(path));
    
                              // 3. 获取属性赋值
                              url = prop.getProperty("url");
                              user = prop.getProperty("user");
                              password = prop.getProperty("password");
                              driver = prop.getProperty("driver");
    
                              // 4. 注册驱动
                              Class.forName(driver);
    
                          } catch (IOException e) {
                              e.printStackTrace();
                          } catch (ClassNotFoundException e) {
                              e.printStackTrace();
                          }
    
    
                      }
    
                      /**
                       * 获取链接
                       * @return 链接对象
                       */
                      public static Connection getConnection(){
                          Connection conn = null;
                          try {
                              conn = DriverManager.getConnection(url, user, password);
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }
    
                          return conn;
                      }
    
                      /**
                       * 释放资源
                       * @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 res
                       * @param stmt
                       * @param conn
                       */
                      public static void close(ResultSet res, Statement stmt, Connection conn) {
                          if (res != null) {
                              try {
                                  res.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();
                              }
                          }
                      }
    
                  }
     	   4. 主类:
     				package cn.xiaoge.jdbc;
    
                    import cn.xiaoge.util.JDBCUtils;
    
                    import java.sql.*;
                    import java.util.Scanner;
    
                    /**
                     *  1. 通过键盘录入用户名和密码
                     *  2. 判断用户是否登录成功
                     */
    
                    public class JdbcDemo11 {
    
                        public static void main(String[] args) {
                            // 获取用户输入的用户名和密码
                            Scanner sc = new Scanner(System.in);
                            System.out.print("请输入用户名: ");
                            String username = sc.next();
                            System.out.print("请输入密码: ");
                            String password = sc.next();
    
                            // 调用方法
                            boolean flag = new JdbcDemo11().login(username, password);
    
                            // 判断
                            if (flag) {
                                System.out.println("登入成功!");
                            } else {
                                System.out.println("用户名或密码错误!");
                            }
                        }
    
                        /**
                         * 登入方法
                         * @param username
                         * @param password
                         * @return
                         */
                        public boolean login(String username, String password) {
                            if (username == null || password == null) {
                                return false;
                            }
    
                            // 链接数据库判断是否登入成功
                            Connection conn = null;
                            PreparedStatement pstmt = null;
                            ResultSet res = null;
    
                            // 1. 获取链接
                            try {
                                conn = JDBCUtils.getConnection();
    
                                // 2. 定义sql
                                String sql = "select * from user where username = ? and password = ?";
    
                                // 3. 获取执行sql的对象
                                pstmt = conn.prepareStatement(sql);
    
                                // 4. 给?赋值
                                pstmt.setString(1, username);
                                pstmt.setString(2, password);
    
                                // 5. 执行查询, 不需要传递sql
                                res = pstmt.executeQuery();
    
                                // 6. 判断
                                return res.next();// 如果有下一行, 则返回false
    
                            } catch (SQLException e) {
                                e.printStackTrace();
                            } finally {
                                JDBCUtils.close(res, pstmt, conn);
                            }
    
                            return false;
                        }
    
                    }
    
                
    

    抽取JDBC工具类: JDBCUtils

    * 目的: 简化书写
    * 分析:
    	1. 注册驱动也抽取
        2. 抽取一个方法链接对象
          * 需求: 不想传递参数(麻烦), 还得保证工具的通用性.
          * 解决: 配置文件
          		jdbc.properties
          				url = 
            			user = 
            			password = 
        3. 抽取一个方法释放资源
     * 代码实现
     	 * 配置文件: 
     		  url = jdbc:mysql://localhost:3306/test2
              user = root
              password = 123456
              driver = com.mysql.cj.jdbc.Driver
              
         * 工具类:
        	  package cn.xiaoge.util;
    
              import java.io.*;
              import java.net.URL;
              import java.sql.*;
              import java.util.Properties;
    
              /**
               *  JDBC 工具类  (工具类里面都是静态方法 列 Arrays工具类)
               */
    
              public class JDBCUtils {
    
                  // 只有静态的变量, 才能被静态代码块访问, 才能被静态方法所访问
                  private static String url;
                  private static String user;
                  private static String password;
                  private static String driver;
    
                  /**
                   *  文件的读取, 只需要读取一次即可拿到这些值, 使用静态代码块
                   */
                  static{
    
                      try {
                          // 读取资源文件, 获取值
                          // 1. 创建Properties集合类.
                          Properties prop = new Properties();
    
                          // 获取src路径下的文件的方式--->ClassLoader 类加载器 (以src作为跟目录)
                          ClassLoader classLoader = JDBCUtils.class.getClassLoader();
                          URL reSource = classLoader.getResource("jdbc.properties");
                          // 获取文件路径
                          String path = reSource.getPath();
                          System.out.println(path);
    
                          // 2. 加载文件
                          prop.load(new FileReader(path));
    
                          // 3. 获取属性赋值
                          url = prop.getProperty("url");
                          user = prop.getProperty("user");
                          password = prop.getProperty("password");
                          driver = prop.getProperty("driver");
    
                          // 4. 注册驱动
                          Class.forName(driver);
    
                      } catch (IOException e) {
                          e.printStackTrace();
                      } catch (ClassNotFoundException e) {
                          e.printStackTrace();
                      }
    
    
                  }
    
                  /**
                   * 获取链接
                   * @return 链接对象
                   */
                  public static Connection getConnection(){
                      Connection conn = null;
                      try {
                          conn = DriverManager.getConnection(url, user, password);
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
    
                      return conn;
                  }
    
                  /**
                   * 释放资源
                   * @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 res
                   * @param stmt
                   * @param conn
                   */
                  public static void close(ResultSet res, Statement stmt, Connection conn) {
                      if (res != null) {
                          try {
                              res.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();
                          }
                      }
                  }
    
              }
    
    		 * 主类: 
         		  package cn.xiaoge.jdbc;
    
                  import cn.xiaoge.domain.Emp;
                  import cn.xiaoge.util.JDBCUtils;
        
                  import java.sql.*;
                  import java.util.ArrayList;
                  import java.util.List;
        
                  /**
                   *  定义一个方法, 查询emp表数据将其封装成对象, 然后装在集合, 返回.
                   */
        
                  public class JdbcDemo9 {
        
                      public static void main(String[] args) {
                          // 因为findAll不是静态方法, 所以要用对象调用
                          List<Emp> list = new JdbcDemo9().findAll();
                          System.out.println(list);
                          System.out.println(list.size());
                      }
        
                      /**
                       *  演示JDBC工具类
                       *
                       *  @return
                       */
        
                      public List<Emp> findAll(){
        
                          Connection con = null;
                          Statement s = null;
                          ResultSet resultSet = null;
                          List<Emp> list = null;
                          try {
                              // 1. 注册驱动
                              // 2. 链接数据库
                              con = JDBCUtils.getConnection();
        
                              // 3. 获取执行sql语句的对象
                              s = con.createStatement();
        
                              // 4. 定义sql
                              String sql = "select * from emp";
        
                              // 5. 执行sql, 返回结果集
                              resultSet = s.executeQuery(sql);
        
                              // 6. 创建集合
                              list = new ArrayList<>();
        
                              // 这样是让他, 不要创建多个引用, 来浪费内存
                              Emp emp = null;
        
                              // 7. 遍历结果集, 封装对象, 装在集合
                              while(resultSet.next()) {
                                  // 获取数据
                                  int id = resultSet.getInt("id");
                                  String ename = resultSet.getString("ename");
                                  int job_id = resultSet.getInt("job_id");
                                  int mgr = resultSet.getInt("mgr");
                                  Date joindate = resultSet.getDate("joindate");
                                  double salary = resultSet.getDouble("salary");
                                  double bonus = resultSet.getDouble("bonus");
                                  int dept_id = resultSet.getInt("dept_id");
        
                                  // 创建emp对象, 并赋值
                                  emp = new Emp();
                                  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);
        
                                  // 装在集合
                                  list.add(emp);
                              }
        
                          } catch (SQLException e) {
                              e.printStackTrace();
                          } finally {
                              JDBCUtils.close(resultSet, s, con);
                          }
        
                          return list;
                      }
        
                  }
    
    	* 案列:
     		* 需求:
     			1. 通过键盘录入用户名和密码
     			2. 判断用户是否登录成功
     					* select * from user where username = "" and password = "";
     					*  如果这个sql有查询结果, 则成功, 反之, 则失败
    							
     		* 步骤:
     			1. 差UN个以按数据库表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. 配置文件jdbc.properties:
     			  url = jdbc:mysql://localhost:3306/test2
                  user = root
                  password = 123456
                  driver = com.mysql.cj.jdbc.Driver
    
    			3. JDBCUtils:
    			  package cn.xiaoge.util;
    
                  import java.io.*;
                  import java.net.URL;
                  import java.sql.*;
                  import java.util.Properties;
    
                  /**
                   *  JDBC 工具类  (工具类里面都是静态方法 列 Arrays工具类)
                   */
    
                  public class JDBCUtils {
    
                      // 只有静态的变量, 才能被静态代码块访问, 才能被静态方法所访问
                      private static String url;
                      private static String user;
                      private static String password;
                      private static String driver;
    
                      /**
                       *  文件的读取, 只需要读取一次即可拿到这些值, 使用静态代码块
                       */
                      static{
    
                          try {
                              // 读取资源文件, 获取值
                              // 1. 创建Properties集合类.
                              Properties prop = new Properties();
    
                              // 获取src路径下的文件的方式--->ClassLoader 类加载器 (以src作为跟目录)
                              ClassLoader classLoader = JDBCUtils.class.getClassLoader();
                              URL reSource = classLoader.getResource("jdbc.properties");
                              // 获取文件路径
                              String path = reSource.getPath();
                              // System.out.println(path);
    
                              // 2. 加载文件
                              prop.load(new FileReader(path));
    
                              // 3. 获取属性赋值
                              url = prop.getProperty("url");
                              user = prop.getProperty("user");
                              password = prop.getProperty("password");
                              driver = prop.getProperty("driver");
    
                              // 4. 注册驱动
                              Class.forName(driver);
    
                          } catch (IOException e) {
                              e.printStackTrace();
                          } catch (ClassNotFoundException e) {
                              e.printStackTrace();
                          }
    
    
                      }
    
                      /**
                       * 获取链接
                       * @return 链接对象
                       */
                      public static Connection getConnection(){
                          Connection conn = null;
                          try {
                              conn = DriverManager.getConnection(url, user, password);
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }
    
                          return conn;
                      }
    
                      /**
                       * 释放资源
                       * @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 res
                       * @param stmt
                       * @param conn
                       */
                      public static void close(ResultSet res, Statement stmt, Connection conn) {
                          if (res != null) {
                              try {
                                  res.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();
                              }
                          }
                      }
    
                  }
    			4. 主类:
    				package cn.xiaoge.jdbc;
    
                    import cn.xiaoge.domain.Emp;
                    import cn.xiaoge.util.JDBCUtils;
                    import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
    
                    import java.sql.*;
                    import java.util.ArrayList;
                    import java.util.List;
                    import java.util.Scanner;
    
                    /**
                     *  1. 通过键盘录入用户名和密码
                     *  2. 判断用户是否登录成功
                     */
    
                    public class JdbcDemo10 {
    
                        public static void main(String[] args) {
                            // 获取用户输入的用户名和密码
                            Scanner sc = new Scanner(System.in);
                            System.out.print("请输入用户名: ");
                            String username = sc.next();
                            System.out.print("请输入密码: ");
                            String password = sc.next();
    
                            // 调用方法
                            boolean flag = new JdbcDemo10().login(username, password);
    
                            // 判断
                            if (flag) {
                                System.out.println("登入成功!");
                            } else {
                                System.out.println("用户名或密码错误!");
                            }
                        }
    
                        /**
                         * 登入方法
                         * @param username
                         * @param password
                         * @return
                         */
                        public boolean login(String username, String password) {
                            if (username == null || password == null) {
                                return false;
                            }
    
                            // 链接数据库判断是否登入成功
                            Connection conn = null;
                            Statement stmt = null;
                            ResultSet res = null;
    
                            // 1. 获取链接
                            try {
                                conn = JDBCUtils.getConnection();
    
                                // 2. 获取执行sql的对象
                                stmt = conn.createStatement();
    
                                // 3. 定义sql
                                String sql = "select * from user where username = '" + username +"' and password = '"+ password +"'";
    
                                // 4. 执行查询
                                res = stmt.executeQuery(sql);
    
                                // 5. 判断
                                return res.next();// 如果有下一行, 则返回false
    
                            } catch (SQLException e) {
                                e.printStackTrace();
                            } finally {
                                JDBCUtils.close(res, stmt, conn);
                            }
    
                            return false;
                        }
    
                    }
    

    JDBC控制事务

    1. 事务: 一个包含多个步骤的业务操作. 如果这个业务操作被事务管理, 则多个步骤要么同时成功, 要么同时失败.
    2. 操作:
    		1. 开启事务
    		2. 提交事务
    		3. 回滚事务
    3. 使用Connection对象来管理事务
    		* 开启事务: setAutoCommit(boolean autoCommit): 调用该方法设置参数为false, 即开启事务
    		* 提交事务: commit()
        	* 回滚事务: rollback()
    4. 案例:
    		1. 配置文件:
    			url = jdbc:mysql://localhost:3306/test3
                user = root
                password = 123456
                driver = com.mysql.cj.jdbc.Driver
            
        2. 工具类JDBCUtils:
       			package cn.xiaoge.util;
    
                import java.io.*;
                import java.net.URL;
                import java.sql.*;
                import java.util.Properties;
        
                /**
                 *  JDBC 工具类  (工具类里面都是静态方法 列 Arrays工具类)
                 */
        
                public class JDBCUtils {
        
                    // 只有静态的变量, 才能被静态代码块访问, 才能被静态方法所访问
                    private static String url;
                    private static String user;
                    private static String password;
                    private static String driver;
        
                    /**
                     *  文件的读取, 只需要读取一次即可拿到这些值, 使用静态代码块
                     */
                    static{
        
                        try {
                            // 读取资源文件, 获取值
                            // 1. 创建Properties集合类.
                            Properties prop = new Properties();
        
                            // 获取src路径下的文件的方式--->ClassLoader 类加载器 (以src作为跟目录)
                            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
                            URL reSource = classLoader.getResource("jdbc.properties");
                            // 获取文件路径
                            String path = reSource.getPath();
                            // System.out.println(path);
        
                            // 2. 加载文件
                            prop.load(new FileReader(path));
        
                            // 3. 获取属性赋值
                            url = prop.getProperty("url");
                            user = prop.getProperty("user");
                            password = prop.getProperty("password");
                            driver = prop.getProperty("driver");
        
                            // 4. 注册驱动
                            Class.forName(driver);
        
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
        
        
                    }
        
                    /**
                     * 获取链接
                     * @return 链接对象
                     */
                    public static Connection getConnection(){
                        Connection conn = null;
                        try {
                            conn = DriverManager.getConnection(url, user, password);
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
        
                        return conn;
                    }
        
                    /**
                     * 释放资源
                     * @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 res
                     * @param stmt
                     * @param conn
                     */
                    public static void close(ResultSet res, Statement stmt, Connection conn) {
                        if (res != null) {
                            try {
                                res.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();
                            }
                        }
                    }
        
                }
    		3. 主类:
    			package cn.xiaoge.jdbc;
    
                import cn.xiaoge.util.JDBCUtils;
        
                import java.sql.*;
                import java.util.Scanner;
        
                /**
                 *  事务操作: 转账案例
                 */
        
                public class JdbcDemo12 {
        
                    public static void main(String[] args) {
                        Connection conn = null;
                        PreparedStatement pstmt = null;
                        PreparedStatement pstmt2 = null;
                        ResultSet res = null;
        
                        try {
                            // 1. 链接数据库
                            conn = JDBCUtils.getConnection();
        
                            // 2. 定义sql
                            // 2.1 张三 - 500
                            String sql1 = "update account set balance = balance - ? where name = ?";
                            // 2.1 李四 + 500
                            String sql2 = "update account set balance = balance + ? where name = ?";
        
                            // 3. 开启事务
                            conn.setAutoCommit(false);
        
                            // 4. 获取执行sql对象
                            pstmt = conn.prepareStatement(sql1);
                            pstmt2 = conn.prepareStatement(sql2);
        
                            // 5. 给?赋值
                            pstmt.setInt(1, 500);
                            pstmt.setString(2, "zhangsan");
        
                            pstmt2.setInt(1, 500);
                            pstmt2.setString(2, "lisi");
        
                            // 6. 执行sql
                            int count = pstmt.executeUpdate();
                            int count2 = pstmt2.executeUpdate();
        
                            // 7. 判断
                            if (conn != null){
                                if (count != 0 && count2 != 0){
                                    // 8. 提交事务
                                    conn.commit();
                                } else {
                                    // 8. 回滚事务
                                    conn.rollback();
                                }
                            }
        
        
        
                        }catch (SQLException e) {
                            e.printStackTrace();
                        }finally {
                            JDBCUtils.close(pstmt, conn);
                            JDBCUtils.close(pstmt2, null);
                        }
                    }
        
                }
    

    数据库连接池

    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
    							* 路径: (这里我用的IDEA)直接将文件放在src目录下即可.
     		        3. 创建核心对象  数据库连接池对象  ComboPooledDataSource
     		        4. 获取链接: getConnection
        * 代码实现:	
    				1. 导入jar包就不写了
    				2. 配置文件c3p0-config.xml:
    						<c3p0-config>
     			               <!-- 使用默认的配置读取连接池对象 -->
     			               <default-config>
     			                 <!--  连接参数 -->
     			                 <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
     			                 <property name="jdbcUrl">jdbc:mysql://localhost:3306/test3</property>
     			                 <property name="user">root</property>
     			                 <property name="password">123456</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.cj.jdbc.Driver</property>
     			                 <property name="jdbcUrl">jdbc:mysql://localhost:3306/test3</property>
     			                 <property name="user">root</property>
     			                 <property name="password">123456</property>
     			   
     			                 <!-- 连接池参数 -->
     			                 <property name="initialPoolSize">5</property>
     			                 <property name="maxPoolSize">8</property>
     			                 <property name="checkoutTimeout">1000</property>
     			               </named-config>
     			             </c3p0-config>
            3. 代码实现:
    			package cn.xiaoge.dataSource.c3p0;
    
                import com.mchange.v2.c3p0.ComboPooledDataSource;
    
                import javax.sql.DataSource;
                import java.sql.Connection;
                import java.sql.SQLException;
    
                public class C3P0Demo2 {
    
                    public static void main(String[] args) throws SQLException {
                        // 1. 获取数据库连接池对象, 什么都不传, 使用默认配置
                        DataSource ds = new ComboPooledDataSource();
    
                        // 2. 获取链接, 获取做大链接10个, 配置文件写的最大10, 这个值可以自己改, 超过配置文件设置的值, 就会报错SQLException
                        for (int i = 0; i < 11; i++) {
                            Connection conn = ds.getConnection();
                            System.out.println(conn);
    
                            if (i == 5) {
                                conn.close(); // 归还链接到连接池中
                            }
                        }
    
                        System.out.println("******************************************************");
                        // testNameConfig(); 一般使用默认的就ok了
    
                    }
    
                    public static void testNameConfig() throws SQLException {
                        // 1. 获取数据库连接池对象
                        // 参数传递配置文件里name的属性值, 就会使用对应的配置, 不传使用默认配置
                        DataSource ds = new ComboPooledDataSource("otherc3p0");
    
                        // 2. 获取链接
                        for (int i = 0; i < 10; i++) {
                            Connection conn = ds.getConnection();
                            System.out.println(conn);
                        }
    
                    }
    
                }
    
            
            
    5. Druid: 数据库连接池实现技术, 由阿里巴巴提供的
    		1. 步骤:
    				1. 导入jar包 druid-1.0.9.jar
    				2. 定义配置文件:
    						* 是properties形式的(键值对形式)
                			* 可以叫任意名称, 可以放在任意目录下
            3. 加载配置文件. 使用Properties集合
            4. 获取数据库连接池对象: 通过工厂类来获取		DruidDataSourceFactory
            5. 获取链接: getConnection
        2. 代码实现:
     		1. 导入jar包就不说了
     		2. 配置文件(我这里叫druid.properties):
     			driverClassName = com.mysql.cj.jdbc.Driver
                url = jdbc:mysql://127.0.0.1:3306/test3
                username = root
                password = 123456
    
                # 初始化连接数
                initialSize = 5
    
                # 最大连接数
                maxActive = 10
    
                # 最大等待时间(单位/)
                maxWait = 3000
            3. 代码实现:
    			package cn.xiaoge.dataSource.druid;
    
                import com.alibaba.druid.pool.DruidDataSourceFactory;
    
                import javax.sql.DataSource;
                import java.io.InputStream;
                import java.sql.Connection;
                import java.util.Properties;
    
                /**
                 * @Author: XiaoGe
                 * @DateTime: 2020/1/22 下午8:32
                 * @Description: druid数据库连接池
                 */
                public class DruidDemo {
    
                    public static void main(String[] args) throws Exception {
                        // 1. 导入jar包
                        // 2. 定义配置文件
                        // 3. 加载配置文件
                        // 3.1 创建Properties集合
                        Properties prop = new Properties();
                        // 3.2 获取src路径下的文件的方式--->ClassLoader 类加载器 (以src作为跟目录), 获取druid.properties配置文件, 返回字节流对象那个
                        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
                        // 3.3 把该配置文件加载进prop集合中
                        prop.load(is);
    
                        // 4. 获取连接池对象, 传递prop集合
                        DataSource ds = DruidDataSourceFactory.createDataSource(prop);
    
                        // 5. 获取链接
                        Connection conn = ds.getConnection();
    
                        // 6. 打印
                        System.out.println(conn);
    
                    }
    
                }  
    
    		3. 定义工具类
    				1. 定义一个类	JDBCUtils
    				2. 提供静态代码块加载配置文件, 初始化连接池对象 
    				3. 提供方法
    						1. 获取链接方法: 通过数据库连接池获取链接
    						2. 释放资源
    						3. 获取连接池的方法
    		4. 代码实现:
    				1. 导入jar包不说了
    				2. 配置文件不说了, 如上那样的配置文件
    				3. 工具类JDBCUtils
    						 package cn.xiaoge.utils;
    
     		                 import com.alibaba.druid.pool.DruidDataSourceFactory;
     		   
     		                 import javax.sql.DataSource;
     		                 import java.io.IOException;
     		                 import java.io.InputStream;
     		                 import java.sql.Connection;
     		                 import java.sql.ResultSet;
     		                 import java.sql.SQLException;
     		                 import java.sql.Statement;
     		                 import java.util.Properties;
     		   
     		                 /**
     		                  * @Author: XiaoGe
     		                  * @DateTime: 2020/1/22 下午9:04
     		                  * @Description: Druid连接池的工具类
     		                  */
     		                 public class JDBCUtils {
     		                     // 1. 定义成员变量 DataSource
     		                     private static DataSource ds;
     		   
     		                     static{
     		   
     		                         try{
     		                             Properties prop = new Properties();
     		                             InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
     		                             prop.load(is);
     		                             ds = DruidDataSourceFactory.createDataSource(prop);
     		                         } catch (IOException e) {
     		                             e.printStackTrace();
     		                         } catch (Exception e) {
     		                             e.printStackTrace();
     		                         }
     		   
     		                     }
     		   
     		                     /**
     		                      * 获取链接
     		                      * @return Connection Object
     		                      * @throws SQLException
     		                      */
     		                     public static Connection getConnection() throws SQLException {
     		                         return ds.getConnection();
     		                     }
     		   
     		                     /**
     		                      * 释放资源
     		                      * @param stmt
     		                      * @param conn
     		                      * @throws SQLException
     		                      */
     		                     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 res
     		                      * @param stmt
     		                      * @param conn
     		                      * @throws SQLException
     		                      */
     		                     public static void close(ResultSet res, Statement stmt, Connection conn) {
     		                         if (res != null) {
     		                             try {
     		                                 res.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() {
     		                         // 因为静态代码块已经加载, 等不等于null都可以返回, 所以这里不判断了
     		                         return ds;
     		                     }
     		   
     		   
     		                 }
     		   			
    				4. 代码实现
    					 package cn.xiaoge.dataSource.druid;
    
     	                 import cn.xiaoge.utils.JDBCUtils;
     	   
     	                 import javax.sql.DataSource;
     	                 import java.sql.Connection;
     	                 import java.sql.PreparedStatement;
     	                 import java.sql.SQLException;
     	   
     	                 /**
     	                  * @Author: XiaoGe
     	                  * @DateTime: 2020/1/22 下午9:25
     	                  * @Description: 使用工具类
     	                  */
     	                 public class DruidDemo2 {
     	   
     	                     public static void main(String[] args) {
     	                         /**
     	                          * 完成一个添加操作: 给account表添加一条记录
     	                          */
     	                         Connection conn = null;
     	                         PreparedStatement pstmt = null;
     	                         try {
     	                             // 1. 获取数据库连接池对象
     	                             DataSource ds = JDBCUtils.getDataSource();
     	   
     	                             if (ds != null) {
     	                                 // 2. 获取链接对象
     	                                 conn = ds.getConnection();
     	   
     	                                 // 3. 定义sql
     	                                 String sql = "insert into account values(?, ?, ?)";
     	   
     	                                 // 4. 获取执行sql对象
     	                                 pstmt = conn.prepareStatement(sql);
     	   
     	                                 // 5. 给?赋值
     	                                 pstmt.setString(1, null);
     	                                 pstmt.setString(2, "wangwu");
     	                                 pstmt.setInt(3, 2000);
     	   
     	                                 // 6. 执行sql
     	                                 int count = pstmt.executeUpdate();
     	   
     	                                 // 7. 判断是否添加成功
     	                                 if (count != 0) {
     	                                     System.out.println("添加成功!");
     	                                 } else {
     	                                     System.out.println("添加失败!");
     	                                 }
     	   
     	                             } else {
     	                                 System.out.println("NullPointerException");
     	                             }
     	                         } catch (SQLException e) {
     	                             e.printStackTrace();
     	                         } finally {
     	                             // 8. 释放资源
     	                             JDBCUtils.close(pstmt, conn);
     	                         }
     	   
     	                     }
     	   
     	                 }
    
    

    Spring JDBC

    * Spring框架对JDBC的简单封装. 提供了一个JDBCTemplate对象简化JDBC开发
    * 步骤:
    		1. 导入jar包
    		2. 创建JdbcTemplate对象, 依赖于数据源DataSource
    				* JdbcTemplate  template = new JdbcTemplate(DataSource);
    
    		3. 调用JdbcTemplate的方法来完成CRUD操作
    				* update(): 执行DM领域具, 增、删、改语句
    				* 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. 查询总记录数
           			* 代码实现:
    						1. 导入jar包不说了
    						2. 配置文件不说了
    						3. 工具类JDBCUtils
    							   package cn.xiaoge.utils;
    
     			                   import com.alibaba.druid.pool.DruidDataSourceFactory;
     			   
     			                   import javax.sql.DataSource;
     			                   import java.io.IOException;
     			                   import java.io.InputStream;
     			                   import java.sql.Connection;
     			                   import java.sql.ResultSet;
     			                   import java.sql.SQLException;
     			                   import java.sql.Statement;
     			                   import java.util.Properties;
     			   
     			                   /**
     			                    * @Author: XiaoGe
     			                    * @DateTime: 2020/1/22 下午9:04
     			                    * @Description: Druid连接池的工具类
     			                    */
     			                   public class JDBCUtils {
     			                       // 1. 定义成员变量 DataSource
     			                       private static DataSource ds;
     			   
     			                       static{
     			   
     			                           try{
     			                               Properties prop = new Properties();
     			                               InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
     			                               prop.load(is);
     			                               ds = DruidDataSourceFactory.createDataSource(prop);
     			                           } catch (IOException e) {
     			                               e.printStackTrace();
     			                           } catch (Exception e) {
     			                               e.printStackTrace();
     			                           }
     			   
     			                       }
     			   
     			                       /**
     			                        * 获取链接
     			                        * @return Connection Object
     			                        * @throws SQLException
     			                        */
     			                       public static Connection getConnection() throws SQLException {
     			                           return ds.getConnection();
     			                       }
     			   
     			                       /**
     			                        * 释放资源
     			                        * @param stmt
     			                        * @param conn
     			                        * @throws SQLException
     			                        */
     			                       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 res
     			                        * @param stmt
     			                        * @param conn
     			                        * @throws SQLException
     			                        */
     			                       public static void close(ResultSet res, Statement stmt, Connection conn) {
     			                           if (res != null) {
     			                               try {
     			                                   res.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() {
     			                           // 因为静态代码块已经加载, 等不等于null都可以返回, 所以这里不判断了
     			                           return ds;
     			                       }
     			   
     			   
     			                   }
    					
    						4. Emp类
    							   package cn.xiaoge.domain;
    
     			                   import java.util.Date;
     			   
     			                   /**
     			                    * @Author: HWB
     			                    * @DateTime: 2020/1/23 下午3:54
     			                    * @Description: Emp表的属性跟数据库字段一一对应
     			                    */
     			                   public class Emp {
     			   
     			                       private Integer id;
     			                       private String ename;
     			                       private Integer job_id;
     			                       private Integer mgr;
     			                       private Date joindate;
     			                       private Double salary;
     			                       private Double bonus;
     			                       private Integer dept_id;
     			   
     			                       public Integer getId() {
     			                           return id;
     			                       }
     			   
     			                       public void setId(Integer id) {
     			                           this.id = id;
     			                       }
     			   
     			                       public String getEname() {
     			                           return ename;
     			                       }
     			   
     			                       public void setEname(String ename) {
     			                           this.ename = ename;
     			                       }
     			   
     			                       public Integer getJob_id() {
     			                           return job_id;
     			                       }
     			   
     			                       public void setJob_id(Integer job_id) {
     			                           this.job_id = job_id;
     			                       }
     			   
     			                       public Integer getMgr() {
     			                           return mgr;
     			                       }
     			   
     			                       public void setMgr(Integer mgr) {
     			                           this.mgr = mgr;
     			                       }
     			   
     			                       public Date getJoindate() {
     			                           return joindate;
     			                       }
     			   
     			                       public void setJoindate(Date joindate) {
     			                           this.joindate = joindate;
     			                       }
     			   
     			                       public Double getSalary() {
     			                           return salary;
     			                       }
     			   
     			                       public void setSalary(Double salary) {
     			                           this.salary = salary;
     			                       }
     			   
     			                       public Double getBonus() {
     			                           return bonus;
     			                       }
     			   
     			                       public void setBonus(Double bonus) {
     			                           this.bonus = bonus;
     			                       }
     			   
     			                       public Integer getDept_id() {
     			                           return dept_id;
     			                       }
     			   
     			                       public void setDept_id(Integer dept_id) {
     			                           this.dept_id = dept_id;
     			                       }
     			   
     			                       @Override
     			                       public String toString() {
     			                           return "Emp{" +
     			                                   "id=" + id +
     			                                   ", ename='" + ename + '\'' +
     			                                   ", job_id=" + job_id +
     			                                   ", mgr=" + mgr +
     			                                   ", joindate=" + joindate +
     			                                   ", salary=" + salary +
     			                                   ", bonus=" + bonus +
     			                                   ", dept_id=" + dept_id +
     			                                   '}';
     			                       }
     			                   }
    
    					  5. 代码实现
    							   package cn.xiaoge.jdbctemplate;
    
     			                   import cn.xiaoge.domain.Emp;
     			                   import cn.xiaoge.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.ResultSet;
     			                   import java.sql.SQLException;
     			                   import java.util.ArrayList;
     			                   import java.util.List;
     			                   import java.util.Map;
     			                   import java.util.Set;
     			   
     			                   /**
     			                    * @Author: HWB
     			                    * @DateTime: 2020/1/23 下午3:58
     			                    * @Description: 对Emp表的操作
     			                    *
     			                    * 1. 修改1号数据的 salary 为 10000
     			                    * 2. 添加一条记录
     			                    * 3. 删除刚才添加的记录
     			                    * 4. 查询id为1的记录, 将其封装为Map集合
     			                    * 5. 查询所有记录, 将其封装为List集合
     			                    * 6. 查询所有记录, 将其封装为Emp对象的List集合
     			                    * 7. 查询总记录数
     			                    *
     			                    */
     			                   public class JdbcTemplateDemo2 {
     			   
     			                       // 创建JdbcTemplate对象
     			                       JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
     			   
     			   
     			                       /**
     			                        * 修改1号数据的 salary 为 10000
     			                        */
     			                       @Test
     			                       public void update(){
     			                           // 定义sql
     			                           String sql = "update emp set salary = 10000 where id = ?";
     			                           int count = template.update(sql, 1001);
     			                           System.out.println(count);
     			                       }
     			   
     			   
     			                       /**
     			                        *  添加一条记录
     			                        */
     			                       @Test
     			                       public void insert(){
     			                           // 定义sql
     			                           String sql = "insert into emp values(?, ?, ?, ?, ?, ?, ?, ?)";
     			                           int count = template.update(sql, 1015, "李白", 4, null, "2002-01-23", 10000.00, null, 20);
     			                           System.out.println(count);
     			                       }
     			   
     			   
     			                       /**
     			                        * 删除刚才添加的记录
     			                        */
     			                       @Test
     			                       public void delete(){
     			                           // 定义sql
     			                           String sql = "delete from emp where ename = ?";
     			                           int count = template.update(sql, "李白");
     			                           System.out.println(count);
     			                       }
     			   
     			   
     			                       /**
     			                        * 查询一号信息, 将其封装为Map集合
     			                        */
     			                       @Test
     			                       public void selectMap(){
     			                           // 定义sql
     			                           String sql = "select * from emp limit ?";
     			                           Map<String, Object> map = template.queryForMap(sql, 1);
     			                           System.out.println(map);
     			                       }
     			   
     			   
     			                       /**
     			                        *  查询所有记录, 将其封装为List集合
     			                        */
     			                       @Test
     			                       public void selectList(){
     			                           // 定义sql
     			                           String sql = "select * from emp";
     			                           List<Map<String, Object>> list = template.queryForList(sql);
     			                           System.out.println(list);
     			                           /*
     			                               // 遍历list集合即map集合
     			                               for (Map<String, Object> stringObjectMap : list) {
     			                                   System.out.println(stringObjectMap);
     			                                   Set<String> keys = stringObjectMap.keySet();
     			                                   for (String key : keys) {
     			                                       System.out.println(stringObjectMap.get(key));
     			                                   }
     			                               }
     			                           */
     			                       }
     			   
     			   
     			                       /**
     			                        * 查询所有记录, 将其封装为Emp对象的List集合
     			                        */
     			                       @Test
     			                       public void selectEmpList(){
     			                           // 定义sql
     			                           String sql = "select * from emp";
     			                           // 现在是自己实现RowMapper<Emp>接口, 所以这么繁琐, 用这个接口的实现类就很简单了, 看selectEmpList_2方法
     			                           List<Emp> list = template.query(sql, new RowMapper<Emp>() {
     			   
     			                               // 结果集: resultSet
     			                               // 小标: i
     			                               @Override
     			                               public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
     			                                   Emp emp = new Emp();
     			                                   // 这里不要用resultSet.next, 因为这里resultSet一次就是一个对象
     			                                   emp.setId(resultSet.getInt("id"));
     			                                   emp.setEname(resultSet.getString("ename"));
     			                                   emp.setJob_id(resultSet.getInt("job_id"));
     			                                   emp.setMgr(resultSet.getInt("mgr"));
     			                                   emp.setJoindate(resultSet.getDate("joindate"));
     			                                   emp.setSalary(resultSet.getDouble("salary"));
     			                                   emp.setBonus(resultSet.getDouble("bonus"));
     			                                   emp.setDept_id(resultSet.getInt("dept_id"));
     			   
     			   
     			                                   return emp;
     			                               }
     			                           });
     			                           for (Emp emp : list) {
     			                               System.out.println(emp);
     			                           }
     			   
     			                       }
     			   
     			   
     			                       /**
     			                        * 查询所有记录, 将其封装为Emp对象的List集合
     			                        */
     			                       @Test
     			                       public void selectEmpList_2(){
     			                           // 定义sql
     			                           String sql = "select * from emp";
     			                           // BeanPropertyRowMapper是RowMapper的实现类, 传递的参数, 传递你查询的类的字节码文件
     			                           List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
     			                           // 报错: Failed to convert property value of type 'null' to required type 'double' for property 'bonus';
     			                           // 所以: 定义类属性时, 变量类型用包装类Integer, Double, 而不是用基本类型int, double, 因为基本类型不能接受null
     			                           for (Emp emp : list) {
     			                               System.out.println(emp);
     			                           }
     			   
     			                       }
     			   
     			   
     			                       /**
     			                        * 查询总记录数
     			                        */
     			                       @Test
     			                       public void count(){
     			                           // 定义sql
     			                           String sql = "select count(id) from emp";
     			                           // queryForObject, 第二个参数传递返回值结果的类型, 因为select count(id) from emp返回的是long类型的
     			                           Long total = template.queryForObject(sql, Long.class);
     			                           System.out.println(total);
     			                       }
     			   
     			                   }
    
    
posted on 2020-01-23 18:50  gmlgxx  阅读(47)  评论(0)    收藏  举报