JDBC【數(shù)據(jù)庫(kù)連接池没龙、DbUtils框架铺厨、分頁(yè)】

1.數(shù)據(jù)庫(kù)連接池

什么是數(shù)據(jù)庫(kù)連接池

簡(jiǎn)單來(lái)說(shuō):數(shù)據(jù)庫(kù)連接池就是提供連接的。硬纤。解滓。

為什么我們要使用數(shù)據(jù)庫(kù)連接池

  • 數(shù)據(jù)庫(kù)的連接的建立和關(guān)閉是非常消耗資源的
  • 頻繁地打開(kāi)、關(guān)閉連接造成系統(tǒng)性能低下

編寫(xiě)連接池

  1. 編寫(xiě)連接池需實(shí)現(xiàn)java.sql.DataSource接口
  2. 創(chuàng)建批量的Connection用LinkedList保存【既然是個(gè)池筝家,當(dāng)然用集合保存洼裤、、LinkedList底層是鏈表溪王,對(duì)增刪性能較好】
  3. 實(shí)現(xiàn)getConnetion()腮鞍,讓getConnection()每次調(diào)用值骇,都是在LinkedList中取一個(gè)Connection返回給用戶
  4. 調(diào)用Connection.close()方法,Connction返回給LinkedList

    private static LinkedList<Connection> list = new LinkedList<>();

    //獲取連接只需要一次就夠了缕减,所以用static代碼塊
    static {
        //讀取文件配置
        InputStream inputStream = Demo1.class.getClassLoader().getResourceAsStream("db.properties");

        Properties properties = new Properties();
        try {
            properties.load(inputStream);
            String url = properties.getProperty("url");
            String username = properties.getProperty("username");
            String driver = properties.getProperty("driver");
            String password = properties.getProperty("password");

            //加載驅(qū)動(dòng)
            Class.forName(driver);

            //獲取多個(gè)連接雷客,保存在LinkedList集合中
            for (int i = 0; i < 10; i++) {
                Connection connection = DriverManager.getConnection(url, username, password);
                list.add(connection);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    //重寫(xiě)Connection方法,用戶獲取連接應(yīng)該從LinkedList中給他
    @Override
    public Connection getConnection() throws SQLException {
        System.out.println(list.size());
        System.out.println(list);

       //先判斷LinkedList是否存在連接
       return list.size() > 0 ? list.removeFirst() : null; 
    }

我們已經(jīng)完成前三步了桥狡,現(xiàn)在問(wèn)題來(lái)了搅裙。我們調(diào)用Conncetion.close()方法,是把數(shù)據(jù)庫(kù)的物理連接關(guān)掉裹芝,而不是返回給LinkedList的

解決思路:

  1. 寫(xiě)一個(gè)Connection子類(lèi)部逮,覆蓋close()方法
  2. 寫(xiě)一個(gè)Connection包裝類(lèi),增強(qiáng)close()方法
  3. 用動(dòng)態(tài)代理嫂易,返回一個(gè)代理對(duì)象出去兄朋,攔截close()方法的調(diào)用,對(duì)close()增強(qiáng)

分析第一個(gè)思路:

  • Connection是通過(guò)數(shù)據(jù)庫(kù)驅(qū)動(dòng)加載的怜械,保存了數(shù)據(jù)的信息颅和。寫(xiě)一個(gè)子類(lèi)Connection,new出對(duì)象缕允,子類(lèi)的Connction無(wú)法直接繼承父類(lèi)的數(shù)據(jù)信息峡扩,也就是說(shuō)子類(lèi)的Connection是無(wú)法連接數(shù)據(jù)庫(kù)的,更別談覆蓋close()方法了障本。

分析第二個(gè)思路:

  • 寫(xiě)一個(gè)Connection包裝類(lèi)教届。
    1. 寫(xiě)一個(gè)類(lèi),實(shí)現(xiàn)與被增強(qiáng)對(duì)象的相同接口【Connection接口】
    2. 定義一個(gè)變量驾霜,指向被增強(qiáng)的對(duì)象
    3. 定義構(gòu)造方法案训,接收被增強(qiáng)對(duì)象
    4. 覆蓋想增強(qiáng)的方法
    5. 對(duì)于不想增強(qiáng)的方法,直接調(diào)用被增強(qiáng)對(duì)象的方法
  • 這個(gè)思路本身是沒(méi)什么毛病的粪糙,就是實(shí)現(xiàn)接口時(shí)强霎,方法太多了!蓉冈,所以我們也不使用此方法

分析第三個(gè)思路代碼實(shí)現(xiàn):


    @Override
    public Connection getConnection() throws SQLException {

        if (list.size() > 0) {
            final Connection connection = list.removeFirst();

            //看看池的大小
            System.out.println(list.size());

            //返回一個(gè)動(dòng)態(tài)代理對(duì)象
            return (Connection) Proxy.newProxyInstance(Demo1.class.getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() {

                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                    //如果不是調(diào)用close方法城舞,就按照正常的來(lái)調(diào)用
                    if (!method.getName().equals("close")) {
                        method.invoke(connection, args);
                    } else {

                        //進(jìn)到這里來(lái),說(shuō)明調(diào)用的是close方法
                        list.add(connection);

                        //再看看池的大小
                        System.out.println(list.size());

                    }
                    return null;
                }

            });
        }
        return null;
    }


我們上面已經(jīng)能夠簡(jiǎn)單編寫(xiě)一個(gè)線程池了洒擦。下面我們來(lái)使用一下開(kāi)源數(shù)據(jù)庫(kù)連接池

DBCP

使用DBCP數(shù)據(jù)源的步驟:

  1. 導(dǎo)入兩個(gè)jar包【Commons-dbcp.jar和Commons-pool.jar】
  2. 讀取配置文件
  3. 獲取BasicDataSourceFactory對(duì)象
  4. 創(chuàng)建DataSource對(duì)象

    private static DataSource dataSource = null;

    static {
        try {
            //讀取配置文件
            InputStream inputStream = Demo3.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(inputStream);

            //獲取工廠對(duì)象
            BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory();
            dataSource = basicDataSourceFactory.createDataSource(properties);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();

    }

    //這里釋放資源不是把數(shù)據(jù)庫(kù)的物理連接釋放了椿争,是把連接歸還給連接池【連接池的Connection內(nèi)部自己做好了】
    public static void release(Connection conn, Statement st, ResultSet rs) {

        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (st != null) {
            try {
                st.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

C3P0

C3P0數(shù)據(jù)源的性能更勝一籌,并且它可以使用XML配置文件配置信息熟嫩!

步驟:

  1. 導(dǎo)入開(kāi)發(fā)包【c3p0-0.9.2-pre1.jar】和【mchange-commons-0.2.jar】
  2. 導(dǎo)入XML配置文件【可以在程序中自己一個(gè)一個(gè)配秦踪,C3P0的doc中的Configuration有XML文件的事例】
  3. new出ComboPooledDataSource對(duì)象

    private static ComboPooledDataSource comboPooledDataSource = null;

    static {
        //如果我什么都不指定,就是使用XML默認(rèn)的配置,這里我指定的是oracle的
        comboPooledDataSource = new ComboPooledDataSource("oracle");
    }

    public static Connection getConnection() throws SQLException {
        return comboPooledDataSource.getConnection();
    }

Tomcat數(shù)據(jù)源

Tomcat服務(wù)器也給我們提供了連接池椅邓,內(nèi)部其實(shí)就是DBCP

步驟:

  1. 在META-INF目錄下配置context.xml文件【文件內(nèi)容可以在tomcat默認(rèn)頁(yè)面的 JNDI Resources下Configure Tomcat's Resource Factory找到】
  2. 導(dǎo)入Mysql或oracle開(kāi)發(fā)包到tomcat的lib目錄下
  3. 初始化JNDI->獲取JNDI容器->檢索以XXX為名字在JNDI容器存放的連接池

context.xml文件的配置:


<Context>

  <Resource name="jdbc/EmployeeDB"
            auth="Container"
            type="javax.sql.DataSource"

            username="root"
            password="root"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/zhongfucheng"
            maxActive="8"
            maxIdle="4"/>
</Context>

        try {

            //初始化JNDI容器
            Context initCtx = new InitialContext();

            //獲取到JNDI容器
            Context envCtx = (Context) initCtx.lookup("java:comp/env");

            //掃描以jdbc/EmployeeDB名字綁定在JNDI容器下的連接池
            DataSource ds = (DataSource)
                    envCtx.lookup("jdbc/EmployeeDB");

            Connection conn = ds.getConnection();
            System.out.println(conn);

        } 


使用dbutils框架

dbutils它是對(duì)JDBC的簡(jiǎn)單封裝柠逞,極大簡(jiǎn)化jdbc編碼的工作量

DbUtils類(lèi)

提供了關(guān)閉連接,裝載JDBC驅(qū)動(dòng)景馁,回滾提交事務(wù)等方法的工具類(lèi)【比較少使用板壮,因?yàn)槲覀儗W(xué)了連接池,就應(yīng)該使用連接池連接數(shù)據(jù)庫(kù)】

QueryRunner類(lèi)

該類(lèi)簡(jiǎn)化了SQL查詢合住,配合ResultSetHandler使用绰精,可以完成大部分的數(shù)據(jù)庫(kù)操作,重載了許多的查詢透葛,更新笨使,批處理方法。大大減少了代碼量

ResultSetHandler接口

該接口規(guī)范了對(duì)ResultSet的操作僚害,要對(duì)結(jié)果集進(jìn)行什么操作硫椰,傳入ResultSetHandler接口的實(shí)現(xiàn)類(lèi)即可。

  • ArrayHandler:把結(jié)果集中的第一行數(shù)據(jù)轉(zhuǎn)成對(duì)象數(shù)組萨蚕。
  • ArrayListHandler:把結(jié)果集中的每一行數(shù)據(jù)都轉(zhuǎn)成一個(gè)數(shù)組靶草,再存放到List中。
  • BeanHandler:將結(jié)果集中的第一行數(shù)據(jù)封裝到一個(gè)對(duì)應(yīng)的JavaBean實(shí)例中岳遥。
  • BeanListHandler:將結(jié)果集中的每一行數(shù)據(jù)都封裝到一個(gè)對(duì)應(yīng)的JavaBean實(shí)例中奕翔,存放到List里。
  • ColumnListHandler:將結(jié)果集中某一列的數(shù)據(jù)存放到List中寒随。
  • KeyedHandler(name):將結(jié)果集中的每一行數(shù)據(jù)都封裝到一個(gè)Map里糠悯,再把這些map再存到一個(gè)map里帮坚,其key為指定的key妻往。
  • MapHandler:將結(jié)果集中的第一行數(shù)據(jù)封裝到一個(gè)Map里,key是列名试和,value就是對(duì)應(yīng)的值讯泣。
  • MapListHandler:將結(jié)果集中的每一行數(shù)據(jù)都封裝到一個(gè)Map里,然后再存放到List
  • ScalarHandler 將ResultSet的一個(gè)列到一個(gè)對(duì)象中阅悍。

使用DbUtils框架對(duì)數(shù)據(jù)庫(kù)的CRUD


/*
* 使用DbUtils框架對(duì)數(shù)據(jù)庫(kù)的CRUD
* 批處理
*
* */
public class Test {

    @org.junit.Test
    public void add() throws SQLException {

        //創(chuàng)建出QueryRunner對(duì)象
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "INSERT INTO student (id,name) VALUES(?,?)";

        //我們發(fā)現(xiàn)query()方法有的需要傳入Connection對(duì)象好渠,有的不需要傳入
        //區(qū)別:你傳入Connection對(duì)象是需要你來(lái)銷(xiāo)毀該Connection,你不傳入节视,由程序幫你把Connection放回到連接池中
        queryRunner.update(sql, new Object[]{"100", "zhongfucheng"});

    }

    @org.junit.Test
    public void query()throws SQLException {

        //創(chuàng)建出QueryRunner對(duì)象
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "SELECT * FROM student";

        List list = (List) queryRunner.query(sql, new BeanListHandler(Student.class));
        System.out.println(list.size());

    }

    @org.junit.Test
    public void delete() throws SQLException {
        //創(chuàng)建出QueryRunner對(duì)象
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "DELETE FROM student WHERE id='100'";

        queryRunner.update(sql);
    }

    @org.junit.Test
    public void update() throws SQLException {
        //創(chuàng)建出QueryRunner對(duì)象
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "UPDATE student SET name=? WHERE id=?";

        queryRunner.update(sql, new Object[]{"zhongfuchengaaa", 1});
    }

    @org.junit.Test
    public void batch() throws SQLException {
        //創(chuàng)建出QueryRunner對(duì)象
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "INSERT INTO student (name,id) VALUES(?,?)";

        Object[][] objects = new Object[10][];
        for (int i = 0; i < 10; i++) {
            objects[i] = new Object[]{"aaa", i + 300};
        }
        queryRunner.batch(sql, objects);
    }

}

分頁(yè)

分頁(yè)技術(shù)是非常常見(jiàn)的拳锚,在搜索引擎下搜索頁(yè)面,不可能把全部數(shù)據(jù)都顯示在一個(gè)頁(yè)面里邊寻行。所以我們用到了分頁(yè)技術(shù)霍掺。

Oracle實(shí)現(xiàn)分頁(yè)


    /*
      Oracle分頁(yè)語(yǔ)法:
        @lineSize---每頁(yè)顯示數(shù)據(jù)行數(shù)
        @currentPage----當(dāng)前所在頁(yè)

    */
    SELECT *FROM (
        SELECT 列名,列名,ROWNUM rn
        FROM 表名
        WHERE ROWNUM<=(currentPage*lineSize)) temp

    WHERE temp.rn>(currentPage-1)*lineSize;

Oracle分頁(yè)原理簡(jiǎn)單解釋


    /*
      Oracle分頁(yè):
        Oracle的分頁(yè)依賴于ROWNUM這個(gè)偽列,ROWNUM主要作用就是產(chǎn)生行號(hào)。

      分頁(yè)原理:
        1:子查詢查出前n行數(shù)據(jù)杆烁,ROWNUM產(chǎn)生前N行的行號(hào)
        2:使用子查詢產(chǎn)生ROWNUM的行號(hào)牙丽,通過(guò)外部的篩選出想要的數(shù)據(jù)

      例子:
        我現(xiàn)在規(guī)定每頁(yè)顯示5行數(shù)據(jù)【lineSize=5】,我要查詢第2頁(yè)的數(shù)據(jù)【currentPage=2】
        注:【對(duì)照著語(yǔ)法來(lái)看】

      實(shí)現(xiàn):
        1:子查詢查出前10條數(shù)據(jù)【ROWNUM<=10】
        2:外部篩選出后面5條數(shù)據(jù)【ROWNUM>5】
        3:這樣我們就取到了后面5條的數(shù)據(jù)
    */

Mysql實(shí)現(xiàn)分頁(yè)


    /*
      Mysql分頁(yè)語(yǔ)法:
      @start---偏移量兔魂,不設(shè)置就是從0開(kāi)始【也就是(currentPage-1)*lineSize】
      @length---長(zhǎng)度烤芦,取多少行數(shù)據(jù)

    */
    SELECT *
    FROM 表名
    LIMIT [START], length;

    /*
      例子:
        我現(xiàn)在規(guī)定每頁(yè)顯示5行數(shù)據(jù),我要查詢第2頁(yè)的數(shù)據(jù)

      分析:
        1:第2頁(yè)的數(shù)據(jù)其實(shí)就是從第6條數(shù)據(jù)開(kāi)始析校,取5條

      實(shí)現(xiàn):
        1:start為5【偏移量從0開(kāi)始】
        2:length為5

*/

總結(jié):

  • Mysql從(currentPage-1)*lineSize開(kāi)始取數(shù)據(jù)构罗,取lineSize條數(shù)據(jù)
  • Oracle先獲取currentPagelineSize條數(shù)據(jù),從(currentPage-1)lineSize開(kāi)始取數(shù)據(jù)

使用JDBC連接數(shù)據(jù)庫(kù)實(shí)現(xiàn)分頁(yè)

下面是常見(jiàn)的分頁(yè)圖片

image

配合圖片智玻,看下我們的需求是什么:

  1. 算出有多少頁(yè)的數(shù)據(jù)绰播,顯示在頁(yè)面上
  2. 根據(jù)頁(yè)碼,從數(shù)據(jù)庫(kù)顯示相對(duì)應(yīng)的數(shù)據(jù)尚困。

分析:

  1. 算出有多少頁(yè)數(shù)據(jù)這是非常簡(jiǎn)單的【在數(shù)據(jù)庫(kù)中查詢有多少條記錄蠢箩,你每頁(yè)顯示多少條記錄,就可以算出有多少頁(yè)數(shù)據(jù)了】
  2. 使用Mysql或Oracle的分頁(yè)語(yǔ)法即可

通過(guò)上面分析事甜,我們會(huì)發(fā)現(xiàn)需要用到4個(gè)變量

  • currentPage--當(dāng)前頁(yè)【由用戶決定的】
  • totalRecord--總數(shù)據(jù)數(shù)【查詢表可知】
  • lineSize--每頁(yè)顯示數(shù)據(jù)的數(shù)量【由我們開(kāi)發(fā)人員決定】
  • pageCount--頁(yè)數(shù)【totalRecord和lineSize決定】

        //每頁(yè)顯示3條數(shù)據(jù)
        int lineSize = 3;

        //總記錄數(shù)
        int totalRecord = getTotalRecord();

        //假設(shè)用戶指定的是第2頁(yè)
        int currentPage = 2;

        //一共有多少頁(yè)
        int pageCount = getPageCount(totalRecord, lineSize);

        //使用什么數(shù)據(jù)庫(kù)進(jìn)行分頁(yè)谬泌,記得要在JdbcUtils中改配置
        List<Person> list = getPageData2(currentPage, lineSize);
        for (Person person : list) {
            System.out.println(person);
        }

    }

    //使用JDBC連接Mysql數(shù)據(jù)庫(kù)實(shí)現(xiàn)分頁(yè)
    public static List<Person> getPageData(int currentPage, int lineSize) throws SQLException {

        //從哪個(gè)位置開(kāi)始取數(shù)據(jù)
        int start = (currentPage - 1) * lineSize;

        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "SELECT name,address  FROM person LIMIT ?,?";

        List<Person> persons = (List<Person>) queryRunner.query(sql, new BeanListHandler(Person.class), new Object[]{start, lineSize});
        return persons;

    }

    //使用JDBC連接Oracle數(shù)據(jù)庫(kù)實(shí)現(xiàn)分頁(yè)
    public static List<Person> getPageData2(int currentPage, int lineSize) throws SQLException {

        //從哪個(gè)位置開(kāi)始取數(shù)據(jù)
        int start = (currentPage - 1) * lineSize;

        //讀取前N條數(shù)據(jù)
        int end = currentPage * lineSize;

        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "SELECT " +
                "  name, " +
                "  address " +
                "FROM ( " +
                "  SELECT " +
                "    name, " +
                "    address , " +
                "    ROWNUM rn " +
                "  FROM person " +
                "  WHERE ROWNUM <= ? " +
                ")temp WHERE temp.rn>?";

        List<Person> persons = (List<Person>) queryRunner.query(sql, new BeanListHandler(Person.class), new Object[]{end, start});
        return persons;

    }

    public static int getPageCount(int totalRecord, int lineSize) {

        //簡(jiǎn)單算法
        //return (totalRecord - 1) / lineSize + 1;

        //此算法比較好理解,把數(shù)據(jù)代代進(jìn)去就知道了逻谦。
        return totalRecord % lineSize == 0 ? (totalRecord / lineSize) : (totalRecord / lineSize) + 1;

    }

    public static int  getTotalRecord() throws SQLException {

        //使用DbUtils框架查詢數(shù)據(jù)庫(kù)表中有多少條數(shù)據(jù)
        QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "SELECT COUNT(*) FROM person";

        Object o = queryRunner.query(sql, new ScalarHandler());

        String ss = o.toString();
        int  s = Integer.parseInt(ss);
        return s;
    }


如果文章有錯(cuò)的地方歡迎指正掌实,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué)邦马,可以關(guān)注微信公眾號(hào):Java3y贱鼻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市滋将,隨后出現(xiàn)的幾起案子邻悬,更是在濱河造成了極大的恐慌,老刑警劉巖随闽,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件父丰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掘宪,警方通過(guò)查閱死者的電腦和手機(jī)蛾扇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)魏滚,“玉大人镀首,你說(shuō)我怎么就攤上這事∈蟠危” “怎么了更哄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵靖秩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我竖瘾,道長(zhǎng)沟突,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任捕传,我火速辦了婚禮惠拭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庸论。我一直安慰自己职辅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布聂示。 她就那樣靜靜地躺著域携,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鱼喉。 梳的紋絲不亂的頭發(fā)上秀鞭,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音扛禽,去河邊找鬼锋边。 笑死,一個(gè)胖子當(dāng)著我的面吹牛编曼,可吹牛的內(nèi)容都是我干的豆巨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼掐场,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼往扔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起熊户,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤萍膛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后敏弃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卦羡,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡噪馏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年麦到,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欠肾。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓶颠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刺桃,到底是詐尸還是另有隱情粹淋,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站桃移,受9級(jí)特大地震影響屋匕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜借杰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一过吻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蔗衡,春花似錦纤虽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至济蝉,卻和暖如春杰刽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背王滤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工专缠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淑仆。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓涝婉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蔗怠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子墩弯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 本文包括傳統(tǒng)JDBC的缺點(diǎn)連接池原理自定義連接池開(kāi)源數(shù)據(jù)庫(kù)連接池DBCP連接池C3P0連接池Tomcat內(nèi)置連接池...
    廖少少閱讀 16,730評(píng)論 0 37
  • JDBC概述 在Java中,數(shù)據(jù)庫(kù)存取技術(shù)可分為如下幾類(lèi):JDBC直接訪問(wèn)數(shù)據(jù)庫(kù)寞射、JDO技術(shù)渔工、第三方O/R工具,如...
    usopp閱讀 3,533評(píng)論 3 75
  • JDBC Java 數(shù)據(jù)庫(kù)連接(Java Database Connectivity桥温,簡(jiǎn)稱JDBC)是 Java ...
    狗子渣渣閱讀 1,942評(píng)論 0 10
  • DriverManager的實(shí)現(xiàn)方式一般是在主程序中建立數(shù)據(jù)庫(kù)的連接引矩,然后進(jìn)行數(shù)據(jù)庫(kù)的操作,操作完畢后斷開(kāi)數(shù)據(jù)庫(kù)連...
    怪蜀黍Zzzzlw閱讀 2,035評(píng)論 0 9
  • 剛剛出門(mén)辦了事情回來(lái)~然后拼車(chē)的師傅說(shuō)他女兒在實(shí)習(xí)侵浸,已經(jīng)放假了旺韭。。掏觉。你怎么還回公司区端。。澳腹。 那不是因?yàn)橹巍Q詈巍!N伊ち凇NJ!?..
    Jennifer愛(ài)生活閱讀 390評(píng)論 0 3