spring boot+mybatis+mysql+Swagger2構建完整項目

從0到1構建一個spring boot + mybatis的項目

圖片發自簡書App

前言:
為什么選擇spring boot?或許對于經歷過編寫大量的配置文件的小伙伴,有一點就可以打動他-----零配置運行一個程序。而且spring boot內嵌Tomcat,當然,spring boot還有好多的優點,大大提高了我們的開發進度。

所以為了有更多的時間陪女朋友,快點加入spring boot的學習吧!!!

學習此篇文章,如果你對以下知識有一定的了解將會更有利于你對這篇文章的理解。
1.spring基礎知識,如IOC,AOP等
2.mybatis基礎
3.mysql基礎
4.maven基礎


好了,開始我們spring boot的學習吧
首先你的電腦上需要以下環境(環境統一,不然會出現奇怪的問題):
1.安裝 IntelliJ Idea(旗艦版)
2.java環境(版本1.8或以上)
3.數據庫Mysql(版本5.7或以上)

一、新建spring boot項目

1.打開idea,并創建一個新的項目:

1.png

2.選擇Spring Initializr選項,并選擇一個SDK,點擊Next


2.png

3.填寫Group(一般為公司域名反寫)和Artifact(項目名),此項目的管理工具為Maven(當然你也可以使用Gradle),打包方式 為jar包,java版本為1.8,點擊Next


3.png

4.這里選擇先添加Web依賴,點擊Next


4.png

5.點擊Finish


5.png

6.好了,我們的spring boot項目就已經創建好了,我們來看一下項目的結構。對于.mvn mvnw mvnw.cmd這幾個文無關緊要,看著煩,可以刪除。

6.png

7.我們來運行一下項目,圖中點擊任意哪個都可以,快捷鍵為Ctrl+Shift+F10

7.png

8.在控制臺中會輸出一大串日志信息,你如果看到了下圖中的信息,恭喜你項目已經啟動成功了


8.png

9.在瀏覽器訪問localhost:8080,你將看到以下信息

9.png

我們在com.example.demo下創建一個controller包,在controller包下創建一個Hello.java類。
src/main/java/com/example/demo/controller/Hello.java

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Hello {
    @RequestMapping("/hi")
    public String hello(){
        return "hello world";
    }
}

重新啟動我們的項目,并訪問localhost:8080/hi我們的spring boot項目的hello world程序就已經成功了,我們沒有寫一行配置,就已經將一個spring boot程序運行起來了。

10.png

二、集成Mybatis

1.我們整理一下我們的項目目錄結構:
11.png
2.在pom.xml文件中添加如下代碼

demo/pom.xml

<dependencies>
        ..........
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        .........
</dependencies>
3.創建數據庫和表

建表語句如下:(你也可以使用mysql workbench這個免費工具,官方可下載)

