zoukankan      html  css  js  c++  java
  • 03JDBC

    JDBC

    JDBC是Java访问数据库的标准规范,具体操作具体由数据库厂商实现,相当于一个数据库驱动。我们只需要会JDBC接口中的方法即可,数据库驱动(jar包)由数据库厂商提供。

    导入驱动jar包:

    1. 创建libs文件夹
    2. 复制jar包到libs
    3. 右键libs->add as library

    JDBC快速实现:

    public class Test {
        public static void main(String[] args) throws Exception {
            // 1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2. 获取数据库连接对象
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "root");
            // 3. 定义sql语句
            String sql = "update stu set score=80 where id=1";
            // 4. 获取sql执行对象
            Statement stmt = conn.createStatement();
            // 5. 执行sql
            int count = stmt.executeUpdate(sql);
            // 6. 处理结果
            System.out.println(count);
            // 7. 释放资源
            stmt.close();
            conn.close();
        }
    }
    

    JDBC的核心API:

    1. DriverManager 驱动管理对象,返回数据库连接对象

      • URL参数如果是本地 可以省略 jdbc:mysql:///stu
      • 处理乱码:jdbc:mysql///stu?characterEncoding=utf8
    2. Connection 数据库连接对象,用于创建一条SQL语句对象

      • Statement stmt = conn.createStatment();
      • PreparedStatment pstmt = conn.prepareStatement(sql);
      • setAutoCommit(boolean); 开始事务
      • commit(); 提交事务
      • rollback(); 回滚事务
    3. Statement 执行静态sql对象

      • boolean execute(sql); 执行任意sql
      • int executeUpdate(sql); 增删改、创建、修改、删除
      • ResultSet executeQuery(sql); 查找
    4. PreparedStatment 执行动态sql对象

    5. ResultSet:执行结果

      ResultSet rs = stmt.executeQuery(sql);
      while (rs.next()) {
          int id = rs.getInt(1);  // 根据列号
          String name = rs.getString("name");  // 根据列名
          System.out.println(id + ": " + name);
      }
      

    JdbcUtils

    如果一个功能经常要用到(代码重复),就把这个功能做成工具类。

    解决:

    1. 工具类中定义许多静态方法,通过传递参数解决;
    2. 如果不想传参,则把参数放在配置文件jdbc.properties中传递;
    3. 配置文件只需要读取一次即可,所以把读取配置文件代码放在静态代码块中。

    最终如下:

    1. src目录下创建配置文件jdbc.properties
    url=jdbc:mysql://localhost:3306/db1
    user=root
    password=root
    driver=com.mysql.jdbc.Driver
    
    1. 创建工具类 JDBCUtils.java
    import java.io.FileReader;
    import java.io.IOException;
    import java.net.URL;
    import java.sql.*;
    import java.util.Properties;
    
    public class JDBCUtils {
        private static String url;
        private static String user;
        private static String password;
        private static String driver;
    
        static {
            try {
                // 获取绝对路径
                ClassLoader classLoader = JDBCUtils.class.getClassLoader();
                URL res = classLoader.getResource("jdbc.properties");
                String path = res.getPath();
                // 加载配置文件
                Properties pro = new Properties();
                pro.load(new FileReader(path));
                url = pro.getProperty("url");
                user = pro.getProperty("user");
                password = pro.getProperty("password");
                driver = pro.getProperty("driver");
                // 注册驱动
                Class.forName(driver);
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() throws SQLException {
            return DriverManager.getConnection(url, user, password);
        }
    
        public static void close(Statement stmt, Connection conn) {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    
        public static void close(Statement stmt, Connection conn, ResultSet rs) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            close(stmt, conn);
        }
    }
    
    1. 数据库连接(测试工具类)
    import java.sql.*;
    
    public class JdbcDemo {
        public static void main(String[] args) {
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                conn = JDBCUtils.getConnection();
                stmt = conn.createStatement();
                String sql = "select * from stu";
                rs = stmt.executeQuery(sql);
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String name = rs.getString("name");
                    System.out.println(id + ": " + name);
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                JDBCUtils.close(stmt, conn, rs);
            }
        }
    }
    

    PreparedStatment

    SQL注入问题:在用户密码和数据库匹配时,如果SQL语句是:

    select * from user where name='Tom' and password='root' or 1=1;

    则返回所有查询结果。

    所以 使用PreparedStatment匹配SQL语句中的占位符?,可以防止SQL注入问题。

    // 定义sql
    String sql = "select * from user where name=? and password=?";
    // 获取执行sql的对象
    PreparedStatement  pstmt = conn.getpreparedStatement(sql);
    // 赋值
    pstmt.setString(1, "Tom");
    pstmt.setString(2, "123");
    // 执行
    ResultSet rs = pstmt.executeQuery();
    

    JDBC控制事务

    使用Connection对象管理事务:

    • setAutoCommit(boolean);` 开始事务:设置为false,相当于开启事务
    • commit(); 提交事务
    • rollback(); 回滚事务

    案例:

    Connection conn =  null;
    PrepareStatment ps = null;
    try{
    	conn = JdbcUtils.getConnection();
    	conn.setAutoCommit(false); // 开启事务
    	ps = conn.prepareStatment("update stu set score=? where name=?");
    	ps.setInt(1, 90);
    	ps.setString(2, "张三");
    	ps.executeUpdate();
    	conn.commit(); // 提交事务
    } catch () {
    	conn.rollback(); // 回滚事务
    } finally {
    	JdbcUtils.close(ps, conn);
    }
    

    JDBC连接池

    之前都是每次连接数据库,执行完sql立马释放资源,降低了执行效率,因此提出数据库连接池。

    1. 接口:javax.sql.DataSourrce,由数据库厂商实现数据库连接池
      • 获取连接:Connection conn = ds.getConnection()
      • 归还连接:conn.close() ,归还给连接池
    2. 常见数据连接池实现:
      • C3P0:
      • Druid:阿里巴巴提供

    C3P0连接池技术:

    1. 导入jar包
      • 导入c3p0-0.9.5.2.jar
      • 导入c3p0的依赖包mchange-commons-java-0.2.12.jar
    2. 定义配置文件
      • 直接将配置文件c3p0-config.xml放在src目录下。
      • 定义一下数据库等
    3. 创建数据库连接池对象DataSource ds = new ComboPooledDataSource();
    4. 获取连接:Connection conn = ds.getConnection();

    Druid连接池:

    连接池使用:

    1. 导入jar包druid-1.0.9.jar

    2. 导入并定义配置文件

      • 任意位置导入druid.properties
    3. 获取连接池对象:通过工厂类获取

    4. 获取连接对象

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

    工具类:

    1. 定义一个类JDBCUtils
    2. 提供静态代码块加载配置文件,初始化连接池对象
    3. 提供方法:
      • 获取连接池的方法
      • 获取连接方法
      • 释放资源

    例子,工具类代码:

    import com.alibaba.druid.pool.DruidDataSourceFactory;
    import javax.sql.DataSource;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;
    
    public class JDBCUtils {
        private static DataSource ds;
    
        static {
            Properties pro = new Properties();
            try {
                pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
                ds = DruidDataSourceFactory.createDataSource(pro);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
    
        public static void close(Statement stmt, Connection conn) {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    
        public static void close(ResultSet rs, Statement stmt, Connection conn) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            close(stmt, conn);
        }
    
        public static DataSource getDataSource() {
            return ds;
        }
    }
    

    工具类测试代码

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class DruidDemo2 {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement pstmt = null;
            try {
                conn = JDBCUtils.getConnection();
                String sql = "insert into stu values(?, ?, ?, ?)";
                pstmt = conn.prepareStatement(sql);
                pstmt.setInt(1, 5);
                pstmt.setString(2, "测试");
                pstmt.setInt(3, 100);
                pstmt.setInt(4, 100);
                int count = pstmt.executeUpdate();
                System.out.println(count);
    
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                JDBCUtils.close(pstmt, conn);
            }
        }
    }
    

    JDBC Template

    JDBC工具类已经很好用了,但是创建连接对象、创建执行对象、执行sql语句等还是很复杂。

    Spring框架对JDBC进行简单封装,提供了JDBC Template对象,简化了JDBC开发,只需要关注执行sql和结果。

    1. 导入JdbcTemplate的jar包(5个)

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

      • JdbcTemplate template= new JdbcTemplate(ds);
    3. 调用JdbcTemplate的方法完成增删改查

      • update(): 增删改

      • queryForMap(): 查询一条记录

        String sql = "select * from emp where id=?";
        Map<String, Object> map = temp.queryForMap(sql, 1);
        
      • queryForList(): 封装为List对象

        String sql = "select * from emp";
        List<Map<String, Object>> list = temp.queryForList(sql);
        for (Map<String, Object> map : list) {
        	System.out.println(map);
        }
        
      • query(): 封装为JavaBean对象

        String sql = "select * from emp";
        List<Emp> list = temp.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
        for (Emp emp : list) {
        	System.out.println(emp);
        }
        
      • queryForObject(): 封装为基本类型对象,用于聚合函数

        String sql = "select count(*) from emp";
        Long total = temp.queryForObject(sql, Long.class);
        System.out.println(total);
        

    一个简单的例子:(连接池等都是template完成,不需要自己写)

    JdbcTemplate template= new JdbcTemplate(JDBCUtils.getDataSource());
    String sql = "update stu set age=18 where id=?";
    int count = template.update(sql, 5);
    System.out.println(count);
    
  • 相关阅读:
    typora永久插入图片
    Cortex-M 处理器 hardfault 定位方法和步骤(基于Keil mdk)
    STM32之CAN ---CAN ID过滤器分析
    记一次payload绕过电脑管家免杀
    kali linux 静态地址和动态地址的设置
    mona
    武装你的浏览器--自用的火狐插件推荐
    kali linux开启ssh
    记一次腾讯云服务器centos linux可视化桌面安装并进行远程桌面登录及其安装中文包
    widows终端远程连接Linux服务器
  • 原文地址:https://www.cnblogs.com/mingriyingying/p/13439277.html
Copyright © 2011-2022 走看看