數(shù)據(jù)庫連接池以及ApacheCommonDBUtils工具類使用

連接池

  • 普通的數(shù)據(jù)庫連接在打開和關(guān)閉連接時(shí)比較損耗性能, 而且是和數(shù)據(jù)庫的直接交互, 連接池就是一個(gè)維護(hù)數(shù)據(jù)庫連接的管理員, 手中經(jīng)常有數(shù)據(jù)庫的連接, 當(dāng)需要連接的時(shí)候, 直接從管理員手中拿, 用完了之后還給管理員, 而且不需要直接和數(shù)據(jù)庫交互
  • 常見的連接池: Tomcat-dbcp, dbcp, c3p0, druid
  • 數(shù)據(jù)源(javax.sql.Datasource)包含了數(shù)據(jù)池, 數(shù)據(jù)源可以管理數(shù)據(jù)池
  • 以前需要Class.forName()加載驅(qū)動, 通過DriverManager.getConnection()直接從數(shù)據(jù)庫獲取連接; 而用連接池的核心就是: 將連接的指向改了, 現(xiàn)在指向的是數(shù)據(jù)源而不是數(shù)據(jù)庫
  • 數(shù)據(jù)庫訪問的核心 --> pstmt/stmt -> Connection -> 1. 直連數(shù)據(jù)庫 2. 數(shù)據(jù)源 (ds.getConnection())

Tomcat-dbcp: 不常用, 了解

  • 類似于 jndi, 在Context.xml中配置下面的MySQL Resource
  • Content.xml中MySQL的配置
    <Resource
        <!-- name指定Resource的JNID名字 -->
        name="jdbc/mysql"
        <!-- 指定Resource的管理者, 有兩個(gè)可選: Container和Applocation;Container:由容器來創(chuàng)建Resource; Application: 由Web應(yīng)用來創(chuàng)建和管理Resource -->
        auth="Container"
        <!-- type: 指定Resource的類型 -->
        type="javax.sql.DataSource"
        <!-- 指定連接池中, 處于活動狀態(tài)的數(shù)據(jù)庫連接的最大數(shù)量, 如果值為0, 標(biāo)識不受限制 -->
        maxActive="100"
        <!-- 指定連接池中, 處于空閑狀態(tài)的數(shù)據(jù)庫連接的最大數(shù)量, 如果值為0, 標(biāo)識不受限制  -->
        maxIdle="30"
        <!-- 指定連接池中,連接處于空閑狀態(tài)的最長時(shí)間(單位為毫秒), 如果超出此最長時(shí)間將會拋出異常; 如果值為-1, 表示允許無限制等待 -->
        maxWait="10000"
        <!-- 指定數(shù)據(jù)庫訪問名 -->
        username="root"
        <!-- 指定數(shù)據(jù)庫訪問密碼 -->
        password="password"
        <!-- 指定連接數(shù)據(jù)庫的驅(qū)動程序的類名 -->
        driverClassName="com.mysql.cj.jdbc.Driver"
        <!-- 指定連接數(shù)據(jù)庫的RUL -->
        url="jdbc:mysql://127.0.0.1:3306/blog?useSSL=false&amp;serverTimezone=UTC"
        />
  • 在項(xiàng)目里面的web.xml中指定context.xml里面配置的數(shù)據(jù)源; 就是指定name,type, auth三個(gè)屬性的值
  • 在DBUtils.java 中將之前通過DriverManager.getConnection(URL, NAME, PWD)獲取連接改為通過 Context ctx = new InitialContext();先獲取Context.xml; 再通過 DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/mysql");獲取DataSource對象, 再通過DataSource對象獲取連接 Connection conn = ds.getConnection();

dbcp 連接池

  • 需要引入jar包 commons-dbcp-1.4.jar, commons-pool.jar
  • 獲取ds的核心類(二選一): BasicDataSource , BasicDataSourceFactory

BasicDataSource類的方式(硬編碼方式)

  • 1.創(chuàng)建 BasicDataSource dbcp = new BasicDataSource();
  • 2.通過下面的常用方法設(shè)置各種屬性即可拿到 dbcp
  • 3.通過 dbcp.getConnrction()獲取數(shù)據(jù)庫連接即可

