JDBC详解之与mySQL数据库的连接和基本操作一

JDBC详解


一 JDBC基本操作

MySQL的JDBC驱动包: mysql-connector-java-5.1.38-bin.jar

  • mysql-connector-java-5.1.38-bin.jar
    是MySQL的JDBC驱动包,用JDBC连接MySQL数据库时必须使用该jar包。
  • maven
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
  • 1 加载驱动
  • 2 获得连接
  • 3 基本操作,执行SQL语句
  • 4 遍历结果集
  • 5 释放资源

代码如下

        //1 加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2 获得连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/han","root","123");
        //3 基本操作,执行SQL
        //3.1 获得执行SQL语句的对象
        Statement createStatement = conn.createStatement();
        //3.2 编写SQL语句
        String sql = "select * from orderitem";
        //3.3 执行SQL
        ResultSet resultSet = createStatement.executeQuery(sql);
        //3.4 遍历结果集
        while(resultSet.next()){
            System.out.println(resultSet.getInt("id"));
            System.out.println(resultSet.getString("product"));
            System.out.println(resultSet.getDouble("price"));
        }
        //4. 释放资源
        resultSet.close();
        createStatement.close();
        conn.close();
    }

对象详解:

  • DriverManager:驱动管理类

    • 作用 1 : 注册驱动. 实际开发中一般不会使用,它会导致驱动注册两次
    • 作用 2 : 获得连接
    • getConnection: 用来获得与数据库连接的方法:这个方法中有三个参数:
               url         :与数据库连接的路径
               user            :与数据库连接的用户名
               password        :与数据库连接的密码
    
    • 主要关注的是url的写法:
    jdbc:mysql://localhost:3306/web_test3
               jdbc        :连接数据库的协议
               mysql       :是jdbc的子协议
               localhost   :连接的MySQL数据库服务器的主机地址。(连接是本机就可以写成localhost),如果连接不是本机的,就需要写上连接主机的IP地址。
               3306        :MySQL数据库服务器的端口号
               web_test3   :数据库名称
            url如果连接的是本机的路径,可以简化为如下格式:
            jdbc:mysql:///web_test3
    
    • connection : 数据库连接对象

      • 作用 1 创建执行SQL语句的对象
      • 作用 2 管理事务
    • statement ; 执行SQL

      • 执行SQL
      • 批处理
    • ResultSet :结果集
      • 通过SQL语句查询的结果

JDBC的增删改查就不多说了,都是最基本的东西
我们来看一下工具类的抽取和配置文件的设置

    -

工具类

public class JDBCUtils {

    private static final String driverClassName;
    private static final String url;
    private static final String username;
    private static final String password;

    // 静态代码块,随着类的加载二加载
    static {
        // 获取属性文件中的内容
        Properties pro = new Properties();

        try {
            pro.load(new FileInputStream("src/db.properties"));

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        driverClassName = pro.getProperty("driverClassName");
        url = pro.getProperty("url");
        username = pro.getProperty("username");
        password = pro.getProperty("password");
    }

    /**
     * 注册驱动
     * @throws ClassNotFoundException 
     */
    public static void loadDriver() throws ClassNotFoundException{

        Class.forName(driverClassName);

    }

    /**
     * 获得连接
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException{

        return DriverManager.getConnection(url,username,password);

    }

    /**
     * 释放资源的方法
     */
    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;
        }
    }
    /**
     * 释放资源
     * @param rs
     * @param stmt
     * @param conn
     */
    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;
        }
    }

}   

配置文件 db.properties :

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/han
username=root
password=123

二 c3p0连接池

连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。

为什么要使用连接池:

连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。

这里我们使用c3p0连接池 :

c3p0是一个开源的JDBC连接池.它实现了数据源和JNDI的绑定,支持JDBC3规范和JDBC2的标准扩展.

c3p0 需要引入的jar包:

c3p0-0.9.1.2.jar

  • maven
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>

使用连接池查询数据:

public class C3p0Demo1 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            //1 创建池
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            //2 设置连接数据库的参数
            dataSource.setDriverClass("com.mysql.jdbc.Driver");
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/han");
            dataSource.setUser("root");
            dataSource.setPassword("123");
            //3 获得连接
            conn = dataSource.getConnection();
            //4 编写SQL
            String sql = "select * from orderitem";
            //5 预编译sql
            ps = conn.prepareStatement(sql);
            //6 执行sql
            rs = ps.executeQuery();

            while(rs.next()){
                System.out.println(rs.getInt("id"));
                System.out.println(rs.getString("product"));
                System.out.println(rs.getDouble("price"));
            }
            //4. 释放资源
            JDBCUtils.release(rs, ps, conn);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

c3p0的配置文件c3p0-config.xml

c3p0可以使用出c3p0-config.xml文件配置,也可以使用 .properties文件配置
创建连接池时默认去类的路径下查找一个名字叫 c3p0-config.xml 的文件.

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///han</property>
        <property name="user">root</property>
        <property name="password">123</property>

        <!-- 默认初始化的连接数量,往连接池放5个连接-->
        <property name="initialPoolSize">5</property>
        <!--连接的最少数量-->
        <property name="minPoolSize">5</property>
        <!--连接的最大数量-->
        <property name="maxPoolSize">20</property>
    </default-config> 

    <!-- This app is massive! -->
