JDBC【PreparedStatment狐树、批處理焙压、處理二進(jìn)制、自動(dòng)主鍵抑钟、調(diào)用存儲(chǔ)過(guò)程涯曲、函數(shù)】

1.PreparedStatement對(duì)象

PreparedStatement對(duì)象繼承Statement對(duì)象,它比Statement對(duì)象更強(qiáng)大在塔,使用起來(lái)更簡(jiǎn)單

  1. Statement對(duì)象編譯SQL語(yǔ)句時(shí)幻件,如果SQL語(yǔ)句有變量,就需要使用分隔符來(lái)隔開(kāi)蛔溃,如果變量非常多绰沥,就會(huì)使SQL變得非常復(fù)雜。PreparedStatement可以使用占位符贺待,簡(jiǎn)化sql的編寫
  2. Statement會(huì)頻繁編譯SQL徽曲。PreparedStatement可對(duì)SQL進(jìn)行預(yù)編譯,提高效率狠持,預(yù)編譯的SQL存儲(chǔ)在PreparedStatement對(duì)象中
  3. PreparedStatement防止SQL注入疟位。【Statement通過(guò)分隔符'++',編寫永等式喘垂,可以不需要密碼就進(jìn)入數(shù)據(jù)庫(kù)】

        //模擬查詢id為2的信息
        String id = "2";

        Connection connection = UtilsDemo.getConnection();

        String sql = "SELECT * FROM users WHERE id = ?";
        PreparedStatement preparedStatement = connection.preparedStatement(sql);

        //第一個(gè)參數(shù)表示第幾個(gè)占位符【也就是?號(hào)】甜刻,第二個(gè)參數(shù)表示值是多少
        preparedStatement.setString(1,id);

        ResultSet resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            System.out.println(resultSet.getString("name"));
        }

        //釋放資源
        UtilsDemo.release(connection, preparedStatement, resultSet);

2.批處理

當(dāng)需要向數(shù)據(jù)庫(kù)發(fā)送一批SQL語(yǔ)句執(zhí)行時(shí),應(yīng)避免向數(shù)據(jù)庫(kù)一條條發(fā)送執(zhí)行正勒,采用批處理以提升執(zhí)行效率

批處理有兩種方式:

  1. Statement
  2. PreparedStatement

通過(guò)executeBath()方法批量處理執(zhí)行SQL語(yǔ)句得院,返回一個(gè)int[]數(shù)組,該數(shù)組代表各句SQL的返回值

以下代碼是以Statement方式實(shí)現(xiàn)批處理


        /*
        * Statement執(zhí)行批處理
        *
        * 優(yōu)點(diǎn):
        *       可以向數(shù)據(jù)庫(kù)發(fā)送不同的SQL語(yǔ)句
        * 缺點(diǎn):
        *       SQL沒(méi)有預(yù)編譯
        *       僅參數(shù)不同的SQL章贞,需要重復(fù)寫多條SQL
        * */
        Connection connection = UtilsDemo.getConnection();

        Statement statement = connection.createStatement();
        String sql1 = "UPDATE users SET name='zhongfucheng' WHERE id='3'";
        String sql2 = "INSERT INTO users (id, name, password, email, birthday)" +
                " VALUES('5','nihao','123','ss@qq.com','1995-12-1')";

        //將sql添加到批處理
        statement.addBatch(sql1);
        statement.addBatch(sql2);

        //執(zhí)行批處理
        statement.executeBatch();

        //清空批處理的sql
        statement.clearBatch();

        UtilsDemo.release(connection, statement, null);

以下方式以PreparedStatement方式實(shí)現(xiàn)批處理


        /*
        * PreparedStatement批處理
        *   優(yōu)點(diǎn):
        *       SQL語(yǔ)句預(yù)編譯了
        *       對(duì)于同一種類型的SQL語(yǔ)句祥绞,不用編寫很多條
        *   缺點(diǎn):
        *       不能發(fā)送不同類型的SQL語(yǔ)句
        *
        * */
        Connection connection = UtilsDemo.getConnection();

        String sql = "INSERT INTO test(id,name) VALUES (?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        for (int i = 1; i <= 205; i++) {
            preparedStatement.setInt(1, i);
            preparedStatement.setString(2, (i + "zhongfucheng"));

            //添加到批處理中
            preparedStatement.addBatch();

            if (i %2 ==100) {

                //執(zhí)行批處理
                preparedStatement.executeBatch();

                //清空批處理【如果數(shù)據(jù)量太大,所有數(shù)據(jù)存入批處理,內(nèi)存肯定溢出】
                preparedStatement.clearBatch();
            }

        }
        //不是所有的%2==100蜕径,剩下的再執(zhí)行一次批處理
        preparedStatement.executeBatch();

        //再清空
        preparedStatement.clearBatch();

        UtilsDemo.release(connection, preparedStatement, null);