常用方法

  • void serDriverClassName(String driverClassName) : 設(shè)置連接數(shù)據(jù)庫的驅(qū)動名
  • void setUrl(String url) : 設(shè)置連接數(shù)據(jù)庫的URL
  • void setUsername(Stirng Username) : 設(shè)置連接數(shù)據(jù)庫的用戶名
  • void setPassword(Stirng Password) : 設(shè)置連接數(shù)據(jù)庫的木馬
  • void setInitialiSize(int initialSize) : 設(shè)置初始化時(shí), 連接數(shù)據(jù)池中的連接數(shù)量
  • void setMaxActive(int maxActive) : 設(shè)置連接池中, 處于活動狀態(tài)的數(shù)據(jù)庫連接最大數(shù)量
  • void setMinIdle(int minIdle) : 設(shè)置連接池中, 處于空閑狀態(tài)的數(shù)據(jù)庫連接的最小數(shù)量
  • Collection getConnection() : 從連接池中獲取一個(gè)數(shù)據(jù)庫連接

BasicDataSourceFactory 配置方式(dbcpconfig.properties配置文件; 全部是k=v)

  • 編寫dbcpconfig.properties配置文件(格式k=v中間不要由空格)
  • 通過創(chuàng)建 Properties 類的實(shí)例, 調(diào)用該實(shí)例的load()方法將配置文件加載進(jìn)來; 需要注意的是load()方法的參數(shù)是流的形式
    • 創(chuàng)建 Properties 實(shí)例: Properties props = new Properties();
    • 將字符串編程輸入流: InputStream input = new DBCPDemo().getClass().getClassLoader().getResourceAsStream("dbcpconfig.properties");
    • 調(diào)用load()方法: props.load(input);
  • 通過 DataSource dbcp = BasicDataSourceFactory.createDataSource(prop); 方法即可創(chuàng)建dbcp
  • dbcpconfig.properties 示例
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/blog?useSSL=false&serverTimezone=UTC
username=root
password=password
initialSize=10

C3P0 連接池

  • 核心類 ComboPooledDataSource
  • C3P0是將DBCP的兩種方式(硬編碼和配置文件)合二為一; 通過ComboPooledDataSource的構(gòu)造參數(shù)來區(qū)分, 無參數(shù)的就是硬編碼; 而有參數(shù)的就是通過配置文件的方式
  • 無參數(shù)構(gòu)造方法步驟:
    • 創(chuàng)建 ComboPooledDataSource c3p0 = new ComboPooledDataSource(); 對象
    • 通過 c3p0的set方法設(shè)置Driver,Url,User,Passwd等
    • return c3p0; 即可
    • 連接時(shí) 通過 c3p0.getConnection()即可
  • 有參數(shù)構(gòu)造方法, 配置文件(c3p0-config.xml)
    • 在IDE的src目錄中編寫c3p0-config.xml文件, 注意的點(diǎn): Url中出現(xiàn)分號(;)時(shí), 應(yīng)該使用(amp;)這種形式
    • 使用時(shí)直接 return new ComboPooledDataSource("jefxff"); 即可返回 c3p0
  • c3p0-config.xml 示例
    <?xml version="1.0" encoding="UTF-8" ?>
    <c3p0-config>
        <!-- 默認(rèn) -->
        <default-config>
            <!-- 如果要深究某個(gè)xml中可以設(shè)置那些屬性, 就找相關(guān)類的屬性, 或者setter()方法 -->
            <property name="user">root</property>
            <property name="password">password</property>
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/blog?useSSL=false&amp;serverTimezone=UTC</property>
            <property name="checkoutTimeout">30000</property>
        </default-config>

        <!-- 自定義 -->
        <named-config name="jefxff">
            <property name="user">root</property>
            <property name="password">password</property>
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/blog?useSSL=false&amp;serverTimezone=UTC</property>
            <property name="checkoutTimeout">20000</property>
        </named-config>
    </c3p0-config>

C3P0的核心類ComboPooledDataSource常用方法

  • public ComboPooledDataSource() : 無參構(gòu)造方法(硬編碼發(fā)方式)
  • public ComboPooledDataSource(String configName) : 加載配置文件的構(gòu)造方法
  • void setDriverClass(String driverClass) : 設(shè)置數(shù)據(jù)庫連接的驅(qū)動
  • void setJdbcUrl(String jdbcUrl) : 設(shè)置連接數(shù)據(jù)庫的URL
  • void setUser(Stirng User) : 設(shè)置數(shù)據(jù)庫連接的用戶名
  • void setPassword(String password) : 設(shè)置數(shù)據(jù)庫連接的密碼
  • void setMaxPoolSize(int maxPoolSize) : 設(shè)置連接池的最大連接數(shù)目
  • void setMinPoolSize(int minPoolSize) : 設(shè)置連接池的最小連接數(shù)目
  • void setInitiaPoolSize(int initiaPoolSize) : 設(shè)置初始化時(shí), 連接池中的連接數(shù)量
  • Connection getConnection() : 從連接池中獲取一個(gè)數(shù)據(jù)庫連接, 該方法由ComboPooledDataSource 的父類 AbstractPoolBackedDataSource提供

