Spring Boot & Spring Data & JPA

:) 本篇會(huì)分別介紹 Spring Data 祭埂,JPA 胚宦,Spring Data JPA

JPA簡(jiǎn)介

jpa全稱(chēng)是 Java Persistence API,jpa定義了各種注解(用來(lái)定義實(shí)體,映射關(guān)系)掏愁。JPA僅僅是一個(gè)規(guī)范歇由,它的實(shí)現(xiàn)比較出名的是Hibernate


JPA實(shí)體

  • 實(shí)體可以簡(jiǎn)單理解成一組狀態(tài)的集合
  • 實(shí)體需要能夠持久化并有持久化標(biāo)識(shí),支持事務(wù)
  • JPA中的實(shí)體使用注解@Entity標(biāo)記果港,實(shí)體的id使用@Id標(biāo)記沦泌,實(shí)體對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名使用@Table標(biāo)記,實(shí)體對(duì)應(yīng)數(shù)據(jù)庫(kù)字段使用@Column標(biāo)記辛掠,主鍵生成策略使用@GeneratedValue標(biāo)記
import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "user")
public class User  implements Serializable {

    @Id
    // 主鍵自動(dòng)增長(zhǎng)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    // 默認(rèn)對(duì)應(yīng)字段 number
    private String number;

   // 省略 getter & setter 
}

實(shí)體還需要一個(gè)默認(rèn)的無(wú)參構(gòu)造函數(shù)


使用spring boot簡(jiǎn)單測(cè)試jpa

  • 添加依賴
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
  • 在classpath:META-INF下面創(chuàng)建一個(gè)java persistence 的配置文件(注意文件路徑必須是 META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
             xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="JPA" transaction-type="RESOURCE_LOCAL">
        <!-- 配置jpa ORM產(chǎn)品 -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!-- 添加對(duì)應(yīng)的持久化類(lèi) -->
        <class>com.suse.yudapi.entity.User</class>
        <properties>
            <!-- jpa中連接數(shù)據(jù)庫(kù) -->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/demo" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="123456"></property>

            <!-- jpa中配置hibernate基本屬性 -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create"/>
        </properties>

    </persistence-unit>
</persistence>
  • 創(chuàng)建一個(gè)測(cè)試程序
public class JPAMain {

    public static void main(String[] args){
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("JPA");
        EntityManager manager = factory.createEntityManager();
        manager.getTransaction().begin();
        User user = new User();
        user.setName("yudapi");
        user.setNumber("12312312");
        manager.persist(user);
        manager.getTransaction().commit();
    }

}


JPA的CRUD操作

  • CRUD都是使用的EntityManager的方法來(lái)完成的谢谦,persist,find萝衩,remove
public class JPAMain {

    public static void main(String[] args){

        EntityManagerFactory factory = Persistence.createEntityManagerFactory("JPA");
        EntityManager manager = factory.createEntityManager();

        User user = new User();
        user.setName("yudapi");
        user.setNumber("12312312");
        // 新增
        manager.getTransaction().begin();
        manager.persist(user);
        manager.getTransaction().commit();
        // 查找
        User userInfo = manager.find(User.class, 1L);
        System.out.println(userInfo.getName()+"  "+userInfo.getNumber());
        // 更新
        userInfo.setName("update after");
        manager.getTransaction().begin();
        manager.persist(userInfo);
        manager.getTransaction().commit();
        System.out.println(userInfo.getName()+"  "+userInfo.getNumber());
        // 刪除
        manager.getTransaction().begin();
        manager.remove(userInfo);
        manager.getTransaction().commit();
    }
}


JPA中的集合映射

  • 類(lèi)似一對(duì)多的關(guān)系回挽,但是沒(méi)有雙向關(guān)聯(lián)關(guān)系,也不能級(jí)聯(lián)操作猩谊。
  • 新建一個(gè)Book實(shí)體千劈,一個(gè)用戶持有多個(gè)book實(shí)體,注意這個(gè)實(shí)體有一個(gè)Embeddable注解牌捷。這個(gè)注解表示這個(gè)實(shí)體可以嵌入其他實(shí)體
@Entity
@Table(name = "books")
@Embeddable
public class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String number;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
}
  • 修改User實(shí)體墙牌,嵌入一個(gè)Book實(shí)體的列表