3.處理大文本和二進(jìn)制數(shù)據(jù)

clob和blob

  • clob用于存儲(chǔ)大文本
  • blob用于存儲(chǔ)二進(jìn)制數(shù)據(jù)

MYSQL

MySQL存儲(chǔ)大文本是用Test【代替clob】两踏,Test又分為4類

  • TINYTEXT
  • TEXT
  • MEDIUMTEXT
  • LONGTEXT

同理blob也有這4類


下面用JDBC連接MySQL數(shù)據(jù)庫(kù)去操作大文本數(shù)據(jù)和二進(jìn)制數(shù)據(jù)


/*
*用JDBC操作MySQL數(shù)據(jù)庫(kù)去操作大文本數(shù)據(jù)
*
*setCharacterStream(int parameterIndex,java.io.Reader reader,long length)
*第二個(gè)參數(shù)接收的是一個(gè)流對(duì)象,因?yàn)榇笪谋静粦?yīng)該用String來(lái)接收兜喻,String太大會(huì)導(dǎo)致內(nèi)存溢出
*第三個(gè)參數(shù)接收的是文件的大小
*
* */
public class Demo5 {

    @Test
    public void add() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();
            String sql = "INSERT INTO test2 (bigTest) VALUES(?) ";
            preparedStatement = connection.prepareStatement(sql);

            //獲取到文件的路徑
            String path = Demo5.class.getClassLoader().getResource("BigTest").getPath();
            File file = new File(path);
            FileReader fileReader = new FileReader(file);

            //第三個(gè)參數(shù)梦染,由于測(cè)試的Mysql版本過(guò)低,所以只能用int類型的朴皆。高版本的不需要進(jìn)行強(qiáng)轉(zhuǎn)
            preparedStatement.setCharacterStream(1, fileReader, (int) file.length());

            if (preparedStatement.executeUpdate() > 0) {
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }

    }

    /*
    * 讀取大文本數(shù)據(jù)帕识,通過(guò)ResultSet中的getCharacterStream()獲取流對(duì)象數(shù)據(jù)
    * 
    * */
    @Test
    public void read() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "SELECT * FROM test2";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {

                Reader reader = resultSet.getCharacterStream("bigTest");

                FileWriter fileWriter = new FileWriter("d:\\abc.txt");
                char[] chars = new char[1024];
                int len = 0;
                while ((len = reader.read(chars)) != -1) {
                    fileWriter.write(chars, 0, len);
                    fileWriter.flush();
                }
                fileWriter.close();
                reader.close();

            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, resultSet);
        }

    }



/*
* 使用JDBC連接MYsql數(shù)據(jù)庫(kù)操作二進(jìn)制數(shù)據(jù)
* 如果我們要用數(shù)據(jù)庫(kù)存儲(chǔ)一個(gè)大視頻的時(shí)候,數(shù)據(jù)庫(kù)是存儲(chǔ)不到的遂铡。
* 需要設(shè)置max_allowed_packet肮疗,一般我們不使用數(shù)據(jù)庫(kù)去存儲(chǔ)一個(gè)視頻
* */
public class Demo6 {

    @Test
    public void add() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();
            String sql = "INSERT INTO test3 (blobtest) VALUES(?)";
            preparedStatement = connection.prepareStatement(sql);

            //獲取文件的路徑和文件對(duì)象
            String path = Demo6.class.getClassLoader().getResource("1.wmv").getPath();
            File file = new File(path);

            //調(diào)用方法
            preparedStatement.setBinaryStream(1, new FileInputStream(path), (int)file.length());

            if (preparedStatement.executeUpdate() > 0) {

                System.out.println("添加成功");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }

    }

    @Test
    public void read() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();
            String sql = "SELECT * FROM test3";
            preparedStatement = connection.prepareStatement(sql);

            resultSet = preparedStatement.executeQuery();

            //如果讀取到數(shù)據(jù),就把數(shù)據(jù)寫到磁盤下
            if (resultSet.next()) {
                InputStream inputStream = resultSet.getBinaryStream("blobtest");
                FileOutputStream fileOutputStream = new FileOutputStream("d:\\aa.jpg");

                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {

                    fileOutputStream.write(bytes, 0, len);

                }
                fileOutputStream.close();
                inputStream.close();

            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }

    }

Oracle