連接池總結(jié)

  • 硬編碼: 獲取某個(gè)連接池?cái)?shù)據(jù)源的對象 ds = new XxxDataSource(); ds.setXxx(); return ds;
  • 配置文件: 編寫配置文件, ds = new XxxDataSource(); 加載配置文件; return ds;

連接池代碼示例

package xyz.xmcs.DataSourceUtils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @author jefxff
 * @date 2020/3/11 - 16:17
 * DataSource 工具類, 可以通過該類獲取 Tomcat-dbcp , DBCP, C3P0 類型連接池的 DataSource,
 *      通過該 DataSource 即可創(chuàng)建數(shù)據(jù)庫的連接 Connection
 */
public class DataSourceUtils {

    /**
     * 此方法第一步: 需要配置tomcat目錄下的context.xml, 添加 <Resource 標(biāo)簽
     * 第二步: 需要在項(xiàng)目中的web.xml中配置 resource-ref 標(biāo)簽
     * @return
     * @throws NamingException
     */
    public static DataSource getTomcatDbcpBySet() throws NamingException {
        // 1. 相當(dāng)于獲取Context.xml
        Context ctx =  new InitialContext();
        // 2. 通過 lookup()方法去web.xml中找配置的<res-res-name字段的值,
        //      但是要注意 字段名字前面要添加 "java:comp/env/"
        return (DataSource) ctx.lookup("java:comp/env/jdbc/mysql");
    }

    /**
     * 1. 此方法需要兩個(gè)jar包: commons-dbcp-1.4.jar, commons-pool.jar
     * 2. 通過創(chuàng)建 BasicDataSource 的實(shí)例, 然后通過該實(shí)例調(diào)用setter方法通過硬編碼的方式,
     *      將Driver, url, name, pwd 等值通過setter方法指定
     * @return
     */
    public static DataSource getDbcpBySet(){

        BasicDataSource dbcp = new BasicDataSource();
        dbcp.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dbcp.setUrl("jdbc:mysql://localhost:3306/blog?useSSL=false&serverTimezone=UTC");
        dbcp.setUsername("root");
        dbcp.setPassword("password");
        dbcp.setInitialSize(20);
        dbcp.setMaxActive(10);
        return dbcp;
    }

    /**
     * 1. 此方法是通過編寫 dbcpconfig.properties 配置文件, 將Driver, url, name, pwd 參數(shù)通過K=V的方式
     *      寫在配置文件中
     * 2. 通過new DbcpUtils().getClass().getClassLoader().getResourceAsStream("配置文件"); 將配置文件加載為輸入流
     * 3. 通過 Properties實(shí)例.load(input)加載配置文件
     * 4. 再通過 BasicDataSourceFactory.createDataSource(properties); 來獲取DBCP對象
     * @return
     */
    public static DataSource getDbcpByProperties() throws Exception {
        Properties prop = new Properties();
        InputStream input=  new DataSourceUtils().getClass().getClassLoader().getResourceAsStream("dbcpconfig.properties");
        prop.load(input);
        return  BasicDataSourceFactory.createDataSource(prop);
    }

    /**
     * 1. 此方法需要兩個(gè)jar包, c3p0-0.9.5.2.jar, mchange-commons-java-0.2.11.jar
     * 2. 此方法是通過獲取 ComboPooledDataSource 的無參對象, 通過該對象的setter方法以硬編碼的方式指定Driver, url, name, pwd 等
     * @return
     */
    public static DataSource getC3p0BySet() throws PropertyVetoException {
        ComboPooledDataSource c3p0 = new ComboPooledDataSource();
        c3p0.setDriverClass("com.mysql.cj.jdbc.Driver");
        c3p0.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/blog?useSSL=false&serverTimezone=UTC");
        c3p0.setUser("root");
        c3p0.setPassword("password");
        return c3p0;
    }