@ElementCollection(targetClass = Book.class)
List<Book> books;

自動(dòng)創(chuàng)建的表結(jié)構(gòu)是兩個(gè)實(shí)體分別創(chuàng)建一個(gè)表,使用了一個(gè)中間表來(lái)存儲(chǔ)關(guān)聯(lián)關(guān)系


JPA實(shí)體間的映射

  • 一對(duì)一映射 @OneToOne宜鸯,這個(gè)是通過(guò)外鍵來(lái)關(guān)聯(lián)的憔古。注解在那個(gè)實(shí)體里面就會(huì)在這個(gè)實(shí)體里面生成一個(gè)關(guān)聯(lián)的外鍵
// in user entity
@OneToOne
UserEx userEx; // 這個(gè)實(shí)體的id會(huì)在user表里面有一個(gè)外鍵字段
  • 一對(duì)多映射@OneToMany,這個(gè)需要添加targetEntity屬性淋袖。這個(gè)是通過(guò)中間表來(lái)關(guān)聯(lián)
  • 多對(duì)一映射@ManyToOne鸿市,這個(gè)會(huì)再多的一方創(chuàng)建一個(gè)外鍵
// in user entity
@ManyToOne(cascade = CascadeType.ALL)
Tag tag;
  • 多對(duì)多映射@ManyToMany


JPA級(jí)聯(lián)操作

  • 級(jí)聯(lián)操作都是 javax.persistence.CascadeType 里面的枚舉,級(jí)聯(lián)可以用在上面的映射關(guān)系注解
  • PERSIST 如果父實(shí)體持久存在即碗,則其所有相關(guān)實(shí)體也將被持久化
  • MERGE 如果父實(shí)體被合并焰情,則其所有相關(guān)實(shí)體也將被合并
  • DETACH 如果父實(shí)體被分離,那么它的所有相關(guān)實(shí)體也將被分離
  • REFRESH 如果父實(shí)體被刷新剥懒,則其所有相關(guān)實(shí)體也將被刷新
  • REMOVE 如果父實(shí)體被移除内舟,則其所有相關(guān)實(shí)體也將被移除
  • ALL 所有上述級(jí)聯(lián)操作都可以應(yīng)用于與父實(shí)體相關(guān)的實(shí)體


JPQL JPA的查詢語(yǔ)言

  • JPQL(Java持久性查詢語(yǔ)言)是一種面向?qū)ο蟮牟樵冋Z(yǔ)言,用于對(duì)持久實(shí)體執(zhí)行數(shù)據(jù)庫(kù)操作初橘。 JPQL不使用數(shù)據(jù)庫(kù)表验游,而是使用實(shí)體對(duì)象模型來(lái)操作SQL查詢



Spring Data 介紹

Spring Data 提供了一個(gè)數(shù)據(jù)訪問(wèn)層的抽象,這個(gè)抽象定義了基本的訪問(wèn)數(shù)據(jù)的接口保檐。這里的數(shù)據(jù)來(lái)源就不一定是數(shù)據(jù)庫(kù)了耕蝉,也可能是緩存,也可能是nosql數(shù)據(jù)庫(kù)等夜只,針對(duì)不同的底層數(shù)據(jù)存儲(chǔ)方式都可以使用同一套代碼進(jìn)行訪問(wèn)


Spring Data 核心概念

  • spring data將數(shù)據(jù)訪問(wèn)對(duì)象抽象成Repository垒在,這個(gè)是一個(gè)標(biāo)記接口,僅僅是標(biāo)記這個(gè)是個(gè)數(shù)據(jù)訪問(wèn)對(duì)象扔亥。這個(gè)接口是一個(gè)泛型接口场躯,T代表的是存儲(chǔ)的實(shí)體(比如這個(gè)類(lèi)是操作用戶的類(lèi)谈为,那么這個(gè)T就是User),ID代表這個(gè)實(shí)體對(duì)應(yīng)的唯一標(biāo)識(shí)
