• JDBC


    jdbc定义

    Java提供访问数据库规范称为JDBC(Java Data Base Connectivity,java数据库连接),而生产厂商提供规范的实现类称为驱动。

    JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库。每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。

    JDBC开发步骤

    1.    注册驱动
    告知JVM使用的是哪一个数据库的驱动

    2.    获得连接
    使用JDBC中的类,完成对MySQL数据库的连接

    3.    获得语句执行平台
    通过连接对象获取对SQL语句的执行者对象

    4.    执行sql语句
    使用执行者对象,向数据库执行SQL语句

    5.    处理结果

    6.    释放资源
    执行一堆close().

    PreparedStatement 预处理对象

    因为SQL注入问题,采用 PreparedStatement 预处理对象来解决。使用PreparedStatement预处理对象时的常用方法:

    • int executeUpdate(); --执行insert update delete语句.
    • ResultSet executeQuery(); --执行select语句.
    • boolean execute(); --执行select返回true 执行其他的语句返回false.
    public void demo01() throws Exception {
        // 1注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3获得预处理对象
        String sql = "insert into sort(sname) values(?)";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL语句占位符设置实际参数
        stat.setString(1, "奢侈品");
        // 5执行SQL语句
        int line = stat.executeUpdate();
        System.out.println("新添加记录数:" + line);
        // 6释放资源
        stat.close();
        conn.close();
    }
    
    public void demo02() throws Exception {
        // 1注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3获得预处理对象中
        String sql = "update sort set sname=? where sid=?";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL语句占位符设置实际参数
        stat.setString(1, "数码产品");
        stat.setInt(2, 1);
        // 5执行SQL语句
        int line = stat.executeUpdate();
        System.out.println("更新记录数:" + line);
        // 6释放资源
        stat.close();
        conn.close();
    }
    
    public void demo03() throws Exception {
        // 1注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3获得预处理对象
        String sql = "delete from sort where sid=?";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL语句占位符设置实际参数
        stat.setInt(1, 1);
        // 5执行SQL语句
        int line = stat.executeUpdate();
        System.out.println("删除记录数:" + line);
        // 6释放资源
        stat.close();
        conn.close();
    }
    
    public void demo05() throws Exception {
        // 1注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
        // 3获得预处理对象
        String sql = "select * from sort where sname=?";
        PreparedStatement stat = conn.prepareStatement(sql);
        // 4 SQL语句占位符设置实际参数
        stat.setString(1, "奢侈品");
        // 5执行SQL语句
        ResultSet rs = stat.executeQuery();
        // 6处理结果集(遍历结果集合)
        while( rs.next() ){
            //获取当前行的分类ID
            String sid = rs.getString("sid");//方法参数为数据库表中的列名
            //获取当前行的分类名称
            String sname = rs.getString("sname");
            //显示数据
            System.out.println(sid+"-----"+sname);
        }
        // 7释放资源
        rs.close();
        stat.close();
        conn.close();
    }
    PreparedStatement的执行方法

    自己处理JDBC连接

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mydb
    user=root
    password=root
    db.propertie
    public class JDBCUtils {
        private static String driver;
        private static String url;
        private static String user;
        private static String password;
        // 静态代码块
        static {
            try {
                // 1 使用Properties处理流
                // 使用load()方法加载指定的流
                Properties props = new Properties();
                Reader is = new FileReader("db.properties");
                props.load(is);
                // 2 使用getProperty(key),通过key获得需要的值,
                driver = props.getProperty("driver");
                url = props.getProperty("url");
                user = props.getProperty("user");
                password = props.getProperty("password");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 获得连接
         */
        public static Connection getConnection() {
            try {
                // 1 注册驱动
                Class.forName(driver);
                // 2 获得连接
                Connection conn = DriverManager.getConnection(url, user, password);
                return conn;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
    JDBCUtils
    public class Demo {
        @Test
        public void insert(){
            try{
                //1,获取连接对象
                Connection conn = JDBCUtils.getConnection();
                //2,指定要执行的SQL语句
                String sql = "INSERT INTO zhangwu(name,money,parent) VALUES(?,?,?)";
                //4,获取SQL语句的执行对象 PreparedStatement
                PreparedStatement ppstat = conn.prepareStatement(sql);
                //5,执行SQL语句
                ppstat.setString(1, "股票收入");
                ppstat.setDouble(2, 5000);
                ppstat.setString(3, "收入");
                int line = ppstat.executeUpdate();
                //6,处理结果集
                System.out.println("line=" + line);
                //7,关闭连接
                ppstat.close();
                conn.close();
            } catch(SQLException e){
                throw new RuntimeException(e);
            }
        }
    }
    测试Demo

    其中 new FileReader("db.properties"); 在实际中还有可能的方式为 JDBCUtils.class.getClassLoader().getResourceAsStream("db.propeties");

    Dbutils

    自己处理的时候,比较繁琐,可以引入工具jar:apache commons组件成员 commons-dbutils-1.6.jar 是JDBC的简化开发工具包。
    DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。
    Dbutils三个核心功能:
    QueryRunner中提供对sql语句操作的API。
    ResultSetHandler接口,用于定义select操作后,怎样封装结果集。
    DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法。

    QueryRunner核心类

    QueryRunner增删改操作

    update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作

    public void insert(){
        try {
            //获取一个用来执行SQL语句的对象   QueryRunner
            QueryRunner qr = new QueryRunner();
            
            String sql = "INSERT INTO zhangwu(name,money,parent) VALUES(?,?,?)";
            Object[] params = {"股票收入", 5500, "收入"};
            Connection conn = JDBCUtils.getConnection();
            int line = qr.update(conn,sql,params);// 用来完成表数据的增加、删除、更新操作
            //结果集处理
            System.out.println("line = " + line);
            
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    public void update(){
        try {
            //创建一个QueryRunner对象,用来完成SQL语句的执行
            QueryRunner qr = new QueryRunner();
            //执行SQL语句
            String sql = "UPDATE zhangwu SET money = money+1000 WHERE name=?";
            Object[] params = {"股票收入"};
            Connection conn = JDBCUtils.getConnection();
            int line = qr.update(conn, sql, params);
            //结果集的处理
            System.out.println("line="+line);
            
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    public void delete(){
        try {
            //创建一个QueryRunner对象,用来完成SQL语句的执行
            QueryRunner qr = new QueryRunner();
            //执行SQL语句
            String sql = "DELETE FROM zhangwu WHERE name = ?";
            Object[] params = {"股票收入"};
            Connection conn = JDBCUtils.getConnection();
            int line = qr.update(conn, sql, params);
            //结果集的处理
            System.out.println("line="+line);
            
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    queryRunner增删改

    QueryRunner查询操作

    query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作

    ResultSetHandler结果集处理类

    ArrayHandler

    将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值

    ArrayListHandler

    将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。

    BeanHandler

    将结果集中第一条记录封装到一个指定的javaBean中。

    BeanListHandler

    将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中

    ColumnListHandler

    将结果集中指定的列的字段值,封装到一个List集合中

    ScalarHandler

    它是用于单数据。例如select count(*) from 表操作。

    MapHandler

    将结果集第一行封装到Map集合中,Key 列名, Value 该列数据

    MapListHandler

    将结果集每一行封装到Map集合中,Key 列名, Value 该列数据,Map集合存储到List集合

    public class ArrayHandlerDemo {
        @Test
        public void method(){
            try {
                //获取QueryRunner对象
                QueryRunner qr = new QueryRunner();
                //执行SQL语句
                String sql = "SELECT * FROM zhangwu";
                Object[] params = {};
                Connection conn = JDBCUtils.getConnection();
                Object[] objArray = qr.query(conn, sql, new ArrayHandler(), params);
                //结果集的处理
                System.out.println( Arrays.toString(objArray) );
                
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class ArrayListHandlerDemo {
        @Test
        public void method(){
            try {
                //获取QueryRunner对象
                QueryRunner qr = new QueryRunner();
                //执行SQL语句
                String sql = "SELECT * FROM zhangwu WHERE money>?";
                Object[] params = {2000};
                Connection conn = JDBCUtils.getConnection();
                 List<Object[]> list = qr.query(conn, sql, new ArrayListHandler(), params);
                //结果集的处理
                 for (Object[] objArray : list) {
                    System.out.println(  Arrays.toString(objArray) );
                }
                
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class BeanHandlerDemo {
        @Test
        public void method(){
            try{
                //获取QueryRunner 
                QueryRunner qr = new QueryRunner();
                //执行SQL语句
                String sql = "SELECT * FROM zhangwu WHERE id=?";
                Object[] params = {1};
                Connection conn = JDBCUtils.getConnection();
                ZhangWu zw = qr.query(conn, sql, new BeanHandler<ZhangWu>(ZhangWu.class), params);
                //结果集处理
                System.out.println(zw);
                
                conn.close();
            } catch(SQLException e){
                throw new RuntimeException(e);
            }
        }
    }
    
    public class BeanListHandlerDemo {
        @Test
        public void method(){
            try{
                //获取QueryRunner 
                QueryRunner qr = new QueryRunner();
                //执行SQL语句
                String sql = "SELECT * FROM zhangwu WHERE money>?";
                Object[] params = {2000};
                Connection conn = JDBCUtils.getConnection();
                List<ZhangWu> list = qr.query(conn, sql, new BeanListHandler<ZhangWu>(ZhangWu.class), params);
                //结果集处理
                for (ZhangWu zw : list) {
                    System.out.println(zw);
                }
                
                conn.close();
            } catch(SQLException e){
                throw new RuntimeException(e);
            }
        }
    }
    
    public class ColumnListHandlerDemo {
        @Test
        public void method(){
            try {
                //获取QueryRunner对象
                QueryRunner qr = new QueryRunner();
                //执行SQL语句
                String sql = "SELECT name FROM zhangwu WHERE money>?";
                Object[] params = {2000};
                Connection conn = JDBCUtils.getConnection();
                List<String> list = qr.query(conn, sql, new ColumnListHandler<String>(), params); 
                //结果集的处理
                for (String str : list) {
                    System.out.println(str);
                }
    
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class ScalarHandlerDemo {
        @Test
        public void method(){
            try {
                //获取QueryRunner对象
                QueryRunner qr = new QueryRunner();
                
                //执行SQL语句
                String sql = "SELECT MAX(money) FROM zhangwu";
                Object[] params = {};
                Connection conn = JDBCUtils.getConnection();
                Double max = qr.query(conn, sql, new ScalarHandler<Double>(), params);
                //结果集的处理
                System.out.println("max=" + max);
                
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    ResultSetHandler例子

    连接池

    “获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。
    Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池。
    常见的连接池:DBCP、C3P0。

    DBCP

    也是一个开源的连接池,是Apache Common成员之一,在企业开发中也比较常见,tomcat内置的连接池。
    commons-dbcp1.4.jar commons-pool-1.5.6.jar

    public class JDBCUtils {
        public static final String DRIVER = "com.mysql.jdbc.Driver";
        public static final String URL = "jdbc:mysql://localhost:3306/daydb";
        public static final String USERNAME = "root";
        public static final String PASSWORD = "root";
        /*
         * 创建连接池BasicDataSource
         */
        public static BasicDataSource dataSource = new BasicDataSource();
        //静态代码块
        static {
            //对连接池对象 进行基本的配置
            dataSource.setDriverClassName(DRIVER); // 这是要连接的数据库的驱动
            dataSource.setUrl(URL); //指定要连接的数据库地址
            dataSource.setUsername(USERNAME); //指定要连接数据的用户名
            dataSource.setPassword(PASSWORD); //指定要连接数据的密码
        }
        /*
         * 返回连接池对象
         */
        public static DataSource getDataSource(){
            return dataSource;
        }
    }
    dbcp的JDBCUtils
    /*
     * 演示使用DBUtils工具  完成数据库表的增加操作
     */
    public class Demo {
        // 插入功能 
        @Test
        public void insert(){
            try {
                //获取一个用来执行SQL语句的对象   QueryRunner
                QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "INSERT INTO zhangwu(name,money,parent) VALUES(?,?,?)";
                Object[] params = {"股票收入", 5500, "收入"};    
                 int line = qr.update(sql,params);
                //结果集处理
                System.out.println("line = " + line);
                
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        
        //删除功能
        @Test
        public void delete(){
            try {
                //创建一个QueryRunner对象,用来完成SQL语句的执行
                QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                //执行SQL语句
                String sql = "DELETE FROM zhangwu WHERE name = ?";
                Object[] params = {"股票收入"};
                int line = qr.update(sql, params);
                //结果集的处理
                System.out.println("line="+line);
                
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        
        //更新功能
        @Test
        public void update(){
            try {
                //创建一个QueryRunner对象,用来完成SQL语句的执行
                QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                //执行SQL语句
                String sql = "UPDATE zhangwu SET money = money+1000 WHERE name=?";
                Object[] params = {"股票收入"};
                int line = qr.update(sql, params);
                //结果集的处理
                System.out.println("line="+line);
                
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        
        //查询功能,将结果集中第一条记录封装到一个指定的javaBean中。
        @Test
        public void search(){
            try{
                //获取QueryRunner 
                QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                //执行SQL语句
                String sql = "SELECT * FROM zhangwu";
                Object[] params = {};
                Product p = qr.query(sql, new BeanHandler<Product>(Product.class), params);
                //结果集处理
                System.out.println(p);
                
            } catch(SQLException e){
                throw new RuntimeException(e);
            }
        }
    }
    Demo

    DBCP的BasicDataSource类常见配置项:

    分类

    属性

    描述

    必须项

    driverClassName

    数据库驱动名称

    url

    数据库的地址

    username

    用户名

    password

    密码

    基本项(扩展)

    maxActive

    最大连接数量

    minIdle

    最小空闲连接

    maxIdle

    最大空闲连接

    initialSize

    初始化连接

    必须项

    driverClassName

    数据库驱动名称

    url

    数据库的地址

    username

    用户名

    password

    密码

    基本项

    maxActive

    最大连接数量

    initialSize

    连接池中初始化多少个Connection连接对象

    扩展项

    maxWait

    超时等待时间以毫秒为单位 1000等于1

    参考文档:http://commons.apache.org/proper/commons-dbcp/configuration.html

    C3P0

    c3p0-config.xml 文件中定义所有的连接信息。采用xml配置文件的方式, 程序会自动寻找配置文件。xml 的文件名固定为 3p0-config.xml 文件在 classpath 路径下,即 src 下, 就是类的加载路径。

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <default-config>
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/数据库名</property>
            <property name="user">root</property>
            <property name="password">asd</property>
        </default-config>
    
        <named-config name="mysql">
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/数据库名</property>
            <property name="user">root</property>
            <property name="password">asd</property>
        </named-config>
    
        <named-config name="oracle">
            ……
        </named-config>
    </c3p0-config>
    3p0-config.xml的基本配置

    如果只有<default-config>则这样初始化数据源:
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    如果初始化指定名称的数据源如mysql, 则这样:
    ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import javax.sql.DataSource;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    /**
     * JDBC的工具类:
     * @author admin
     *
     */
    public class JDBCUtils2 {
        // 默认去类路径下去找 c3p0-config.xml
        private static final ComboPooledDataSource DATA_SOURCE =new ComboPooledDataSource();
        /**
         * 获得连接的方法
         */
        public static Connection getConnection(){
            Connection conn = null;
            try {
                conn = DATA_SOURCE.getConnection();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return conn;
        }
        
        public static DataSource getDataSource(){
            return DATA_SOURCE;
        }
        
        /**
         * 释放资源的方法
         */
        public static void release(ResultSet rs,Statement stmt,Connection conn){
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 垃圾回收尽快回收对象.
                rs = null;
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 垃圾回收尽快回收对象.
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 垃圾回收尽快回收对象.
                conn = null;
            }
        }
        
        public static void release(Statement stmt,Connection conn){
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 垃圾回收尽快回收对象.
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 垃圾回收尽快回收对象.
                conn = null;
            }
        }
    }
    c3p0的JDBCUtils

    c3p0的连接方式除了xml配置还有,set方法设置,和properties配置两种。

    直接用set方法设置参数, 基本方法

    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
    dataSource.setUser("root");
    dataSource.setPassword("asd");

    调用的时候只需要在QueryRunner的构造方法里引用dataSource(以dbutils为例), 就像这样:
    QueryRunner qr = new QueryRunner(dataSource);

    当然也可以用dataSource获取一个连接, 像这样:
    Connection conn = dataSource.getConnection();

    然后查询的时候调用QueryRunner的无参构造函数, 像这样:
    QueryRunner qr = new QueryRunner();

    然后在调用查询方法时, 传入连接对象就可以了, 像这样:
    User user = qr.query(conn, sql, new BeanHandler<User>(User.class));

    采用.porperties属性文件的方式

    固定文件名:c3p0.properties。文件在classpath路径下,即src下, 就是类的加载路径。

    里面的配置如下
    c3p0.driverClass=com.mysql.jdbc.Driver
    c3p0.jdbcUrl=jdbc:mysql://localhost:3306/数据库名
    c3p0.user=root
    c3p0.password=asd

    初始化数据源:
    ComboPooledDataSource dataSource = new ComboPooledDataSource();

  • 相关阅读:
    美团容器平台架构及容器技术实践
    【人物志】美团首席科学家夏华夏:不断突破边界的程序人生
    Category 特性在 iOS 组件化中的应用与管控
    浅谈大型互联网企业入侵检测及防护策略
    【基本功】深入剖析Swift性能优化
    CAT 3.0 开源发布,支持多语言客户端及多项性能提升
    安装window下的redis,redis可视化管理工具(Redis Desktop Manager)安装,基础使用,实例化项目
    .Net Core Redis的使用
    焦点IT Redis安装与配置( Windows10 或Windows server)
    用VScode配置Python开发环境
  • 原文地址:https://www.cnblogs.com/boomoom/p/10328625.html
Copyright © 2020-2023  润新知