    /**
     * 1. 此方法需要編寫 c3p0-config.xml文件, 指定default的配置, 以及自己的配置
     * 2. 在使用是通過創(chuàng)建有參數(shù)的 ComboPooledDatasource 對象, 參數(shù)中指定c3p0-config.xml配置的name屬性
     * @return
     */
    public static DataSource getC3p0ByXml(){
        return new ComboPooledDataSource("jefxff");
    }
}

Apache Commons DBUtils 工具類使用

Apache DButils

  • Apache DButils 是對Java JDBC的簡單封裝, 主要好處就是方便返回查詢的結(jié)果
  • 下載 commons-dbutils-1.7-bin.zip 文件并解壓, 主要使用 commons-dbutils-1.7.jar 文件, 包括幾個(gè)重點(diǎn)類: DbUtils, QueryRunner, ResultSetHandler
  • DbUtils: 打開關(guān)閉連接, 提交事務(wù)
  • 關(guān)鍵類 QueryRunner : 增刪改查方法的基礎(chǔ), 所有的增刪改查都必須創(chuàng)建該類的實(shí)例, 通過該類的實(shí)例來調(diào)用query或者update方法來執(zhí)行增刪改查; 其中該實(shí)例參數(shù)可以是一個(gè)DataSource實(shí)例, 又DS實(shí)例后是自動提交事務(wù)
    • updte() : 第一個(gè)參數(shù)是SQL語句, 第二個(gè)參數(shù)是Object[] 類型的數(shù)組的參數(shù); 有很多重載的方法
    • query() : 有很多重載的方法, 第一個(gè)參數(shù)是SQL語句, 第二個(gè)參數(shù)是ResultSetHandler接口的實(shí)現(xiàn)類, 不同的實(shí)現(xiàn)類代表返回不同的結(jié)果形式, 第三個(gè)參數(shù)是Object[] 類型的數(shù)組的參數(shù);
  • ResultSetHandler接口 : 有很多的實(shí)現(xiàn)類, 一個(gè)實(shí)現(xiàn)類對應(yīng)于一種不同 的查詢結(jié)果類型

通過 ResultSetHandler 接口的實(shí)現(xiàn)類來實(shí)現(xiàn)查詢

  • ArrayHandler實(shí)現(xiàn)類: 返回結(jié)果集中的第一行數(shù)據(jù), 并用Object[]接收
  • ArrayListhandler實(shí)現(xiàn)類: 返回結(jié)果集的多行數(shù)據(jù), 接收類型是 List<Obkect[]>
  • BeanHandler實(shí)現(xiàn)類: 返回結(jié)果集的第一行數(shù)據(jù), 并將結(jié)果集放在Bean里,即對象Student里面. (反射會通過無參構(gòu)造來創(chuàng)建對象)
  • BeanListHandler實(shí)現(xiàn)類: 返回結(jié)果集的多行數(shù)據(jù),接收類型為 List<Student>
  • BeanMapHandler實(shí)現(xiàn)列: 返回結(jié)果集的多行數(shù)據(jù), 接收類型為 Map<>(如果是Oracle數(shù)據(jù)庫, Java中對應(yīng)的Oracle默認(rèn)的數(shù)值類型 BigDecimal(數(shù)字通過 new BigDecimal(int) 方法轉(zhuǎn)換為BigDecimal))
  • MapHandler實(shí)現(xiàn)類: 返回一行以Map形式包裝的數(shù)據(jù)
  • MapListHandler實(shí)現(xiàn)類: 返回多行以List<\map>形式包裝的數(shù)據(jù)
  • KeyedHandler: 返回多行數(shù)據(jù), 并且給每個(gè)添加數(shù)據(jù)添加字段
  • ColumnListHandler : 把結(jié)果集的 某一列保存在List中
  • ScalarHandler: 查詢單值結(jié)果型

Apache DButils 代碼示例

package xyz.xmcs.Dao.Impl;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import xyz.xmcs.Dao.IArticlesDal;
import xyz.xmcs.Entity.Articles;
import xyz.xmcs.Utils.DataSourceUtils;
import java.sql.SQLException;
import java.util.List;

public class ArticlesDaoImpl implements IArticlesDal {
    // 創(chuàng)建QueryRunner對象, 參數(shù)傳入DataSource實(shí)例, 即以配置文件的方式創(chuàng)建的DataSource
    static QueryRunner runner = new QueryRunner(DataSourceUtils.getC3p0ByXml());