@Indexed
public interface Repository<T, ID> {
}
  • Repository僅僅是個(gè)標(biāo)記接口踢关,并沒(méi)有定義任何方法伞鲫。spring data提供了一個(gè)包含基本操作的Repository,CrudRepository(這個(gè)接口是Repository的子接口)
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> saveAll(Iterable<S> var1);

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> var1);

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}

  • 對(duì)于不同的存儲(chǔ)技術(shù)spring data提供了不同的接口签舞,比如JpaRepository榔昔,MongoRepository

spring data中的這些接口都不需要實(shí)現(xiàn),具體的實(shí)現(xiàn)是由spring data通過(guò)動(dòng)態(tài)代理針對(duì)不同的存儲(chǔ)技術(shù)實(shí)現(xiàn)的瘪菌,我們只需要按照約定將接口定義好就可以了


spring data demo

  • 這里先用 spring boot 來(lái)完成一個(gè) spring data 的demo
  • 依賴(這里用了 jpa 如果不清楚就先當(dāng)成一個(gè)orm框架就行了)
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
  • 創(chuàng)建測(cè)試數(shù)據(jù)庫(kù)(demo數(shù)據(jù)庫(kù) 和 user測(cè)試表)
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  `number` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • 定義實(shí)體類(lèi)
@Entity
@Table(name = "user")
public class User  implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String number;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

  • 定義User的Repository接口
public interface UserRepository extends CrudRepository<User,Long> { }
  • 雖然我們定義了Repository接口但是并沒(méi)有實(shí)現(xiàn)我們需要使用注解@EnableJpaRepositories激活Repository的自動(dòng)代理
@SpringBootApplication
@RestController
@EnableJpaRepositories
public class App {
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}
  • 訪問(wèn)數(shù)據(jù)庫(kù)(記得配置數(shù)據(jù)庫(kù)鏈接信息哦,DataSourcePerporties)
@SpringBootApplication
@RestController
@EnableJpaRepositories
public class App {

    @Autowired
    UserRepository userRepository;

    @RequestMapping("/insertUser")
    public User insertUser(){
        User user = new User();
        user.setName("dapi");
        user.setNumber("123456");
        user = userRepository.save(user);
        return user;
    }

    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}

@EnableJpaRepositories這個(gè)注解是激活 jpa 的方式來(lái)生成代理嘹朗,有些時(shí)候我們的應(yīng)用可能還用了其他的存儲(chǔ)技術(shù)师妙,比如mogodb這個(gè)時(shí)候就可以使用@EnableMogoRepositories,@EnableJpaRepositories可以添加一個(gè)basePackages屬性可以指定只代理特定包下面的Repositor接口



↓ 詳細(xì)介紹使用spring data的詳細(xì)步驟

定義Repository接口

  • 定義我們特定的repository接口我們有好幾種選擇:Repository 屹培,CrudRepository默穴,PagingAndSortingRepository(支持排序和分頁(yè)的方法定義,這個(gè)沒(méi)有什么特別的我們也可以按照規(guī)則自己定義方法)褪秀,當(dāng)然也可以不繼承任何的接口(前面已經(jīng)所有這些接口僅僅是一個(gè)標(biāo)記接口)

  • 有些時(shí)候我們會(huì)定義一個(gè)根據(jù)項(xiàng)目需求寫(xiě)的一個(gè)父Repository接口蓄诽,其他所有的Repository接口都需要繼承這個(gè)接口。這個(gè)父Repository接口是不需要被代理的媒吗,這個(gè)時(shí)候可以在父Repository接口使用注解 @NoRepositoryBean

  • 如果不想繼承spring data的Repository標(biāo)記接口仑氛,可以使用注解

