mybatis、jstl、log4j搭建自动回复机器人(含知识要点与步骤)

转载请注明出处:
牵手生活--头条新闻:笔记是整理思路方式,分享是一个美德,牵手是我的生活方式
牵手生活--简书:笔记是整理思路方式,分享是一个美德,牵手是我的生活方式

项目效果

机器人聊天url

http://localhost:8080/InitTalkServlet.action
机器人聊天

自动回复指令维护url

http://localhost:8080/List.action
自动回复指令维护

app实现流程

  • javaBean 创建于数据库中表对应的实体
  • dao:实现表对应的增删改查,如MessageDAO是和message表相关的数据库操作
  • service:负责调用对应的dao,并实现与数据库无关的业务逻辑操作。如MessageService调用MessageDAO实现增删改查,并负责一些数据类型转换。
  • servlet:主要是通过调用对应的service,提供http方法方法,并处理web访问的格式(如UTF-8)与参数接收。
  • DbHelper:提供访问数据库辅助。如单例模式DBJdbcHelper提供jdbc方式访问mysql数据库连接对象Connection;DBMybatisHelper(还没改为单例模式)提供mybatis访问数据库的会话SqlSession
app实现流程

用idea创建一个maven 的web项目MicroMessageMybatis

注:如果对idea创建Manven webapp不熟悉,可参见Spring MVC -Hello World(环境搭建)

app 目录结构1
image.png

下面介绍涉及知识

  • Maven
  • mybatis(数据库访问框架)
  • jdbc
  • EL表达式(不介绍)
  • JSTL表达式
  • javaBean
  • Servlet
  • js(不介绍)
  • jquery(不介绍)