    // update的操作都是一樣的, 所以提取出來單獨(dú)作為一個(gè)方法處理
    private static boolean checkUpdate(String sql, Object[] params) {
        try {
            // 增刪改的方法通過 QueryRunner實(shí)例調(diào)用update()方法來執(zhí)行
            // 接受兩個(gè)參數(shù), 第一個(gè)參數(shù)是sql語句, 第二個(gè)參數(shù)是sql語句需要的參數(shù)
            int count = runner.update(sql, params);
            if(count > 0){
                return true;
            } else {
                return false;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean addArticles(Articles articles){
        String sql = "insert into articles values(?,?,?,?,?,?,?)";
        Object[] params = {articles.getId(),articles.getAuthor(),articles.getTitle(),articles.getContent(),
            articles.getCreatedate(),articles.getUser_id(),articles.getCategory_id()};
         return checkUpdate(sql, params);
    }

    

    @Override
    public boolean isExist(String title) {
        return queryArticlesByName(title)==null?false:true;
    }


    @Override
    public Articles queryArticlesById(int id) {
        String sql = "select * from articles where id = ?";
        Object[] params = {id};
        try {
            // 查詢的方法通過 QueryRunner實(shí)例調(diào)用query()方法來執(zhí)行
            // 第一個(gè)參數(shù)是sql語句, 第二個(gè)參數(shù)是ResultSetHandler實(shí)現(xiàn)類, 代表不同的返回值類型, 第三個(gè)參數(shù)是sql語句的參數(shù)
            Articles article = runner.query(sql, new BeanHandler<>(Articles.class), params);
            return article;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }


    @Override
    public List<Articles> queryAllArticles() {
        String sql = "select * from articles";
        try {
            // 查詢的方法通過 QueryRunner實(shí)例調(diào)用query()方法來執(zhí)行
            // 第一個(gè)參數(shù)是sql語句, 第二個(gè)參數(shù)是ResultSetHandler實(shí)現(xiàn)類, 代表不同的返回值類型, 第三個(gè)參數(shù)是sql語句的參數(shù)
            List<Articles> list = runner.query(sql, new BeanListHandler<>(Articles.class));
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public int getTotalArticlesCount() {
        String sql = "select count(1) from articles";
        try {
            // 查詢的方法通過 QueryRunner實(shí)例調(diào)用query()方法來執(zhí)行
            // 第一個(gè)參數(shù)是sql語句, 第二個(gè)參數(shù)是ResultSetHandler實(shí)現(xiàn)類, 代表不同的返回值類型
            // ScalarHandler 實(shí)現(xiàn)類代表的是返回單值性的查詢, 返回的類型是 long 類型的值
            long query = runner.query(sql, new ScalarHandler<>());
            return (int)query;
        } catch (SQLException e) {
            e.printStackTrace();
            return -1;
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汞舱,一起剝皮案震驚了整個(gè)濱河市膀斋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伯铣,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸟雏,死亡現(xiàn)場離奇詭異溯革,居然都是意外死亡节榜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門膨疏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來一睁,“玉大人,你說我怎么就攤上這事佃却≌哂酰” “怎么了啊终?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵病梢,是天一觀的道長。 經(jīng)常有香客問我谋右,道長灶泵,這世上最難降的妖魔是什么育八? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮赦邻,結(jié)果婚禮上髓棋,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好按声,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布膳犹。 她就那樣靜靜地躺著,像睡著了一般儒喊。 火紅的嫁衣襯著肌膚如雪镣奋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天怀愧,我揣著相機(jī)與錄音侨颈,去河邊找鬼。 笑死芯义,一個(gè)胖子當(dāng)著我的面吹牛哈垢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扛拨,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼耘分,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绑警?” 一聲冷哼從身側(cè)響起求泰,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎计盒,沒想到半個(gè)月后渴频,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡北启,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年卜朗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咕村。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡场钉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出懈涛,到底是詐尸還是另有隱情逛万,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布批钠,位于F島的核電站宇植,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏价匠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一呛每、第九天 我趴在偏房一處隱蔽的房頂上張望踩窖。 院中可真熱鬧,春花似錦晨横、人聲如沸洋腮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啥供。三九已至悯恍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伙狐,已是汗流浹背涮毫。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贷屎,地道東北人罢防。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像唉侄,于是被迫代替她去往敵國和親咒吐。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

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