@RepositoryDefinition(domainClass = User.class,idClass = Long.class)
public interface UserRepository  {
    <S extends User> S save(S user);
}
  • 多種存儲(chǔ)技術(shù)混合用的情況,比如JPA 和 MongoDB同時(shí)用的時(shí)候闸英。有個(gè)尷尬的事情就是锯岖,同一個(gè)Repository究竟是操作 sql數(shù)據(jù)庫(kù)呢還是操作 MongoDB呢?原則就是只要有能夠區(qū)分這兩種操作的代碼就行甫何,比如這個(gè)Repository繼承的是JpaRepository那這個(gè)就是操作sql數(shù)據(jù)庫(kù)出吹,如果操作的實(shí)體使用了@Entity注解那就是操作sql了,如果實(shí)體使用@Docment那就是操作mongodb了辙喂,如果Repository沒(méi)有使用特定的Repository捶牢,實(shí)體同時(shí)使用了@Entity和@Docment那這個(gè)時(shí)候就只能使用包名來(lái)區(qū)分了,比如jpa的Repository都在一個(gè)包里面@EnableJpaRepositories(basePackages = "com.suse.re.jpa")


定義查詢方法

  • 在Repository接口中按照特定的方式定義方法巍耗,就可以實(shí)現(xiàn)特定的查詢(當(dāng)然不止這一種方式扣甲,后面在介紹其他方式)
  • 查詢方法find…By,read…By杖刷, query…By裹虫,count…By, get…By娄琉。只要按照這種方式定義方法名次乓,就可以實(shí)現(xiàn)查詢(還有很多其他的支持吓歇,后面結(jié)合 jpa 一起說(shuō))
@RepositoryDefinition(domainClass = User.class,idClass = Long.class)
public interface UserRepository  {
    <S extends User> S save(S user);

    List<User> findByName(String name);
}
  • 分頁(yè)和排序處理,只需要在方法后面添加參數(shù)就可以處理了
@RepositoryDefinition(domainClass = User.class,idClass = Long.class)
public interface UserRepository  {
    <S extends User> S save(S user);
     
    // 定義排序
    List<User> findByName(String name, Sort orders);
}

    @RequestMapping("/filterName")
    public List<User> filterName(){
        // 使用排序
        Sort orders = new Sort(Sort.Direction.DESC,"id");
        return userRepository.findByName("dapi",orders);
    }
@RepositoryDefinition(domainClass = User.class,idClass = Long.class)
public interface UserRepository  {
    <S extends User> S save(S user);

    List<User> findByName(String name, Pageable pageable);
}

Pageable pageable = PageRequest.of(0,1);
return userRepository.findByName("dapi",pageable);

這兩個(gè)參數(shù)不能同時(shí)使用票腰,如果想要同時(shí)支持分頁(yè)和選擇城看,僅僅是構(gòu)造Pageable的時(shí)候不同。PageRequest pageable = PageRequest.of(0,1,Sort.Direction.DESC,"id");


創(chuàng)建Repository實(shí)例

  • 注解@EnableJpaRepositories
  • 使用EntityManager
class MyRepositoryImpl<T, ID extends Serializable>
        extends SimpleJpaRepository<T, ID> {
    private final EntityManager entityManager;

    MyRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }
    @Transactional
    public <S extends T> S save(S entity) {
    }
}


spring data web

  • 開(kāi)啟 spring data web 支持杏慰,@EnableSpringDataWebSupport
  • 直接將參數(shù)轉(zhuǎn)化成 Pageable 和 Sort
// http://localhost:8080/filterName?page=0&size=1&sort=id,DESC
    @RequestMapping("/filterName")
    public List<User> filterName(Pageable pageable){
        // PageRequest pageable = PageRequest.of(0,1,Sort.Direction.DESC,"id");
        return userRepository.findByName("dapi",pageable);
    }



Spring Data JPA簡(jiǎn)介

  • spring data jpa 是構(gòu)建在spring data 之上的一個(gè)簡(jiǎn)化 jpa 操作的庫(kù)


依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>


配置

  • 兩個(gè)注解:@EnableJpaRepositories@EnableTransactionManagement
@SpringBootApplication
@RestController
@EnableJpaRepositories
@EnableTransactionManagement
public class App {

    @Autowired
    UserRepository userRepository;

    @RequestMapping("/insertUser")
    public User insertUser(){
        User user = new User();
        user.setName("dapixxx");
        user.setNumber("123456");
        user = userRepository.save(user);
        return user;
    }


    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}