下面介绍涉及的工作步骤

  • pom.xml
  • 创建mybatis的辅助类DBMybatisHelper.java
  • 创建jdbc的辅助类DBJdbcHelper.java
  • 配置mybatis配置文件入口.xml文件与不同的mapper对应的.xml
  • 配置日志系统log4j的log4j.properties配置文件
  • 搭建单元测试框架(这里仅用于调试mybatis获取数据功能)
  • 创建不同的javaBean(基本与数据库表一致,涉及到父子表,采用List<子表javaBean>方式定义属性:如 private List<CommandContent> contentList;//一条指令对应的自动回复内容列表
  • 创建与javaBean对应的DAO:处理数据库的相关操作
  • 创建service : 调用DAO跟数据库交互,还有一些业务逻辑需要处理,一般用service一般与servlet对应,被servlet调用
  • 创建不同的servlet:
  • 在web.xml中注册servlet,并配置http访问路径
  • 创建单元测试用例

配置pom.xml 用Maven方式导入到

  • mysql(访问mysql数据库)
  • servlet
  • slf4j(日志系统,用于测试mybatis)
  • mybatis(数据库访问框架)
  • junit单元测试
  • JSTL(这里没有采用Maven的方式配置,而是导入对应的jar包)
JSTL表达式的jar包

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>6.0.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <!--添加Servlet-->

    <!--添加Servlet-->
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.0-b01</version>
      <scope>provided</scope>
    </dependency>

    <!-- slf4j日志处理 应用 log4j 调试动态 SQL-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>


      <!-- 添加mybatis依赖 -->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.2.8</version>
      </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.8.2</version>
    </dependency>

    <!--添加log4j依赖-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.5.6</version>
    </dependency>


  </dependencies>

Mybatis中OGNL表达式

Mybatis中OGNL表达式1
Mybatis中OGNL表达式2

Mybatis配置文件

  • mybatis配置文件入口Configuration.xml(可以是其他文件名称哦)
  • mybatis范围数据库的sql语句与参数配置文件Command.xml;CommandContent.xml;Message.xml
    mybatis的配置文件参考mybatis源码中的例子:


    mybatis配置例子路径

mybatis-3-mybatis-3.4.6\src\test\java\org\apache\ibatis\submitted\complex_property

  • Configuration.xml:用于配置数据库连接
  • User.xml:用于配置对user表的增、删、改、查

注意点:如果xml中有&符合,需要用&转义如

<property name="url" value="jdbc:mysql://**.96.**.27:3306/auth?serverTimezone=UTC&useUnicode=true"/>

需要改为

<property name="url" value="jdbc:mysql://**.96.**.27:3306/auth?serverTimezone=UTC&amp;useUnicode=true"/>
Mybatis配置文件--Configuration.xml
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC">
        <property name="" value=""/>
      </transactionManager>
      <dataSource type="UNPOOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://**.96.**.27:3306/auth?serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="你的密码"/>

      </dataSource>
    </environment>
  </environments>

  <!--mybatis范围数据库的sql语句与参数配置文件-->
  <mappers>
    <mapper resource="sqlMybatisMapping/Message.xml"/>
    <mapper resource="sqlMybatisMapping/Command.xml"/>
    <mapper resource="sqlMybatisMapping/CommandContent.xml"/>
  </mappers>

  
</configuration>
Mybatis配置文件--Message.xml

Message.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Message">

  <resultMap type="com.younghare.micromessage.bean.Message" id="MessageResult">
      <!--数据库主键使用id标签,否则使用result标签;jdbcType对应jdbc中的java.sqlMybatisMapping.Types下的类型-->
    <!--<result column="password" jdbcType="VARCHAR" property="password.encrypted"/>-->
    <id column="ID" jdbcType="INTEGER" property="id"/>
    <result column="COMMAND" jdbcType="VARCHAR" property="command"/>
      <result column="description" jdbcType="VARCHAR" property="description"/>
    <result column="CONTENT" jdbcType="VARCHAR" property="content"/>
  </resultMap>

  <!--配置一个sql语句,让mybatis可以读到并执行
  resultMap:对应java中的javabean:与数据库查询结果对应的
  xml中&不能直接使用必须转&amp; ":也不能直接使用必须用&quot;进行转
  参数配置使用OGNL表达式:&quot表示单引号
  -->
  <!--SELECT * FROM message WHERE id = #{id:INTEGER}-->
  <select id="queryMessageList" parameterType="com.younghare.micromessage.bean.Message" resultMap="MessageResult">
      SELECT ID,COMMAND,DESCRIPTION,CONTENT FROM message where 1=1
      <if test="command !=null and !&quot;&quot;.equals(command.trim())">
        and COMMAND = #{command}</if>
      <if test="description !=null and !&quot;&quot;.equals(description.trim())">
        and DESCRIPTION like '%' #{description} '%'  </if>
  </select>

    <!--单条记录删除-->
    <delete id="deleteOne" parameterType="int">
        DELETE FROM message WHERE ID = #{_parameterType}
    </delete>

    <!--批量记录删除,separator 是分隔符-->
    <delete id="deleteBatch" parameterType="java.util.List">
        DELETE FROM message WHERE ID in (
        <foreach collection="list" item="item" separator=",">
            #{item}
        </foreach>
        )
    </delete>



</mapper>

Mybatis配置文件--父子表Command.xml、CommandContent.xml

Command.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Command">

  <!--
  表返回数据与javaBean的映射关系;涉及到一对多关系
  -->
  <resultMap type="com.younghare.micromessage.bean.Command" id="Command">
      <!--数据库主键使用id标签,否则使用result标签;jdbcType对应jdbc中的java.sqlMybatisMapping.Types下的类型
      collection标签表示主表包含子表的一个集合与javaBean中的Command的CommandContent.Content属性对应;CommandContent的配置信息在CommandContent.xml中
      C_ID 是查询中ID的别名
      -->
      <!--<result column="password" jdbcType="VARCHAR" property="password.encrypted"/>-->
    <id column="C_ID" jdbcType="INTEGER" property="id"/>
    <result column="NAME" jdbcType="VARCHAR" property="name"/>
    <result column="DESCRIPTION" jdbcType="VARCHAR" property="description"/>
    <collection property="contentList"  resultMap="CommandContent.Content"/>
  </resultMap>
    <!--配置一个sql语句,让mybatis可以读到并执行
  resultMap:对应java中的javabean:与数据库查询结果对应的
  xml中&不能直接使用必须转&amp; ":也不能直接使用必须用&quot;进行转
  参数配置使用OGNL表达式:&quot表示单引号
  查询参数使Command实体对象,自动映射对象的属性作为参数如:command.name
  left join 表示无论字表是否有内容,主表的内容必须出来
  -->


  <select id="queryCommandList" parameterType="com.younghare.micromessage.bean.Command" resultMap="Command">
    select a.ID C_ID,a.NAME,a.DESCRIPTION,b.ID,b.CONTENT,b.COMMAND_ID
    from COMMAND a left join COMMAND_CONTENT b
    on a.ID=b.COMMAND_ID
    <where>
        <if test="name != null and !&quot;&quot;.equals(name.trim())">
            and a.NAME=#{name}
        </if>
        <if test="description != null and !&quot;&quot;.equals(description.trim())">
            and a.DESCRIPTION like '%' #{description} '%'
        </if>
    </where>
  </select>
</mapper>

CommandContent.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="CommandContent">
  <resultMap type="com.younghare.micromessage.bean.CommandContent" id="Content">
    <id column="ID" jdbcType="INTEGER" property="id"/>
    <result column="CONTENT" jdbcType="VARCHAR" property="content"/>
    <result column="COMMAND_ID" jdbcType="VARCHAR" property="commandId"/>
  </resultMap>
</mapper>

Mybatis配置文件的读取DBMybatisHelper.sql

public class DBMybatisHelper {
    /**
     * 根据配置文件返回一个mybatis的sqlsession
     * @return
     * @throws IOException
     */
    public SqlSession getSqlSession() throws IOException {
        //通过配置文件获取数据库连接信息,从src的目录开始
        //Reader reader= Resources.getResourceAsReader("com/younghare/micromessage/config/Configuration.xml");
        Reader reader= Resources.getResourceAsReader("Configuration.xml");
        //通过配置信息构建一个SqlSessionFactory
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        //通过sqlSessionFactory打开一个数据库会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    };
}

配置日志系统log4j配置(用于通过日志观察mybatis的sql语句、传递参数)

可以匹配值输出到控制台,也可以log输出到文件

控制台观察日志

log4j.properties

#配置输出到控制台,如果要输出到文件,需要修改这类
log4j.appender.Cons=org.apache.log4j.ConsoleAppender
# 按自己的想法输出
log4j.appender.Cons.layout=org.apache.log4j.PatternLayout
# 自定义输出日志的格式%d:产生日志的时间;%t:产生日志线程的线程名称;%5p:输出日志的级别(5位字符);%c:表示所处类的全名包括包名;%m:日志内容 %n:表示换行
log4j.appender.Cons.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n


# Root logger set to DEBUG、Console using the A2 appender defined above.
#设置log4j输出日志的级别、位置DEBUG、Console
log4j.rootLogger=DEBUG, Cons 
log4j.additivity=false

#key=value的形式进行配置
# 位某个包下配置不同的级别
log4j.logger.com.younghare.micromessage=debug, Cons
log4j.logger.org.springframework=debug, Cons
log4j.additivity.com=false
# 这个包下的输出的是NNFO日志级别
log4j.logger.org.apache=INFO

jdbc 访问mysql辅助类DBJdbcHelper.java

package com.younghare.micromessage.db;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBJdbcHelper {
    private static final String driver = "com.mysql.jdbc.Driver"; //数据库驱动
    //连接数据库的URL地址
    //private static final String url="jdbc:mysql://localhost:3306/phpmyadmin?useUnicode=true&characterEncoding=UTF-8";
    private static final String url="jdbc:mysql://47.96.6.27:3306/auth?useUnicode=true&characterEncoding=UTF-8";
    private static final String username="root";//数据库的用户名
    private static final String password="emailczg";//数据库的密码

    private static Connection conn=null;

    //静态代码块负责加载驱动
    static
    {
        try
        {
            Class.forName(driver);
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

    //单例模式返回数据库连接对象
    public static Connection getConnection() throws Exception
    {
        if(conn==null)
        {
            conn = DriverManager.getConnection(url, username, password);
            return conn;
        }
        return conn;
    }

    public static void main(String[] args) {

        try
        {
            Connection conn = DBJdbcHelper.getConnection();
            if(conn!=null)
            {
                System.out.println("数据库连接正常!");
            }
            else
            {
                System.out.println("数据库连接异常!");
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }

    }
}

javaBean的创建(仅提供Message.java其他不列出来)

Message.java

/**
 * 与指令消息表对应的实体类
 */
public class Message {
    private String id;  //主键
    private String command;  //指令名称
    private String description; //描述
    private String content;   //内容

    public String getId() {
        return id;
    }

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

    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

DAO的创建(仅提供MessageDAO.java其他不列出来)

MessageDAO.java

public class MessageDAO {
    static Logger logger = LoggerFactory.getLogger(MessageDAO.class);; //LogDemo为相关的类

    /**
     * 查询消息列表
     * @param command 指令
     * @param description 描述 --模糊匹配
     * @return  返回消息列表
     */
    public List<Message> queryMessageListByMysql(String command,String description) {
        List<Message> messageList = new ArrayList<>();
        try {

            Connection conn =DBJdbcHelper.getConnection();

            //conn = DriverManager.getConnection(url, username, password);
            String sqlQuery = "SELECT ID,COMMAND,DESCRIPTION,CONTENT FROM message where 1=1";
            StringBuilder sql = new StringBuilder(sqlQuery);
            List<String> paramList = new ArrayList<String>();
            if (command != null && !"".equals(command.trim())){
                sql.append(" and COMMAND = ?");
                paramList.add(command);
            }
            if (description != null && !"".equals(description.trim())){
                sql.append(" and DESCRIPTION like '%?%'");//模糊匹配
                paramList.add(description);
            }
            System.out.println("sqlMybatisMapping:"+sql.toString());


            PreparedStatement statement = conn.prepareStatement(sql.toString());
            for(int i=0;i<paramList.size();i++){
                statement.setString(i+1,paramList.get(i));
                System.out.println(paramList.get(i));
            }

            ResultSet rs = statement.executeQuery();

            while (rs.next()){
                Message message = new Message();
                messageList.add(message);
                message.setId(rs.getString("ID"));
                message.setCommand(rs.getString("COMMAND"));
                message.setDescription(rs.getString("DESCRIPTION"));
                message.setContent(rs.getString("CONTENT"));
            }
            //req.setAttribute("messageList",messageList);

        }catch (ClassNotFoundException e){
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return messageList;
    }


    public List<Message> queryMessageList(String command,String description) {
        List<Message> messageList = new ArrayList<>();
        DBMybatisHelper dbMybatisHelper = new DBMybatisHelper();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbMybatisHelper.getSqlSession();
            Message message = new Message();
            message.setCommand(command);
            message.setDescription(description);
            //通过sqlSession执行SQL语句---Message:mapper namespace="Message";queryMessageList是在Message.xml配置的id
            //messageList = sqlSession.selectList("Message.queryMessageList");//
            messageList = sqlSession.selectList("Message.queryMessageList",message);//

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null){
                sqlSession.close();
            }

        }

        return  messageList;

    }

    /**
     * 删除message中的一条记录
     * @param id
     */
    public  void deleteOne(int id){
        DBMybatisHelper dbMybatisHelper = new DBMybatisHelper();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbMybatisHelper.getSqlSession();
            /*Message.deleteOne是:Message.xml配置的id*/
            sqlSession.delete("Message.deleteOne",id);//
            sqlSession.commit();//增删改都需要commit

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null){
                sqlSession.close();
            }

        }

    }

    /**
     * 删除批量message中的记录
     * @param ids
     */
    public  void deleteBatch(List<Integer> ids){
        DBMybatisHelper dbMybatisHelper = new DBMybatisHelper();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbMybatisHelper.getSqlSession();
            /*Message.deleteOne是:Message.xml配置的id*/
            sqlSession.delete("Message.deleteBatch",ids);//
            sqlSession.commit();//增删改都需要commit

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null){
                sqlSession.close();
            }

        }

    }



}

service的创建(仅提供MessageService.java其他不列出来)

MessageService.java

/**
 * 与ListServlet对应
 * 跟数据库交互之前,还有一些业务逻辑需要处理,一般用service一般与servlet对应,被servlet调用
 */
public class MessageService {

    /**
     * 查询message的记录集合
     * @param command
     * @param description
     * @return
     */
    public List<Message> queryMessageList(String command,String description){
        MessageDAO messageDAO = new MessageDAO();
        return messageDAO.queryMessageList(command,description);
    }
    /**
     * 删除message的某条记录
     * @param id
     */
    public void deleteOne(String  id){
        if (id != null && !"".equals(id.trim())){
            MessageDAO messageDAO = new MessageDAO();
            messageDAO.deleteOne(Integer.valueOf(id));
        }
    }

    /**
     * 删除message的某条记录
     * @param ids
     */
    public void deleteBatch(String[]  ids){
        List<Integer> idList = new ArrayList<Integer>();
        for (String id : ids) {
            idList.add(Integer.valueOf(id));
        }

        MessageDAO messageDAO = new MessageDAO();
        messageDAO.deleteBatch(idList);
    }


}

创建不同的servlet((仅提供ListServlet.java;DeleteOneServlet.java其他不列出来)

ListServlet.java

public class ListServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request,response);


    }

    protected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp)
            throws javax.servlet.ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("UTF-8");
        //接受页面的值
        String command =req.getParameter("command");
        String description = req.getParameter("description");
        //向页面传值
        req.setAttribute("command",command);
        req.setAttribute("description",description);
        
        //查询消息列表,并传递给页面
        MessageService messageService = new MessageService();
        req.setAttribute("messageList", messageService.queryMessageList(command,description));

        //调整页面
        req.getRequestDispatcher("/WEB-INF/jsp/back/list.jsp").forward(req,resp);

    }
}