下面用JDBC連接Oracle數(shù)據(jù)庫(kù)去操作大文本數(shù)據(jù)和二進(jìn)制數(shù)據(jù)


//使用JDBC連接Oracle數(shù)據(jù)庫(kù)操作二進(jìn)制數(shù)據(jù)

/*
* 對(duì)于Oracle數(shù)據(jù)庫(kù)和Mysql數(shù)據(jù)庫(kù)是有所不同的扒接。
* 1.Oracle定義了BLOB字段伪货,但是這個(gè)字段不是真正地存儲(chǔ)二進(jìn)制數(shù)據(jù)
* 2.向這個(gè)字段存一個(gè)BLOB指針,獲取到Oracle的BLOB對(duì)象,把二進(jìn)制數(shù)據(jù)放到這個(gè)指針里面,指針指向BLOB字段
* 3.需要事務(wù)支持
*
* */
public class Demo7 {
    @Test
    public void add() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = UtilsDemo.getConnection();

            //開(kāi)啟事務(wù)
            connection.setAutoCommit(false);

            //插入一個(gè)BLOB指針
            String sql = "insert into test4(id,image) values(?,empty_blob())";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);
            preparedStatement.executeUpdate();

            //把BLOB指針查詢出來(lái),得到BLOB對(duì)象
            String sql2 = "select image from test4 where id= ? for update";
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.setInt(1, 1);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                //得到Blob對(duì)象--當(dāng)成是Oracle的Blob,不是JDBC的,所以要強(qiáng)轉(zhuǎn)[導(dǎo)的是oracle.sql.BLOB包]
                BLOB  blob = (BLOB) resultSet.getBlob("image");

                //寫入二進(jìn)制數(shù)據(jù)
                OutputStream outputStream = blob.getBinaryOutputStream();

                //獲取到讀取文件讀入流
                InputStream inputStream = Demo7.class.getClassLoader().getResourceAsStream("01.jpg");

                int len=0;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {

                    outputStream.write(bytes, 0, len);
                }
                outputStream.close();
                inputStream.close();
                connection.setAutoCommit(true);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            UtilsDemo.release(connection, preparedStatement, null);
        }

    }

    @Test
    public void find() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = UtilsDemo.getConnection();
            String sql = "SELECT * FROM test4 WHERE id=1";

            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {

                //獲取到BLOB對(duì)象
                BLOB blob = (BLOB) resultSet.getBlob("image");

                //將數(shù)據(jù)讀取到磁盤上
                InputStream inputStream = blob.getBinaryStream();
                FileOutputStream fileOutputStream = new FileOutputStream("d:\\zhongfucheng.jpg");
                int len=0;
                byte[] bytes = new byte[1024];

                while ((len = inputStream.read(bytes)) > 0) {

                    fileOutputStream.write(bytes, 0, len);
                }

                inputStream.close();
                fileOutputStream.close();

            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            UtilsDemo.release(connection, preparedStatement, null);
        }
    }
}

對(duì)于JDBC連接Oracle數(shù)據(jù)庫(kù)操作CLOB數(shù)據(jù),我就不再重復(fù)了,操作跟BLOB幾乎相同


4.獲取數(shù)據(jù)庫(kù)的自動(dòng)主鍵列

為什么要獲取數(shù)據(jù)庫(kù)的自動(dòng)主鍵列數(shù)據(jù)?

應(yīng)用場(chǎng)景:

有一張老師表钾怔,一張學(xué)生表超歌。現(xiàn)在來(lái)了一個(gè)新的老師,學(xué)生要跟著新老師上課蒂教。