保存實(shí)體

  • 保存實(shí)體最后會(huì)調(diào)用 EntityManager 的 persist 方法或者是 merge方法 判斷是更具Id來(lái)判斷了测柠,如果Id為空會(huì)調(diào)用 persist 如果id不為空則調(diào)用 merge


查詢方法

  • 首先要知道有三種方式可以寫(xiě)查詢方法:方法名,JPA NamedQueries 缘滥,@Query

  • 方法名:按照特定的方式命名函數(shù)轰胁,spring data 最后會(huì)解析這個(gè)函數(shù)名

  • NamedQueries: 這個(gè)是JPA里面注解查詢

  • Query: 這個(gè)是spring data 的一個(gè)擴(kuò)展,和上面那個(gè)類(lèi)似

  • 按照方法名:比如 List<User> findByEmailAddressAndLastname(String emailAddress, String lastname); 這個(gè)方法名最后會(huì)被翻譯成 select u from User u where u.emailAddress = ?1 and u.lastname = ?2朝扼。 具體支持那些關(guān)鍵字就看這里吧赃阀。

  • @NamedQueries(JPQL) & @NamedNativeQuery(支持sql)

@Entity
@NamedQuery(name = "User.findByEmailAddress",
query = "select u from User u where u.emailAddress = ?1")
public class User {
}

public interface UserRepository extends JpaRepository<User, Long> {
      List<User> findByLastname(String lastname);
      User findByEmailAddress(String emailAddress);
}

  • @Query
public interface UserRepository extends JpaRepository<User, Long> {
        @Query("select u from User u where u.emailAddress = ?1")
        User findByEmailAddress(String emailAddress);
}
  • @Query & Like
public interface UserRepository extends JpaRepository<User, Long> {
        @Query("select u from User u where u.firstname like %?1")
        List<User> findByFirstnameEndsWith(String firstname);
}
  • @Query & sql
public interface UserRepository extends JpaRepository<User, Long> {
        @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery =
true)
        User findByEmailAddress(String emailAddress);
}
  • @Query & sql & page
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
  • @Query & name parameters
public interface UserRepository extends JpaRepository<User, Long> {
        @Query("select u from User u where u.firstname = :firstname or u.lastname =:lastname")
        User findByLastnameOrFirstname(@Param("lastname") String lastname,
            @Param("firstname") String firstname);
}


投影

  • 簡(jiǎn)單的說(shuō)就是實(shí)體的有些部分不想返回,我們就可以用投影來(lái)操作
  • 建立一個(gè)接口擎颖,將需要返回的字段聲明成方法
class Person {
    @Id UUID id;
    String firstname, lastname;
    Address address;
    static class Address {
        String zipCode, city, street;
    }
}

interface NamesOnly {
    String getFirstname();
    String getLastname();
}

interface PersonRepository extends Repository<Person, UUID> {
    Collection<NamesOnly> findByLastname(String lastname);
}


?
End

[2]??spring boot JDBC
[4]??spring boot Mybatis

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末榛斯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子搂捧,更是在濱河造成了極大的恐慌驮俗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件允跑,死亡現(xiàn)場(chǎng)離奇詭異王凑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)吮蛹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)荤崇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人潮针,你說(shuō)我怎么就攤上這事术荤。” “怎么了每篷?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵瓣戚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我焦读,道長(zhǎng)子库,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任矗晃,我火速辦了婚禮仑嗅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己仓技,他們只是感情好鸵贬,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著脖捻,像睡著了一般阔逼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上地沮,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天嗜浮,我揣著相機(jī)與錄音,去河邊找鬼摩疑。 笑死危融,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雷袋。 我是一名探鬼主播专挪,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼片排!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起速侈,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤率寡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后倚搬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體冶共,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年每界,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捅僵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眨层,死狀恐怖庙楚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情趴樱,我是刑警寧澤馒闷,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站叁征,受9級(jí)特大地震影響纳账,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捺疼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一疏虫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦卧秘、人聲如沸呢袱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)产捞。三九已至,卻和暖如春哼御,著一層夾襖步出監(jiān)牢的瞬間坯临,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工恋昼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留看靠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓液肌,卻偏偏與公主長(zhǎng)得像挟炬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嗦哆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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