zoukankan      html  css  js  c++  java
  • JDBC02

    JDBC重构设计:
    重构:就是通过调整程序代码,改善软件的质量,性能,使其程序的设计模式和框架更加合理
    1.在书写Dao.Impl包下类时候每个方法中是不是都写了驱动名称/数据库连接路径/用户名和密码
    更换任意一个值,非常麻烦
    解决:将当前数据提取出来,做一个封装,分装成一个成员变量 方便修改
    2.在书写Dao.Impl包下类时候每个方法中是不是都写了加载驱动/获取连接对象
    每个方法都写了会出现重复
    解决:提供一个方法专门用来提供加载驱动和获取连接对象的操作
    static --> 做工具类 封装出一个工具类 ,提供加载驱动和连接对象方法
    JDBCUtil工具类 --.提供一些连接数据库的基本属性,提供一个连接方法
    3.JDBCUtil中getConn这个方法中有一句话Class.forname-->只要调用方法就会加载这句话
    既然Class.forname每次都要加载,可以在创建JDBCUtil类的时候就提供加载完成
    Class.forname提供到static代码块中
    4. 在书写Dao.Impl包下类时候每个方法中是不是都写了释放资源
    连接对象,执行语句对象 结果集对象
    提取出来做一个封装就是是释放前资源对象
    第一版本重构

    5.JDBCUtil中虽然提供了一些属性这些属性是连接数据库的基本属性
    只要是修改这些属性,那么就需要找到这个类JDBCUtil
    可以将当前连接数据的属性值写成一个资源文件db.properties 提供连接数据库的属性
    第二版重构

    6.在书写Dao.Impl包下类时候每个方法中都使用SQL语句,但是是静态SQL直接将SQL语句完全写完,即不方便也不便捷,
    提供预编译语言对象
    执行SQL语句的时候Statement接口 -->对象 --> 用于执行静态SQL
    对数据库操作也提供一种预编译语句
    PreparedStatement表示预编译的 SQL 语句的对象。
    在写SQL语句式,所有传递参数的位置都使用 ? 作为占位符存在
    通过当前接口下setXXX(位置符号,实际传入的值)
    如何看?是哪个位置 --> ? 是从1开始依次类推
    例如:"UPDATE EMPLOYEESSET SALARY = ? WHERE ID = ?"
    从左向后开始 第一个 ? 就即使第1位,依次类推
    pstmt.setBigDecimal(1, 153833.00)
    pstmt.setInt(2, 110592)
    ps:XXX-->对应的是数据类型 -->如何知道数据类型 数据库表中类的数据类型对应

    执行操作方法不变参考父类接口中Statement
    executeQuery() --> 查询 executeUpdate()---> 插入,删除 更新

    
    

    *******db.properties

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/db1
    username=root
    password=123456

    /**
    *
    */
    package com.qfedu.Day28_JDBC2.domain;

    /**
    * Description: domain包存储的都是描述类 <br/>
    * Copyright (c) , 2018, JK <br/>
    * This program is protected by copyright laws. <br/>
    * Program Name:Student.java <br/>
    *
    * @author 千锋智哥
    * @version : 1.0
    */
    //这个类的设计原则是根据表来完成的 ,表中提供哪些列,那么就需要在这个类中描述出来
    public class Student {
    private String name;
    private Integer age;
    private Long id;
    public Student(String name, Integer age, Long id) {
    super();
    this.name = name;
    this.age = age;
    this.id = id;
    }
    public Student() {
    super();
    // TODO Auto-generated constructor stub
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    public Long getId() {
    return id;
    }
    public void setId(Long id) {
    this.id = id;
    }
    @Override
    public String toString() {
    return "Student [name=" + name + ", age=" + age + ", id=" + id + "]"+" ";
    }

    }

    
    

    /**
    *
    */
    package com.qfedu.Day28_JDBC2.dao;

    
    

    import java.util.List;

    
    

    import com.qfedu.Day28_JDBC2.domain.Student;

    
    

    /**
    * Description: 定义对数据库中的数据访问方法<br/>
    * Copyright (c) , 2018, JK <br/>
    * This program is protected by copyright laws. <br/>
    * Program Name:IStudentDAO.java <br/>
    *
    * @author 千锋智哥
    * @version : 1.0
    */
    public interface IStudentDAO {
    /**
    * 将学生对象保存到数据库中
    * @param student 需要保存的学生对象
    */
    void save(Student student);
    /**
    * 删除指定学生对象
    * @param id 被删除学生对象在数据库中的主键
    */
    void delete(int id);
    /**
    * 修改指定id学生对象的信息
    * @param id 学生对象在数据库中主键
    * @param student 新的学生对象
    */

    void update(int id,Student student);

    /**
    *查询所有学生对象
    *@return 获取所有学生对象信息并存储到集合中
    */
    List<Student> list();

    /**
    * 通过指定id查出对应的学生
    * @param id 指定id
    * @return 如果存在返回该id对应的学生对象,不存在就返回null
    */

    Student get(int id);

    }

    /**
    *
    */
    package com.qfedu.Day28_JDBC2.PerparedStatement;

    import static org.junit.Assert.*;

    import java.sql.*;

    import org.junit.Test;

    /**
    * Description: 测试预编译语句<br/>
    * Copyright (c) , 2018, JK <br/>
    * This program is protected by copyright laws. <br/>
    * Program Name:PSTest.java <br/>
    *
    * @author 千锋智哥
    * @version : 1.0
    */
    public class PSTest {

    @Test
    public void testSaveByPerparedStatement()throws Exception {
    String sql = "insert into t_student(name,age)values(?,?)";
    //加载驱动获取连接对象
    Class.forName("com.mysql.jdbc.Driver");
    //获取连接对象
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "123456");
    //获取执行预编译语句对象,参数需要传入sql语句

    PreparedStatement ps = conn.prepareStatement(sql);
    //给当前SQL语句中? 占位的位置赋予实际的值
    //第一个?的位置是1 依次类推 从左向右 赋值的数据类型需要和数据库中表的数据类型一致
    //当前的步骤只是给SQL语句赋值,并没有执行
    ps.setString(1, "B哥");
    ps.setInt(2, 35);
    //执行SQL 预编译对象的执行语句 一定没有参数 千万不要传递
    int rows = ps.executeUpdate();
    if(rows > 0) {
    System.out.println("插入成功");
    }

    ps.close();
    conn.close();

    }

    }

    /**
    *
    */
    package com.qfedu.Day28_JDBC2.dao.Impl;

    
    

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;

    
    

    import com.qfedu.Day28_JDBC2.dao.IStudentDAO;
    import com.qfedu.Day28_JDBC2.domain.Student;

    
    

    /**
    * Description: 就是对整个业务的实现逻辑CRUD<br/>
    * Copyright (c) , 2018, JK <br/>
    * This program is protected by copyright laws. <br/>
    * Program Name:StudentDAOImpl.java <br/>
    *
    * @author 千锋智哥
    * @version : 1.0
    */
    public class StudentDAOImpl implements IStudentDAO {

    
    

    /*
    * 插入 插入数据
    */
    @Override
    public void save(Student student) {
    String sql = "insert into t_student(name,age)values(?,?)";
    Connection conn = null;
    PreparedStatement ps = null;
    try {
    conn = JDBCUtil.getConn();
    //获取预编译对象
    ps = conn.prepareStatement(sql);
    //赋值
    ps.setString(1, student.getName());
    ps.setInt(2, student.getAge());
    //执行SQL 不要有参数
    int rows = ps.executeUpdate();

    if (rows == 1) {
    System.out.println("插入成功");
    }

    
    

    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    JDBCUtil.close(conn, ps, null);
    }

    
    

    }

    
    

    /*
    * 删除
    */
    @Override
    public void delete(int id) {
    String sql = "delete from t_student where id = ?";
    Connection conn = null;
    PreparedStatement ps = null;
    try {
    conn = JDBCUtil.getConn();
    ps = conn.prepareStatement(sql);
    ps.setInt(1, id);
    int rows = ps.executeUpdate();
    if (rows == 1) {
    System.out.println("删除成功");
    }

    
    

    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    JDBCUtil.close(conn, ps, null);
    }

    
    

    }

    
    

    /*
    * 更新
    */
    @Override
    public void update(int id, Student student) {
    String sql = "update t_Student set name = ?,age = ? where id = ?";
    Connection conn = null;
    PreparedStatement ps = null;
    try {
    conn = JDBCUtil.getConn();
    ps = conn.prepareStatement(sql);
    ps.setString(1, student.getName());
    ps.setInt(2, student.getAge());
    ps.setLong(3, id);
    int rows = ps.executeUpdate();
    if (rows == 1) {
    System.out.println("更新成功");
    }

    
    

    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    JDBCUtil.close(conn, ps, null);
    }

    
    

    }

    
    

    /*
    * 查询
    */

    
    

    @Override
    public List<Student> list() {
    // SQL语句
    String sql = "select * from t_student";
    // 创建一个集合对象 用来存储 查询结果
    List<Student> list = new ArrayList<>();
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {

    
    

    conn = JDBCUtil.getConn();
    ps = conn.prepareStatement(sql);
    rs = ps.executeQuery();

    
    

    while (rs.next()) {
    Student stu = new Student();
    // 因为数据库表中的列所对应的值是是可以出现null
    // 这里在做描述类的时候,建议将数据类型使用包装类这样既可以兼容null也可以兼容基本类型
    stu.setId(rs.getLong("id"));
    stu.setName(rs.getString("name"));
    stu.setAge(rs.getInt("age"));
    list.add(stu);
    }

    
    

    if (list.size() != 0) {
    return list;

    
    

    }

    
    

    } catch (Exception e) {

    
    

    e.printStackTrace();
    } finally {
    JDBCUtil.close(conn, ps, rs);

    
    

    }

    
    

    return null;
    }

    
    

    /*
    * 单独查询
    */
    @Override
    public Student get(int id) {
    String sql = "select * from t_student where id= ?";
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {

    
    

    conn = JDBCUtil.getConn();
    ps = conn.prepareStatement(sql);
    ps.setLong(1, id);
    rs = ps.executeQuery();


    // 将结果集中的对象取出来
    while (rs.next()) {
    Student stu = new Student();
    stu.setId(rs.getLong("id"));
    stu.setName(rs.getString("name"));
    stu.setAge(rs.getInt("age"));
    return stu;
    }

    
    

    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    JDBCUtil.close(conn, ps, rs);
    }

    
    

    // 没有渠道值就是空对象
    return null;

    
    

    }

    
    

    public static void main(String[] args) {
    List<Student> list = new StudentDAOImpl().list();
    System.out.println(list);
    }

    
    

    }

    /**
    *
    */
    package com.qfedu.Day28_JDBC2.DBCP;

    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Properties;

    import javax.sql.DataSource;

    import org.apache.commons.dbcp.BasicDataSourceFactory;


    import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil;

    /**
    * Description: <br/>
    * Copyright (c) , 2018, JK <br/>
    * This program is protected by copyright laws. <br/>
    * Program Name:BDCPDemo.java <br/>
    *
    * @author 千锋智哥
    * @version : 1.0
    */
    class DBCPUtil{
    //1.先创建连接池对象
    private static DataSource ds;
    //DBCP不能像C3P0一样自动获取资源
    static {
    try {
    Properties p = new Properties();
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    InputStream in = loader.getResourceAsStream("dbcp.properties");
    //加载文件
    p.load(in);
    //DBCP对象 --> 工厂模式 -->Spring推荐 --> 底层就是工厂模式和注解
    ds = BasicDataSourceFactory.createDataSource(p);
    }catch(Exception e) {
    e.printStackTrace();
    }

    }

    public static Connection getConnection() {
    try {
    return ds.getConnection();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    throw new RuntimeException("连接异常");
    }





    }

    public class DBCPDemo {

    public static void main(String[] args)throws Exception {
    /*
    * 正常使用DBCP创建对象
    * BasicDataSource ds = new BasicDataSource();
    * ds.setDriver/url/username/password
    *
    *
    */


    String sql = "select * from product";
    Connection conn = DBCPUtil.getConnection();
    //剩余操作和JDBC是一样的
    PreparedStatement ps = conn.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();
    while(rs.next()) {
    String name = rs.getString("productName");
    double price = rs.getDouble("salePrice");
    System.out.println(name + " "+ price);

    }
    //可以不用释放 池会管理
    //建议直接释放
    JDBCUtil.close(conn, ps, rs);

    }

    }




    预编译语句和静态语句的区别
    PerparedStatement的优点:
    1.预编译语句的代码的可读性和可维护性好(SQL模板中使用?占位符表示参数)
    2.预编译语句能最大好处的提高性能(预编译)
    需要注意的是MySQL中是不支持预编译语句的性能优化的而Oracle是支持的而写数据非常快
    ps:预编译的意思其实就是提前先编译好,然后在执行
    3.预编译语句可以保证安全(SQL注入-->PHP写到网站)
    而Statemet语句繁琐需要先创建完还需要进行拼接 所以建议使用预编译的形式来完成SQL语句

    最后简要给大家分析一下预编译语句在数据库端的过程
    通过Java app 将数据库查询语句发送给数据库,数据库做如下操作:
    1.安全性能分析
    2.语法分析
    3.语法编译
    4.选择并执行一条对于当前计划
    5.针对于某一些数据库服务器,会存在一个预编译池 (字符串池)
    在池中会先判断当前发送到DB的SQL是否已经存在在预编译池中了
    若存在,则直接执行第4步
    若不存在,就执行1-2-3-4-5再把该SQL存到预编译池中
    重构第三版

    为什么要使用连接池:
    为什么必须要使用数据库连接池
    普通的JDBC数据连接(Connection对象)使用DriverManager来获取,每次想数据库建立连接的时候都需要将
    Connection对象加载内存中,然后在验证用户和密码(需要花费0.05~1s的时间)
    建立很多Connection连接 开销成本就会非常大
    需要数据连接的时候就会想数据要求一个连接请求,然后执行玩完成后在断开连接,这样的方式也会造成跟大的开销
    需要一种可以即可以面对多人次的访问,又可以自动断开连接的技术 --> 数据库连接池


    在java中连接池使用 javax.sql.DataSource接口来表示连接池和数据源


    ps: javax --> 增强包
    ps:DataSource和JDBC一样仅仅是一个接口.由各大服务厂商来实现
    Connection接收数据库连接池对象
    常量的DataSource:
    C3p0: Hibernate推荐,该连接池在07年之后就不在更新
    ps:相对来来说老一点项目都在使用C3p0 不太推荐了:性能不太好
    DBCP: Apache组织的项目 Spring推荐的, 真的不错
    Druid: 阿里巴巴的项目(德鲁伊) 比较好的

    使用连接池和不使用连接池区别?
    没有连接池通过DriverManager来获对象直接连接DB
    连接池之后:直接通过连接池对象来获连接对象
    Connection conn = DataSource对象.getConnection();
    没有连接池的时候当前连接对象.close来释放资源
    有了建连接池可以通过吃来进行对对象资源释放的管理

    下面这些连接池都需要JDBC驱动

    C3p0使用方式:
    1.将当前C3p0所支持的jar包复制到工程下
    2.通过build path --> add build path 加载到工程
    3.简单的演示了C3P0连接
    4.提供两种配置C3P0资源文件
    需要注意C3P0的配置文件名字是固定不能变
    c3p0-config.xml c3p0.properties
    4.1使用xml作为资源文件加载
    c3p0会自动检测是否存在c3p0-config.xml,若存在自动加载,创建对象即可
    4.2使用c3p0.properties作为资源文件

    *****c3p0-config.xml

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

    <!--checkoutTimeout
    配置当连接池所有连接用完时应用程序getConnection的等待时间。为0则无限等待直至有其他连接释放
    或者创建新的连接,不为0则当时间到的时候如果仍没有获得连接,则会抛出SQLException。
    initialPoolSize
    连接池初始化时创建的连接数
    maxIdleTime
    连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接
    如果为0,则永远不会断开连接
    maxPoolSize
    连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待
    其他连接释放,所以这个值有可能会设计地很大
    minPoolSize
    连接池保持的最小连接数
    maxStatements
    连接池为数据源缓存的PreparedStatement的总数。由于PreparedStatement属于单个Connection,所以
    这个数量应该根据应用中平均连接数乘以每个连接的平均PreparedStatement来计算。为0的时候不缓存
    -->
    <property name="checkoutTimeout">30000</property>
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
    <property name="maxStatements">200</property>

    </default-config>
    </c3p0-config>

    *****c3p0.properties

    c3p0.jdbcUrl=jdbc:mysql://localhost:3306/db1
    c3p0.driverClass=com.mysql.jdbc.Driver
    c3p0.user=root
    c3p0.password=123456

    
    

    c3p0.checkoutTimeout=30000
    c3p0.initialPoolSize=10
    c3p0.maxIdleTime=30
    c3p0.maxPoolSize=100
    c3p0.maxStatements=200
    c3p0.minPoolSize=10
    >


    /**
    * */ package com.qfedu.Day28_JDBC2.C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: C3P0连接<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:C3P0Demo.java <br/> * * @author 千锋智哥 * @version : 1.0 */ public class C3P0Demo { //资料中会有c3p0的官方文档 //提供一个静态方法 public static DataSource getDataSource()throws Exception{ //创建连接池对象 ComboPooledDataSource ds = new ComboPooledDataSource(); //告诉连接池如何可以进行数据库的连接 ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql://localhost:3306/db1"); ds.setUser("root"); ds.setPassword("123456"); return ds; } public static void main(String[] args) throws Exception { String sql = "select * from product"; //此时拿到的对象就是连接池中出现的Connection对象 Connection conn = getDataSource().getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } } /** * */ package com.qfedu.Day28_JDBC2.C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: XML来进行C3P0使用<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:C3P0DemoXML.java <br/> * * @author 千锋智哥 * @version : 1.0 */ class C3P0Util{ //XML配置文件 //1.创建连接池对象 private static ComboPooledDataSource ds = new ComboPooledDataSource(); public static Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } throw new RuntimeException("数据库连接异常"); } } public class C3P0DemoXML { /** * @param args */ public static void main(String[] args) throws Exception{ String sql = "select * from product"; Connection conn = C3P0Util.getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } } /** * */ package com.qfedu.Day28_JDBC2.C3P0; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.EmptyStackException; import javax.sql.DataSource; import com.mchange.v2.c3p0.DataSources; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: Properties文件连接C3P0<br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:C3P0DemoProperties.java <br/> * * @author 千锋智哥 * @version : 1.0 */ class C3P0Utils{ //连接池对象 private static DataSource ds; static { try { //加载池对象并且获取Properties文件 DataSource dss = DataSources.unpooledDataSource(); //通过对象构建具体DataSource ds = DataSources.pooledDataSource(dss); } catch (SQLException e) { throw new RuntimeException("连接异常"); } } public static Connection getConnection()throws Exception{ return ds.getConnection(); } } public class C3P0DemoProperties { public static void main(String[] args)throws Exception { String sql = "select * from product"; //此时拿到的对象就是连接池中出现的Connection对象 Connection conn = C3P0Utils.getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } }



    DBCP连接池:
    1.将DBCP所支持的jar复制到当前工程下
    2.通过build path --> add build path 加载到工程
    3.演示连接
    4.直接使用配置文件的形式来进行连接,但是不支持XML

    **********dbcp.properties
    url=jdbc:mysql://localhost:3306/db1 driverClass=com.mysql.jdbc.Driver username=root password=123456 maxActive=20 /** * */ package com.qfedu.Day28_JDBC2.DBCP; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil; /** * Description: <br/> * Copyright (c) , 2018, JK <br/> * This program is protected by copyright laws. <br/> * Program Name:BDCPDemo.java <br/> * * @author 千锋智哥 * @version : 1.0 */ class DBCPUtil{ //1.先创建连接池对象 private static DataSource ds; //DBCP不能像C3P0一样自动获取资源 static { try { Properties p = new Properties(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream in = loader.getResourceAsStream("dbcp.properties"); //加载文件 p.load(in); //DBCP对象 --> 工厂模式 -->Spring推荐 --> 底层就是工厂模式和注解 ds = BasicDataSourceFactory.createDataSource(p); }catch(Exception e) { e.printStackTrace(); } } public static Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } throw new RuntimeException("连接异常"); } } public class DBCPDemo { public static void main(String[] args)throws Exception { /* * 正常使用DBCP创建对象 * BasicDataSource ds = new BasicDataSource(); * ds.setDriver/url/username/password * * */ String sql = "select * from product"; Connection conn = DBCPUtil.getConnection(); //剩余操作和JDBC是一样的 PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { String name = rs.getString("productName"); double price = rs.getDouble("salePrice"); System.out.println(name + " "+ price); } //可以不用释放 池会管理 //建议直接释放 JDBCUtil.close(conn, ps, rs); } }


    Druid连接池:
    Druid连接池和DBCP是一样的,jar包到工程
    通过build path --> add build path 加载到工程
    配置文件也和DBCP一样
    创建对象方式 不一样

    *****druid.properties
    url=jdbc:mysql://localhost:3306/db1
    driverClass=com.mysql.jdbc.Driver
    username=root
    password=123456
    maxActive=20
    /**
     * 
     */
    package com.qfedu.Day28_JDBC2.Druid;
    
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import com.qfedu.Day28_JDBC2.dao.Impl.JDBCUtil;
    
    /**
     * Description: druid连接池<br/>
     * Copyright (c) , 2018, JK <br/>
     * This program is protected by copyright laws. <br/>
     * Program Name:DruidDemo.java <br/>
     * 
     * @author 千锋智哥
     * @version : 1.0
     */
    class DruidUtil{
        //1.先创建连接池对象
        private static  DataSource ds;
        //DBCP不能像C3P0一样自动获取资源
        static {
            try {
              Properties p = new Properties();
              ClassLoader loader = Thread.currentThread().getContextClassLoader();
              InputStream in = loader.getResourceAsStream("druid.properties");
             //加载文件
              p.load(in);
              //创建对象
             ds = DruidDataSourceFactory.createDataSource(p);
             
            }catch(Exception e) {
                e.printStackTrace();
            }
            
        }
        
          public static Connection getConnection() {
              try {
                return ds.getConnection();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
              throw new  RuntimeException("连接异常");
          }
        
        
    }
    
    public class DruidDemo {
    
        public static void main(String[] args)throws Exception {
             String sql = "select * from product";
             Connection conn = DruidUtil.getConnection();
             //剩余操作和JDBC是一样的
               PreparedStatement ps = conn.prepareStatement(sql);
               ResultSet rs =   ps.executeQuery();
               while(rs.next()) {
                   String  name = rs.getString("productName");
                   double  price = rs.getDouble("salePrice");
                   System.out.println(name + " "+ price);
               
               }
               //可以不用释放 池会管理
               //建议直接释放
               JDBCUtil.close(conn, ps, rs);
        }
    
    }


  • 相关阅读:
    cookie操作
    css加载动画...
    三目运算符的运用
    遍历对象长度
    2年
    相亲

    股市周期
    功利心
    思考笔记
  • 原文地址:https://www.cnblogs.com/lijun199309/p/9664382.html
Copyright © 2011-2022 走看看