我首先要知道老師的id編號(hào)是多少,學(xué)生才能知道跟著哪個(gè)老師學(xué)習(xí)【學(xué)生外鍵參照老師主鍵】脆荷。



    @Test
    public void test() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();

            String sql = "INSERT INTO test(name) VALUES(?)";
            preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setString(1, "ouzicheng");

            if (preparedStatement.executeUpdate() > 0) {

                //獲取到自動(dòng)主鍵列的值
                resultSet = preparedStatement.getGeneratedKeys();

                if (resultSet.next()) {
                    int id = resultSet.getInt(1);
                    System.out.println(id);
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }


5.調(diào)用數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程

調(diào)用存儲(chǔ)過(guò)程的語(yǔ)法:


    {call <procedure-name>[(<arg1>,<arg2>, ...)]}

調(diào)用函數(shù)的語(yǔ)法:


    {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}

如果是Output類型的凝垛,那么在JDBC調(diào)用的時(shí)候是要注冊(cè)的。如下代碼所示:


/*
    jdbc調(diào)用存儲(chǔ)過(guò)程

    delimiter $$
        CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam varchar(255))
        BEGIN
            SELECT CONCAT('zyxw---', inputParam) into inOutParam;
        END $$
    delimiter ;
*/
//我們?cè)贘DBC調(diào)用存儲(chǔ)過(guò)程,就像在調(diào)用方法一樣
public class Demo9 {

    public static void main(String[] args) {
        Connection connection = null;
        CallableStatement callableStatement = null;

        try {
            connection = JdbcUtils.getConnection();

            callableStatement = connection.prepareCall("{call demoSp(?,?)}");

            callableStatement.setString(1, "nihaoa");

            //注冊(cè)第2個(gè)參數(shù),類型是VARCHAR
            callableStatement.registerOutParameter(2, Types.VARCHAR);
            callableStatement.execute();

            //獲取傳出參數(shù)[獲取存儲(chǔ)過(guò)程里的值]
            String result = callableStatement.getString(2);
            System.out.println(result);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
                callableStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

參考資料:


----------------------------------------------------------------------------------過(guò)程

#修改mysql語(yǔ)句的結(jié)果符為//
mysql > delimiter //

#定義一個(gè)過(guò)程蜓谋,獲取users表總記錄數(shù)梦皮,將10設(shè)置到變量count中
create procedure simpleproc(out count int)
begin
    select count(id) into count from users;
end
//

#修改mysql語(yǔ)句的結(jié)果符為;
mysql > delimiter ;

#調(diào)用過(guò)程,將結(jié)果覆給變量a桃焕,@是定義變量的符號(hào)
call simpleproc(@a);

#顯示變量a的值
select @a;

//以下是Java調(diào)用Mysql的過(guò)程
    String sql = "{call simpleproc(?)}";
    Connection conn = JdbcUtil.getConnection();
    CallableStatement cstmt = conn.prepareCall(sql);
    cstmt.registerOutParameter(1,Types.INTEGER);
    cstmt.execute();
    Integer count = cstmt.getInt(1);
    System.out.println("共有" + count + "人");

----------------------------------------------------------------------------------函數(shù)

#修改mysql語(yǔ)句的結(jié)果符為//
mysql > delimiter //

#定義一個(gè)函數(shù)剑肯,完成字符串拼接
create function hello( s char(20) ) returns char(50) 
return concat('hello,',s,'!');
//

#修改mysql語(yǔ)句的結(jié)果符為;
mysql > delimiter ;

#調(diào)用函數(shù)
select hello('world');

//以下是Java調(diào)用Mysql的函數(shù)
    String sql = "{? = call hello(?)}";
    Connection conn = JdbcUtil.getConnection();
    CallableStatement cstmt = conn.prepareCall(sql);
    cstmt.registerOutParameter(1,Types.VARCHAR);
    cstmt.setString(2,"zhaojun");
    cstmt.execute();
    String value = cstmt.getString(1);
    System.out.println(value);
    JdbcUtil.close(cstmt);
    JdbcUtil.close(conn);

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末师痕,一起剝皮案震驚了整個(gè)濱河市溃睹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胰坟,老刑警劉巖因篇,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡竞滓,警方通過(guò)查閱死者的電腦和手機(jī)咐吼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)商佑,“玉大人锯茄,你說(shuō)我怎么就攤上這事±蛴” “怎么了撇吞?”我有些...
    開(kāi)封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)礁叔。 經(jīng)常有香客問(wèn)我牍颈,道長(zhǎng),這世上最難降的妖魔是什么琅关? 我笑而不...
    開(kāi)封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任煮岁,我火速辦了婚禮,結(jié)果婚禮上涣易,老公的妹妹穿的比我還像新娘画机。我一直安慰自己,他們只是感情好新症,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布步氏。 她就那樣靜靜地躺著,像睡著了一般徒爹。 火紅的嫁衣襯著肌膚如雪荚醒。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天隆嗅,我揣著相機(jī)與錄音界阁,去河邊找鬼。 笑死胖喳,一個(gè)胖子當(dāng)著我的面吹牛泡躯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丽焊,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼较剃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了技健?” 一聲冷哼從身側(cè)響起重付,我...
    開(kāi)封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凫乖,沒(méi)想到半個(gè)月后确垫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體弓颈,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年删掀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翔冀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡披泪,死狀恐怖纤子,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情款票,我是刑警寧澤控硼,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站艾少,受9級(jí)特大地震影響卡乾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缚够,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一幔妨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谍椅,春花似錦误堡、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至杖们,卻和暖如春沾谜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胀莹。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婚温,地道東北人描焰。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像栅螟,于是被迫代替她去往敵國(guó)和親荆秦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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