CREATE TABLE `test`.`user` (
  `user_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用戶id',
  `user_name` VARCHAR(45) NOT NULL COMMENT '用戶名',
  `password` VARCHAR(45) NOT NULL COMMENT '密碼',
  `age` INT NOT NULL COMMENT '年齡',
  PRIMARY KEY (`user_id`))
COMMENT = '用戶表';

這樣我們就已經將mybatis和mysql集成到我們的spring boot項目中去了。下面教大家如何配置使用mybatis.(包括如何使用mybatis generator插件生成代碼。)

4編寫mybatis代碼生成的配置

src/main/resources/mybatis下新建一個mybatis-generator.xml

src/main/resources/mybatis/mybatis-generator.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--導入屬性配置-->
    <properties resource="datasource.properties"/>

    <!--指定特定數據庫的jdbc驅動jar包的位置-->
    <classPathEntry location="${db.driverLocation}"/>

    <context id="default" targetRuntime="MyBatis3">

        <!-- optional,旨在創建class時,對注釋進行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--jdbc的數據庫連接 -->
        <jdbcConnection
                driverClass="${db.driverClassName}"
                connectionURL="${db.url}"
                userId="${db.username}"
                password="${db.password}">
        </jdbcConnection>


        <!-- 非必需,類型處理器,在數據庫類型和java類型之間的轉換控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>


        <!-- Model模型生成器,用來生成含有主鍵key的類,記錄類 以及查詢Example類
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在該項目下所在的路徑
        -->
        <javaModelGenerator targetPackage="com.example.demo.pojo" targetProject="./src/main/java">
            <!-- 是否允許子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否對model添加 構造函數 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否對類CHAR類型的列的數據進行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model對象是否 不可改變  即生成的Model對象不會有 setter方法,只有構造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!--mapper映射文件生成所在的目錄 為每一個數據庫的表生成對應的SqlMap文件 -->
        <sqlMapGenerator targetPackage="mybatis/mapper" targetProject="./src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 客戶端代碼,生成易于使用的針對Model對象和XML配置文件 的代碼
                type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper對象
                type="MIXEDMAPPER",生成基于注解的Java Model 和相應的Mapper對象
                type="XMLMAPPER",生成SQLMap XML文件和獨立的Mapper接口
        -->

        <!-- targetPackage:mapper接口dao生成的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.demo.dao" targetProject="./src/main/java">
            <!-- enableSubPackages:是否讓schema作為包的后綴 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>

        <!-- 每個table標簽對應數據庫中的一張表,用于生成pojo -->
        <table tableName="user" domainObjectName="User" enableCountByExample="true" enableUpdateByExample="true"
               enableDeleteByExample="true" enableSelectByExample="true" selectByExampleQueryId="true"/>

        <!-- geelynote mybatis插件的搭建 -->
    </context>
</generatorConfiguration>

新建resources/datasource.properties并添加如下代碼:(#號后面的為注釋,這個文件將會被resources/mybatis/mybatis-generator.xml引用)

#數據庫本地的驅動jar包路徑(你的路徑和此處不一定相同)
db.driverLocation=C:/Users/sifu/.m2/repository/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6.jar
#數據庫驅動
db.driverClassName=com.mysql.jdbc.Driver
#數據庫url
db.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&verifyServerCertificate=false
#數據庫用戶名
db.username=root
#數據庫密碼
db.password=sifu

修改application.properties名稱為application.yml并且添加如下代碼(此文件中有嚴格的代碼格式):
resources/application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&verifyServerCertificate=false
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: sifu
mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml
  type-aliases-package: com.example.demo.pojo

解釋:
url:數據庫鏈接地址
driver-class-name:數據庫驅動
username:數據庫用戶名
password:數據庫密碼
mapper-locations:指定生成的*.xml文件路徑
type-aliases-package:指定實體類路徑

為什么修改使用yml格式的配置文件,原因是為了使代碼更加簡潔。以上application.yml代碼等同于application.properties的如下代碼:

spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&verifyServerCertificate=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=sifu

mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.example.demo.pojo

看一下,是不是yml格式的配置更加簡潔?至于用哪個,自己決定咯,個人推薦用yml格式的!!

5.添加mybatis generator插件

修改pom.xml文件,添加mybatis的代碼生成插件

.......
    <build>
        <plugins>
            ..........
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                    <configurationFile>${project.basedir}/src/main/resources/mybatis/mybatis-generator.xml
                    </configurationFile>
                </configuration>
            </plugin>
        </plugins>
    </build>

雙擊mybatisi-generator:generate(注意:不要運行多次,否則會生成重復的代碼,編譯時會出現神奇的bug

12.png

此時Build成功:

13.png

讓我們再看一下我們的項目結構:

14.png

多了四個文件,這些就是mybatis generator插件生成的代碼。
UserMapper:用于操作數據庫的接口(沒有實現類,對應UserMapper.xml文件)
User:實體類,對應數據庫中的一張表
UserExample:用于做條件增刪改查用的
UserMapper.xml:里面是一些sql語句

用這些生成的代碼來操作數據庫面對大部分業務已經足夠了,如果不能滿足,那就自己在UserMapper.javaUserMapper.xml中去編寫添加接口和sql語句吧!這個由你自己去探索!!

現在我們的spring boot + mybatis項目已經基本構建完成了,我們完全可以成功的運行我們的項目。但是到此處還不夠,我們還需要一點其他的工具,讓我們開發項目更加便捷快速。接著看吧!

三、集成測試工具Swagger2

為了我們能夠更好的測試我們編寫的代碼,我們在pom.xml中添加如下代碼,集成swagger2.
pom.xml

<dependencies>
        .......
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
</dependencies>

注意:swagger的版本最好設置高一點,版本過低時,參數如果是對象,調試會出現問題,這里設置為2.7.0版本。

并且新建com/example/demo/config/SwaggerConfig.java---swagger的配置文件,添加如下代碼:

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot中使用Swagger2構建RESTful APIs")
                .description("")
                .termsOfServiceUrl("")
                .contact(new Contact("sifu","www.xxx.com","123456@qq.com"))
                .version("1.0")
                .build();
    }

}

注意.apis(RequestHandlerSelectors.basePackage(""))中請填寫正確的controller路徑。

下面讓我們來編寫一個業務邏輯的代碼,往我們的數據庫中插入一條數據
新建com/example/demo/service/UserService.java

package com.example.demo.service;

import com.example.demo.pojo.User;

public interface UserService {
    int add(User user);
}

新建com/example/demo service/impl/UserserviceImpl.java

package com.example.demo.service.impl;

import com.example.demo.dao.UserMapper;
import com.example.demo.pojo.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    public int add(User user) {
        return userMapper.insert(user);
    }
}

新建com/example/demo/controller/UserController.java

package com.example.demo.controller;

import com.example.demo.pojo.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/add")
    public int add(User user) {
        return userService.add(user);
    }
}

現在我們運行一下我們的程序

15.png

ps:臥槽,報錯了??逗我玩呢?浪費我這么多時間

不要急嘛,報錯原因是無法找到UserMapper.java.我們在啟動類DemoAppliction.java上添加一個注解@MapperScan("com.example.demo.dao"),用于掃描com/example/demo/dao包下的NameMapper.java文件(如果我們不集成Swagger2,則不會報這個錯誤,也不需要添加此的注解

com/example/demo/DemoAppliction.java

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.demo.dao")
public class DemoApplication {

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

好了,啟動我們的項目,并訪問http://localhost:8080/swagger-ui.html我們就可以看到一個調試的界面。

16.png

是不是感覺這界面看起來很爽,很清晰,但是如果只是好看,那就太low了,重點是在于它的功能強大。

填寫參數,因為傳的參數是User對象,所以需要填的參數都是實體類中的字段。(UserId是自增的,所以不填)點擊Try it out!

17.png

Response Body為返回值為1,說明數據庫中已經有一條數據插入了,狀態碼為200,說明請求成功了。

現在我們來看一下我們的數據庫中的數據,我們使用idea自帶的數據庫連接工具

18.png

彈出此界面,填寫一些必要的信息,點擊Test Connection,如果測試成功,那就點擊ok:

19.png

雙擊user,我們看到了我們之前添加的數據:


20.png

到此,我們的spring boot + mybatis 已經完全構建成功了,接下來就是編寫業務邏輯層的代碼了,這個就由你自己去探索了。

四、集成Spring AOP(日志打印使用Slf4j)

下面我們繼續讓我們的項目添加Spring AOP
1.pom.xml添加如下代碼:

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2.下載安裝一個插件(記得一定要安裝好哦!):lombok(很好用,下面再講)
3.新建com/example/demo/aspect/HttpAspect.java,并添加如下代碼(此處為了演示,只添加一些日志打印的代碼):

package com.example.demo.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Aspect
@Component
public class HttpAspect {

    @Pointcut(value = "execution(public * com.example.demo.controller.*.*(..))")
    public void log() {
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // url
        log.info("url={}", request.getRequestURL());
        // port
        log.info("port={}", request.getRemotePort());
        // method
        log.info("method={}", request.getMethod());
        // ip
        log.info("ip={}", request.getRemoteAddr());
        // class_method
        log.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        // 參數
        log.info("args={}", Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(Object object) {
        log.info("response={}", object);
    }
}

光看此處的代碼,我們發現我們根本就沒有聲明log這個變量,但是我們卻使用了它。這就是lombok插件的功能,在這個類上有一個@Slf4j的注解(要使用此注解,lombok插件請安裝好),添加這個注解就相當于在此類中添加了如下代碼:

import org.slf4j.Logger;
.....
private final Logger log = org.slf4j.LoggerFactory.getLogger(HttpAspect.class);

注意:此處的log對象必須看清楚是org.slf4j.Logger的實例

添加了這段代碼的作用是:在執行controller中的方法之前會先執行此類中的方法。

當然,lombok插件的功能遠遠不止這一點,剩下的就是你自己去探索了。

這里推薦一個關于lombok的使用的學習教程:https://my.oschina.net/u/1024107/blog/889184

Spring AOP學習教程:http://412887952-qq-com.iteye.com/blog/2305333

擴展

最后,為了我們能更好的進行開發,下面我們繼續添加一點功能。

1.熱部署

pom.xml添加如下代碼:

<dependencies>
        ........
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
</dependencies>
<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
            .......
        </plugins>
</build>

設置:


image.png

按:ctrl+shift+a

image.png

勾選:
image.png

這樣,你修改了你項目的代碼就不需要點重啟,它會自動幫你部署,但是重啟有一定的延時,但是比重新點擊重啟速度快,至于用不用,完全取決于你自己了。(修改static文件中的靜態html,css,js等不會重新編譯,但是訪問時頁面依然會改變)

2.添加MybatisCodeHelper插件

這個插件直接下載安裝即可(龜速下載,我也很無奈)。作用就是能夠快速的在UserMapper.javaUerMapper.xml之間快速跳轉.

21.png

點擊圖中標記的圖標就可以隨意跳轉了。

lombok插件一樣,此插件也不僅僅這個功能,剩下的你就慢慢探索去吧!

3.打包

編寫完代碼之后,我們就需要將項目進行打包了

22.png

雙擊package,項目根目錄將會出現一個target目錄在此目錄下將會有一個.jar文件,這個就是我們需要的已經打包好了的可執行文件。

注意:我們這個項目使用的spring boot版本為1.5.6.RELEASE(此時最新穩定版本),在運行package時,由于插件也是使用的1.5.6.RELEASE版本,會造成打包失敗(具體原因我也不太清楚,可能是這個版本的插件有問題),所以解決辦法就是修改插件的版本號,此處改為1.5.4.RELEADSE版本。
ps:一遍一遍調試總結出來的結果,我也很無奈呀=-=

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.4.RELEASE</version>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
            .....
</plugins>

下圖標記的地方就是我們需要的jar文件

23.png
4.運行

現在只要有這個jar文件,同時Java的環境,就可以運行這個jar包了。打開cmd,運行命令:

java -jar demo.jar
24.png

服務就啟動了!!!!

當然此命令后面也可以加參數:

java -jar demo.jar --server.port=8888

25.png

運行在8888端口號上,實際上就相當于在application.yml文件中添加如下代碼

server:
  port: 8888

至于想設置其他的什么參數,我想你應該知道怎么做了吧

最后,我已經將此項目分享到GitHub上了,大家可以去download或者clonehttps://github.com/Gitsifu/demo


下面我們在聊聊常見的配置:

server:
  port: 8080
  context-path: /user

port:設置項目啟動的端口號(上面提到了哦!),默認端口號為8080
context-path:設置項目訪問的url路徑根路徑(例如添加了/user則訪問鏈接http://localhost:8080/swagger-ui.html就應該變成這樣的http://localhost:8080/user/swagger-ui.html

。。。。。。此處省略一萬字節。。。。。

有關Spring Boot的基礎學習下面推薦幾篇文章:

微服務開發的入門級框架Spring Boot詳解(一)
微服務開發的入門級框架Spring Boot詳解(二)
微服務開發的入門級框架Spring Boot詳解(三)
微服務開發的入門級框架Spring Boot詳解(四)
微服務開發的入門級框架Spring Boot詳解(五)

好了,現在整個項目的基本架構已經基本完成了,我也該去陪我女朋友了,各位小伙伴再見咯。




哦,對了,我不是沒女朋友么,哪來的女朋友陪,哎。。。還是敲我的代碼去了。。。

誰說我沒對象,new一個就可以了

聲明:原創文章,歡迎轉載,轉載請注明出處,謝謝!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容