JavaWeb - Hibernate框架使用(一)

1. Hibernate是什么

1.1 框架是什么

  • 1.框架是用来提高开发效率的
  • 2.封装了好了一些功能.我们需要使用这些功能时,调用即可.不需要再手动实现.
  • 3.所以框架可以理解成是一个半成品的项目.只要懂得如何驾驭这些功能即可.

1.2 hibernate框架是什么

Hibernate框架是什么

Overview

1.3 hibernate的好处

操作数据库的时候,可以以面向对象的方式来完成.不需要书写SQL语句

1.4 hibernate是一款orm框架

  • ORM:object relationg mapping. 对象关系映射
    ORM之Hibernate
  • orm分4级
    • hibernate属于4级:完全面向对象操作数据库
    • mybatis属于2级
    • dbutils属于1级

2 Hibernate框架的搭建

2.1 导包

  • 下载hibernate-release-5.2.12.Final.zip
  • 解压,复制导入hibernate-release-5.2.12.Final\lib\required目录下的所有jar包


    hibernate核心jar包
  • MySQL驱动包:mysql-connector-java-5.1.40-bin.jar

2.2 创建数据库、表、实体

  • 创建数据库hibernate_32
  • 创建表
CREATE TABLE `cst_customer` (
      `cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
      `cust_name` VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
      `cust_source` VARCHAR(32) DEFAULT NULL COMMENT '客户信息来源',
      `cust_industry` VARCHAR(32) DEFAULT NULL COMMENT '客户所属行业',
      `cust_level` VARCHAR(32) DEFAULT NULL COMMENT '客户级别',
      `cust_linkman` VARCHAR(64) DEFAULT NULL COMMENT '联系人',
      `cust_phone` VARCHAR(64) DEFAULT NULL COMMENT '固定电话',
      `cust_mobile` VARCHAR(16) DEFAULT NULL COMMENT '移动电话',
      PRIMARY KEY (`cust_id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  • Customer.java
public class Customer {
    private Long cust_id;   
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_linkman;
    private String cust_phone;
    private String cust_mobile;
    public Long getCust_id() {
        return cust_id;
    }
    public void setCust_id(Long cust_id) {
        this.cust_id = cust_id;
    }
    public String getCust_name() {
        return cust_name;
    }
    public void setCust_name(String cust_name) {
        this.cust_name = cust_name;
    }
    public String getCust_source() {
        return cust_source;
    }
    public void setCust_source(String cust_source) {
        this.cust_source = cust_source;
    }
    public String getCust_industry() {
        return cust_industry;
    }
    public void setCust_industry(String cust_industry) {
        this.cust_industry = cust_industry;
    }
    public String getCust_level() {
        return cust_level;
    }
    public void setCust_level(String cust_level) {
        this.cust_level = cust_level;
    }
    public String getCust_linkman() {
        return cust_linkman;
    }
    public void setCust_linkman(String cust_linkman) {
        this.cust_linkman = cust_linkman;
    }
    public String getCust_phone() {
        return cust_phone;
    }
    public void setCust_phone(String cust_phone) {
        this.cust_phone = cust_phone;
    }
    public String getCust_mobile() {
        return cust_mobile;
    }
    public void setCust_mobile(String cust_mobile) {
        this.cust_mobile = cust_mobile;
    }
    @Override
    public String toString() {
        return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + "]";
    }
}

2.3 书写orm元数据(对象实体Customer与数据库表cst_customer的映射配置文件)

  • Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
   <!-- 配置表与实体对象的关系 -->
   <!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. -->
<hibernate-mapping package="domain" >
    <!-- 
        class元素: 配置实体与表的对应关系的
            name: 完整类名
            table:数据库表名
     -->
    <class name="Customer" table="cst_customer" >
        <!-- id元素:配置主键映射的属性
                name: 填写主键对应属性名
                column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名
                type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
                        每个类型有三种填法: java类型|hibernate类型|数据库类型
                not-null(可选):配置该属性(列)是否不能为空. 默认值:false
                length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
         -->
        <id name="cust_id"  >
            <!-- generator:主键生成策略(明天讲) -->
            <generator class="native"></generator>
        </id>
        <!-- property元素:除id之外的普通属性映射
                name: 填写属性名
                column(可选): 填写列名
                type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
                        每个类型有三种填法: java类型|hibernate类型|数据库类型
                not-null(可选):配置该属性(列)是否不能为空. 默认值:false
                length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
         -->
        <property name="cust_name" column="cust_name" >
            <!--  <column name="cust_name" sql-type="varchar" ></column> -->
        </property>
        <property name="cust_source" column="cust_source" ></property>
        <property name="cust_industry" column="cust_industry" ></property>
        <property name="cust_level" column="cust_level" ></property>
        <property name="cust_linkman" column="cust_linkman" ></property>
        <property name="cust_phone" column="cust_phone" ></property>
        <property name="cust_mobile" column="cust_mobile" ></property>
    </class>
</hibernate-mapping>

2.4 书写hibernate主配置文件

  • hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
    
        <!-- 
        #hibernate.dialect org.hibernate.dialect.MySQLDialect
        #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
        #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
        #hibernate.connection.driver_class com.mysql.jdbc.Driver
        #hibernate.connection.url jdbc:mysql:///test
        #hibernate.connection.username gavin
        #hibernate.connection.password
         -->
         <!-- 数据库驱动 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
         <!-- 数据库url -->
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate_32</property>
         <!-- 数据库连接用户名 -->
        <property name="hibernate.connection.username">root</property>
         <!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">root</property>
        <!-- 数据库方言
            不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
            sql99标准: DDL 定义语言  库表的增删改查
                      DCL 控制语言  事务 权限
                      DML 操纵语言  增删改查
            注意: MYSQL在选择方言时,请选择最短的方言.
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        
        
        <!-- #hibernate.show_sql true 
             #hibernate.format_sql true
        -->
        <!-- 将hibernate生成的sql语句打印到控制台 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 将hibernate生成的sql语句格式化(语法缩进) -->
        <property name="hibernate.format_sql">true</property>
        <!-- 
        ## auto schema export  自动导出表结构. 自动建表
        #hibernate.hbm2ddl.auto create      自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
        #hibernate.hbm2ddl.auto validate    校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 引入orm元数据
            路径书写: 填写src下的路径
         -->
        <mapping resource="domain/Customer.hbm.xml" />
        
    </session-factory>
</hibernate-configuration>

2.5 使用测试

  • TestHibernate.java
package hello;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import domain.Customer;

public class TestHibernate {
    @Test
    public void test(){
        Configuration conf = new Configuration().configure();
        SessionFactory sessionFactory = conf.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        //---------------
        Customer c = new Customer();
        c.setCust_name("伊尔");
        session.save(c);
        //---------------
        transaction.commit();
        session.close();
        sessionFactory.close();
    }
}
  • 运行测试


    第一次使用Hibernate

3. 配置文件详解

3.1 orm元数据(Customer.hbm.xml)

  • 根元素
<!-- 配置表与实体对象的关系 -->
<!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. -->
<hibernate-mapping package="domain" >
  • class元素
    <!-- 
        class元素: 配置实体与表的对应关系的
            name: 完整类名
            table:数据库表名
     -->
    <class name="Customer" table="cst_customer" >
  • id元素
        <!-- id元素:配置主键映射的属性
                name: 填写主键对应属性名
                column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名
                type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
                        每个类型有三种填法: java类型|hibernate类型|数据库类型
                not-null(可选):配置该属性(列)是否不能为空. 默认值:false
                length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
         -->
        <id name="cust_id"  >
            <!-- generator:主键生成策略 -->
            <generator class="native"></generator>
        </id>
  • property元素
        <!-- property元素:除id之外的普通属性映射
                name: 填写属性名
                column(可选): 填写列名
                type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
                        每个类型有三种填法: java类型|hibernate类型|数据库类型
                not-null(可选):配置该属性(列)是否不能为空. 默认值:false
                length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
         -->
        <property name="cust_name" column="cust_name" >
            <!--  <column name="cust_name" sql-type="varchar" ></column> -->
        </property>

这里的<property/>元素要说一下,引用Hibernate官方文档的一个例子

<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>

The two <property/> elements declare the remaining two persistent properties of the Event(例子中的实体类) class: date and title. The date property mapping includes the column attribute, but the title does not. In the absence of a column attribute, Hibernate uses the property name as the column name. This is appropriate for title, but since date is a reserved keyword in most databases, you need to specify a non-reserved word for the column name.

The title mapping also lacks a type attribute. The types declared and used in the mapping files are neither Java data types nor SQL database types. Instead, they are Hibernate mapping types, which are converters which translate between Java and SQL data types. Hibernate attempts to determine the correct conversion and mapping type autonomously if the type attribute is not specified in the mapping, by using Java reflection to determine the Java type of the declared property and using a default mapping type for that Java type.

In some cases this automatic detection might not chose the default you expect or need, as seen with the date property. Hibernate cannot know if the property, which is of type java.util.Date, should map to a SQL DATE, TIME, or TIMESTAMP datatype. Full date and time information is preserved by mapping the property to the timestamp converter, which identifies the converter class org.hibernate.type.TimestampType.

从上面可以看出来几点:

  1. column属性是可以省略的,默认属性名和数据库列名一致
  2. type属性也是可以省略的,Hibernate会自动检测实体属性的类型
  3. 但是上述例子中的属性date,它的column属性不能省略,因为date是大多数数据库的保留关键字(reserved keyword),所以要为其指定列名;而且type属性也不能省略,需要具体指定一种日期时间类型,这里使用的是Hibernate映射类型timestamp

3.2 hibernate主配置文件(hibernate.cfg.xml)

  • 必选属性配置(5个)
        <!-- 数据库驱动 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
         <!-- 数据库url -->
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate_32</property>
         <!-- 数据库连接用户名 -->
        <property name="hibernate.connection.username">root</property>
         <!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">root</property>
        <!-- 数据库方言
            不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
            sql99标准:DDL 定义语言  库表的增删改查
                    DCL 控制语言  事务 权限
                    DML 操纵语言  增删改查
        注意: MYSQL在选择方言时,请选择最短的方言(指下面的第一个hibernate.dialect org.hibernate.dialect.MySQLDialect).
        #hibernate.dialect org.hibernate.dialect.MySQLDialect
        #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
        #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  • 可选属性配置(3个)
        <!-- 将hibernate生成的sql语句打印到控制台 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 将hibernate生成的sql语句格式化(语法缩进) -->
        <property name="hibernate.format_sql">true</property>
        <!-- 
        ## auto schema export  自动导出表结构. 自动建表
        #hibernate.hbm2ddl.auto create
         自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto create-drop
         自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto update  (推荐使用) 
         自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
        #hibernate.hbm2ddl.auto validate
         校验.不自动生成表.每次启动会校验数据库中表是否正确.校验属性与列名是否一致,校验失败会抛出SchemaManagementException
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>
  • 元数据引入配置
        <!-- 引入orm元数据
        路径: 填写src下的路径
          右键Customer.hbm.xml,复制全限定名/Hibernate_CRM/src/domain/Customer.hbm.xml,
        删除前面的/Hibernate_CRM/src/
         -->
        <mapping resource="domain/Customer.hbm.xml" />

4. Hibernate API详解

4.1 Configuration

  • 创建
    Configuration conf = new Configuration();
  • 加载主配置(加载src目录下的hibernate.cfg.xml。通过查看无参configure()方法的源码可以知道,实际上是直接return了有参方法configure(String resource),参数赋的是默认的路径字符串hibernate.cfg.xml
    conf.configure();
  • 加载orm元数据(早期写法,了解即可;如果主配置文件中已经进入映射配置,则不需要手动加载)
    conf.addResource(resourceName);
    conf.addClass(persistentClass);
  • 创建SessionFactory实例
    SessionFactory sessionFactory = conf.buildSessionFactory();

4.2 SessionFactory

  • SessionFactory功能: 用于创建操作数据库核心对象session对象的工厂。简单说功能就一个---创建session对象
  • 注意:
    • sessionFactory 负责保存和使用所有配置信息.消耗内存资源非常大.
    • sessionFactory 属于线程安全的对象设计.
    • 保证在web项目中,只创建一个sessionFactory.
  • 获得session
    //打开一个新的session对象
    sf.openSession();
    //获得一个与线程绑定的session对象
    sf.getCurrentSession();

4.3 Session & Transaction

  • session对象功能: 表达hibernate框架与数据库之间的连接(会话).session类似于JDBC的connection对象. 还可以完成对数据库中数据的增删改查操作.session是hibernate操作数据库的核心对象。
  • 调用session的save/update/delete/get方法将实体交给Hibernate进行管理,Hibernate负责为每个实体对数据库执行INSERT/UPDATE/DELETE/SELECT操作。
  • 对象的简单增删改查操作:
    @Test
    //session的新增
    public void fun2(){
        //1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2 根据配置信息,创建 SessionFactory对象
        SessionFactory sf = conf.buildSessionFactory();
        //3 获得session
        Session session = sf.openSession();
        //4 session获得操作事务的Transaction对象
        //获得操作事务的tx对象
        //Transaction tx = session.getTransaction();
        //开启事务并获得操作事务的tx对象(建议使用)
        Transaction tx2 = session.beginTransaction();
        //----------------------------------------------
        Customer c = new Customer();
        c.setCust_name("Google");
        
        session.save(c);
        //----------------------------------------------
        tx2.commit();//提交事务
        session.close();//释放资源
        sf.close();//释放资源
    }
    @Test
    //session的查询
    //查询id为1的customer对象
    public void fun3(){
        //1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2 根据配置信息,创建 SessionFactory对象
        SessionFactory sf = conf.buildSessionFactory();
        //3 获得session
        Session session = sf.openSession();
        //4 session获得操作事务的Transaction对象
        //获得操作事务的tx对象
        //Transaction tx = session.getTransaction();
        //开启事务并获得操作事务的tx对象(建议使用)
        Transaction tx2 = session.beginTransaction();
        //----------------------------------------------
        
        Customer customer = session.get(Customer.class, 1l);
        
        System.out.println(customer);
        //----------------------------------------------
        tx2.commit();//提交事务
        session.close();//释放资源
        sf.close();//释放资源
    }
    @Test
    //session的修改
    //修改id为1的customer对象的name属性为黑马程序员
    public void fun4(){
        //1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2 根据配置信息,创建 SessionFactory对象
        SessionFactory sf = conf.buildSessionFactory();
        //3 获得session
        Session session = sf.openSession();
        //4 session获得操作事务的Transaction对象
        //获得操作事务的tx对象
        //Transaction tx = session.getTransaction();
        //开启事务并获得操作事务的tx对象(建议使用)
        Transaction tx2 = session.beginTransaction();
        //----------------------------------------------
        //1 获得要修改的对象
        Customer c = session.get(Customer.class, 1l);
        //2 修改
        c.setCust_name("黑马程序员");
        //3 执行update
        session.update(c);
        //----------------------------------------------
        tx2.commit();//提交事务
        session.close();//释放资源
        sf.close();//释放资源
    }
    @Test
    //session的删除
    //删除id为1的customer对象
    public void fun5(){
        //1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2 根据配置信息,创建 SessionFactory对象
        SessionFactory sf = conf.buildSessionFactory();
        //3 获得session
        Session session = sf.openSession();
        //4 session获得操作事务的Transaction对象
        //获得操作事务的tx对象
        Transaction tx = session.getTransaction();
        tx.begin();
        //开启事务并获得操作事务的tx对象(建议使用)
        Transaction tx2 = session.beginTransaction();
        //----------------------------------------------
        //1 获得要修改的对象
        Customer c = session.get(Customer.class, 1l);
        //2 调用delete删除对象
        session.delete(c);
        //----------------------------------------------
        tx2.commit();//提交事务
        session.close();//释放资源
        sf.close();//释放资源
    }
  • Transaction封装了事务的操作
    @Test
    //事务操作
    public void fun1(){
        //1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2 根据配置信息,创建 SessionFactory对象
        SessionFactory sf = conf.buildSessionFactory();
        //3 获得session
        Session session = sf.openSession();
        //4 session获得操作事务的Transaction对象
        //获得操作事务的tx对象
        //Transaction tx = session.getTransaction();
        //开启事务并获得操作事务的tx对象(建议使用)
        Transaction tx2 = session.beginTransaction();
        //----------------------------------------------
        //do something here...
        //----------------------------------------------
        tx2.commit();//提交事务
        tx2.rollback();//回滚事务
        session.close();//释放资源
        sf.close();//释放资源
    }

4.4 封装HibernateUtils.java

package utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static SessionFactory sessionFactory;

    static {
        // 1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        // 2 根据配置信息,创建 SessionFactory对象
        sessionFactory = conf.buildSessionFactory();
    }

    // 获得session => 获得全新session
    public static Session openSession() {
        // 3 获得session
        return sessionFactory.openSession();
    }

    // 获得session => 获得与线程绑定的session
    public static Session getCurrentSession() {
        // 3 获得session
        return sessionFactory.getCurrentSession();
    }

    public static void main(String[] args) {
        System.out.println(HibernateUtils.openSession());
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容