<!--    <named-config name="oracle">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///han</property>
        <property name="user">root</property>
        <property name="password">123</property>
    </named-config> -->
</c3p0-config>
  • 连接池对象应该是一个应用只创建一次就可以的,不需要每次使用都创建一个新的连接池。所以我们要改写工具类:
public class JDBCUtils2 {
    //获得连接池
    private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();

    /**
     * 返回连接池
     */
    public static DataSource getDataSource(){

        return dataSource;
    }
    /**
     * 获得连接
     * @throws SQLException 
     */
    public static Connection getConnection() throws Exception{

        return dataSource.getConnection();
    }

    /**
     * 释放资源的方法
     */
    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;
        }
    }

    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;
        }
    }
}

三 JDBC的工具类库: DBUtils的概述

开源工具类库: 对JDBC的简单封装,而且没有影响性能。 因为JDBC手写比较麻烦,而且有非常多的代码是类似的。比如获得连接,预编译SQL,释放资源等..那么可以将这些代码抽取出来放到工具类中。将类似的代码进行抽取。大大简化JDBC的编程。

DBUtils需要使用的jar包:**

commons-dbutils-1.6.jar

maven

<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency>
    <groupId>commons-dbutils</groupId>
    <artifactId>commons-dbutils</artifactId>
    <version>1.6</version>
</dependency>

DBUtils的API详解:

  • QueryRunner对象:核心运行类
    • 在一般情况下如果执行CRUD的操作:
      • 构造:
        QueryRunner(DataSource ds);
      • 方法:
        int update(String sql,Object… args);
        T query(String sql,ResultSetHandler rsh,Object… args);
    • 如果有事务管理的话使用另一套完成CRUD的操作
      • 构造:
        QueryRunner();
      • 方法:
        int update(Connection conn,String sql,Object… args);
        T query(Connection conn,String sql,ResultSetHandler rsh,Object… args);

增删改:

导入jar包,配置出c3p0-config.xml, JDBCUtils2工具类
这里不需要手动的释放资源,DBUtils会自动的释放资源,则JDBCUtils2工具类中的释放资源的代码就可以删掉了.
这里只写一个插入数据:

    //插入数据
    public void insertProduct() throws SQLException{
        QueryRunner queryRunner = new QueryRunner(JDBCUtils2.getDataSource());
        queryRunner.update("insert into orderitem values (?,?,?)",null,"电视","45.2");
    }

查询

创建JavaBean :Student 类
处理结果集接口 ResultSetHandler 的实现类:

  • BeanHandler : 将一条记录封装到javaBean中去 行 (常用)
        @Test
        public void demo1() throws SQLException{
            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
            Student student = qr.query(" select * from user where id = ?",new BeanHandler<Student>(Student.class),2 );
            System.out.println(student);
        }
  • BeanListHandler : 将多条记录封装到装有javaBean的List集合中去 行(常用)
                @Test
                /**
                 * 一条记录就是一个Java对象(javaBean),如果多条记录,则将多个对象装到List集合中去.
                 * @throws SQLException
                 */
                public void demo2() throws SQLException{
                    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                    List<Student> list = qr.query("select * from user ", new BeanListHandler<Student>(Student.class));
                    for (Student student : list) {
                        System.out.println(student);
                    }
                }
  • ArrayHandler : 将一条记录封装到一个Object数组中
                    @Test
                public void demo5() throws SQLException{
                    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                    Object[] obj = qr.query("select * from user where id = ?", new ArrayHandler(),3);
                    for (Object object : obj) {
                        System.out.println(object);
                    }
                }
  • ArrayListHandler :.将多条记录封装到一个装有Object数组的List集合中去.
        ScalarHandler : 将单个值封装.
                @Test
                public void demo3() throws SQLException{
                    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                    Object obj = qr.query("select count(*) from user", new ScalarHandler());
                    System.out.println(obj);
                }
  • ColumnListHandler() : 将一列(字段)的值封装到List集合中 ()可以传入参数,传入的是要封装的列.
                @Test
                public void demo4() throws SQLException{
                    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                    List<Object> list = qr.query("select nickname from user ", new ColumnListHandler());
                    for (Object obj : list) {
                        System.out.println(obj);
                    }
                }
  • MapHandler: 将一条记录封装到一个Map集合中,Map集合的key是列名(字段名) values是表中列的记录值 //结果 {id=1, username=小张, nickname=张三, age=12, password=123}

  • MapListHandler : 将多条记录封装到一个装有Map集合中的List集合中

                @Test
                public void demo6() throws SQLException{
                    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
                    List<Map<String,Object>> list = qr.query("select * from user", new MapListHandler());
                    for (Map<String, Object> map : list) {
                        System.out.println(map);
                    }    
                }

第一次写博客,如果有错误的地方指正

猜你喜欢

转载自blog.csdn.net/weixin_42430194/article/details/80650706