DeleteOneServlet.java

package com.younghare.micromessage.servlet;

import com.younghare.micromessage.service.MessageService;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.IOException;

/**
 * message单条记录删除控制层
 */
@WebServlet(name = "DeleteOneServlet")
public class DeleteOneServlet extends HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request,response);


    }

    protected void doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp)
            throws javax.servlet.ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("UTF-8");
        //接受页面的值
        String id =req.getParameter("id");
        //查询消息列表,并传递给页面
        MessageService messageService = new MessageService();
        messageService.deleteOne(id);

        //调整页面
        req.getRequestDispatcher("/List.action").forward(req,resp);

    }
}

在web.xml中注册servlet,并配置http访问路径

<web-app>
...
    <servlet>
        <servlet-name>ListServlet</servlet-name>
        <servlet-class>com.younghare.micromessage.servlet.ListServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>DeleteOneServlet</servlet-name>
        <servlet-class>com.younghare.micromessage.servlet.DeleteOneServlet</servlet-class>
    </servlet>

...

    <!--http://localhost:8080/List.action-->
    <servlet-mapping>
        <servlet-name>ListServlet</servlet-name>
        <url-pattern>/List.action</url-pattern>
    </servlet-mapping>

    <!--http://localhost:8080/DeleteOneServlet.action-->
    <servlet-mapping>
        <servlet-name>DeleteOneServlet</servlet-name>
        <url-pattern>/DeleteOneServlet.action</url-pattern>
    </servlet-mapping>

...
</web-app>

创建单元测试用例MessageDAOTest

MessageDAOTest.java

import com.younghare.micromessage.bean.Message;
import org.junit.Test;

import java.util.List;

public class MessageDAOTest {
    @Test
    public void testqueryMessageList() {
        MessageDAO messageDAO = new MessageDAO();
        List<Message> messages = messageDAO.queryMessageList("","精");
        System.out.println("记录数:"+messages.size());
    }

    @Test
    public void testqueryMessageListByMysql() {
        MessageDAO messageDAO = new MessageDAO();
        List<Message> messages =  messageDAO.queryMessageListByMysql("","");
        System.out.println("记录数:"+messages.size());

    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容