JavaEE Mybatis使用

1. Mybatis官网

下载地址
解压之后的内容:

图1.png

Mybatis框架结构:


图2.png

简要概述:

  • SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句,此文件需要在SqlMapConfig.xml中加载。
  • 通过mybatis环境等配置信息构造SqlSessionFactory(即会话工厂)。
  • 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
  • mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
  • MappedStatement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个MappedStatement对象,sql的id即是MappedStatement的id。
  • MappedStatement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是JDBC编程中对preparedStatement设置参数。
  • MappedStatement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于JDBC编程中对结果的解析处理过程。

2. 导入数据库表

1). 使用Navicat工具,在root上右键选择新建数据库

图3.png

2). 新建数据库->确定
图4.png

3). 打开数据库mybatis->在mybatis/表处单击右键选择运行SQL文件...
图5.png

4). 选择桌面的sql文件->点击开始
图6.png

mybatis.sql文件内容

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `orders`
-- ----------------------------
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下单用户id',
  `number` varchar(32) NOT NULL COMMENT '订单号',
  `createtime` datetime NOT NULL COMMENT '创建订单时间',
  `note` varchar(100) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');
INSERT INTO `user` VALUES ('26', '王五', null, null, null);

5). 导入成功后,刷新表,数据如下:


图7.png

3. 测试

1). 创建新的Java工程,并导入Mybatis使用的java包,注意要导入对应的数据库驱动包(这里导入的是mysql-connector-java-5.1.42-bin.jar)


图7.png

2). 在工程目录下创建一个源码包config,并在config包下创建sqlmap包、log4j.properties和SqlMapConfig.xml文件。


图8.png

log4j.properties文件内容

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

SqlMapConfig.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>
    <!-- 和spring整合后environments配置将废除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
</configuration>

SqlMapConfig.xml是mybatis的核心配置文件,以上文件的配置内容为数据源、事务管理。
注意:等后面mybatis和Spring两个框架整合之后,environments的配置将被废除.
3). 创建一个po类--User
po类作为mybatis进行sql映射使用,po类通常与数据库表对应,User.java文件的内容如下:

public class User {
    // id
    private int id;
    // 用户名
    private String username;
    // 性别
    private String sex;
    // 用户名
    private Date birthday;
    // 地址
    private String address;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
                + address + "]";
    }
    
}

4). 在classpath下的sqlmap目录下创建sql映射文件user.xml
user.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="test">

</mapper>
  • namespace:即命名空间,其用于隔离sql语句(即不同sql映射文件中的两个相同id的sql语句如何来区分)

5). 加载映射文件
mybatis框架需要加载映射文件,将user.xml添加在SqlMapConfig.xml中.
在SqlMapConfig.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>
    <!-- 和spring整合后environments配置将废除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    
    <!-- 添加的内容 -->
    <mappers>
        <!-- resource是基于classpath来查找的 -->
        <mapper resource="sqlmap/user.xml"/>
    </mappers>
</configuration>

6). 入门程序测试——根据id查询用户信息
I. user.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="test">
    <!-- 根据id获取用户信息,
        parameterType: 查询参数的数据类型,即定义输入到sql中的映射类型
        resultType: 查询结果的数据类型,如果是pojo则该给出全路径
        #{id}表示使用PreparedStatement设置占位符号并将输入变量id传到sql中,#{}作用就是占位符,相当于JDBC中的? 
     -->
    <select id="getUserById" parameterType="int" resultType="com.mazaiting.po.User">
        select * from user where id = #{id};
    </select>
</mapper>

II. 编写MybatisTest类

public class MybatisTest {
    
    @Test
    public void testGetUserById() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        SqlSessionFactory factory = builder.build(inputStream);
        // 4. 创建SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 5. 使用SqlSession对象执行查询,得到User对象
        // 第一个参数: 执行查询的StatementId,即配置文件user.xml中的id, 第二参数传入id对应的值
        User user = sqlSession.selectOne("getUserById", 10);
        // 6. 打印结果
        System.out.println(user);
        // 7. 释放资源
        sqlSession.close();
    }
}

III. 执行测试代码, 打印结果:


图9.png

IV. 优化代码
一般来讲工厂对象一般在实际开发是单例的,并不需要频繁地创建

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    @Test
    public void testGetUserById() {
        // 4. 创建SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 5. 使用SqlSession对象执行查询,得到User对象
        // 第一个参数: 执行查询的StatementId,即配置文件user.xml中的id, 第二参数传入id对应的值
        User user = sqlSession.selectOne("getUserById", 10);
        // 6. 打印结果
        System.out.println(user);
        // 7. 释放资源
        sqlSession.close();
    }

}

7). 根据用户名称模糊查询用户信息列表
I. user.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="test">   
    <!-- 如果查询结果返回的是List集合,那么resultType只需要设置为List集合中的一个元素的数据类型 -->
    <select id="getUserByName" parameterType="string" resultType="com.mazaiting.po.User">
        select * from user where username like #{username}
    </select>
</mapper>

II. 编写测试方法

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    @Test
    public void testGetUserByName() {
        SqlSession session = factory.openSession();
        List<User> list = session.selectList("getUserByName", "%张%");
        for (User user : list) {
            System.out.println(user.toString());
        }
        session.close();
    }
}

III. 执行测试方法,打印结果:


图10.png

IV. 另一个中不建议使用的占位符方式

<?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="test">
        <!-- 如果查询结果返回的是List集合,那么resultType只需要设置为List集合中的一个元素的数据类型 -->
    <select id="getUserByName1" parameterType="string" resultType="com.mazaiting.po.User">
        select * from user where username like '%${value}%'
    </select>
</mapper>

测试代码:

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    @Test
    public void testGetUserByName1() {
        SqlSession session = factory.openSession();
        List<User> list = session.selectList("getUserByName1", "张");
        for (User user : list) {
            System.out.println(user.toString());
        }
        session.close();
    }

}

图11.png

不推荐使用:原因容易引起SQL注入。

总结

---{}和${}

1). #{}:表示一个占位符号,可以很好地去避免sql注入。其原理是将占位符位置的整个参数和sql语句两部分提交给数据库,数据库去执行sql语句,去表中匹配所有的记录是否和整个参数是否一致。
#{}要获取输入参数的值:

  • 如果输入参数是简单数据类型,则#{}中可以写value或其它名称。
  • 如果输入参数是pojo对象类型,则#{}可通过OGNL方式去获取,表达式就是属性.属性.属性....方式。

2). ${}表示一个sql拼接符号,其原理是在向数据库发出sql之前去拼接好sql再提交给数据库执行。
${}要获取输入参数的值:

  • 如果输入参数是简单数据类型,则${}中只能写value。
  • 如果输入参数是pojo对象类型,则${}可通过OGNL方式去获取,表达式就是属性.属性.属性....方式。

一般情况下建议使用#{},特殊情况下必须要用${},比如:

1>. 动态拼接sql中动态组成排序字段,要通过${}将排序字段传入sql中。
2>. 动态拼接sql中动态组成表名,要通过${}将表名传入sql中。

---parameterType和resultType
  • parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
  • resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。
---selectOne()和selectList()方法
  • selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常.
  • selectList可以查询一条或多条记录。

4. 其他操作

1). 插入数据
I. user.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="test">
    <!-- 插入数据 -->
    <insert id="addUser" parameterType="com.mazaiting.po.User">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>

如果输入参数是pojo,那么#{}中的名称就是pojo类中的属性(用到了对象图导航的思想)
II. 编写测试代码

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    @Test
    public void testAddUser() {
        // 创建Session对象
        SqlSession session = factory.openSession();
        // 创建对象
        User user = new User();
        user.setUsername("mazaiting");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("科学院");
        
        // 插入数据
        session.insert("addUser", user);
        // 关闭Session
        session.close();
    }
}

III. 执行测试代码,打印结果:
可以看出虽然执行了sql语句,但是事务并没有提交,而是回滚了。


图12.png

IV. 因此,应将测试代码修改为

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    @Test
    public void testAddUser() {
        // 创建Session对象
        SqlSession session = factory.openSession();
        // 创建对象
        User user = new User();
        user.setUsername("mazaiting");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("科学院");
        
        // 插入数据
        session.insert("addUser", user);
        // 提交事务
        session.commit();
        // 关闭Session
        session.close();
    }

}

V. 执行单元测试,打印结果:


图13.png

2). 自增主键返回

  • LAST_INSERT_ID():返回auto_increment自增列新记录id值。该函数是在当前事务下取到你最后生成的id值,而我们应知道查询操作是没有开启事务的,增删改操作是需要开启事务的。

I. 在user.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="test">   
    <!-- 插入数据,返回主键 -->
    <insert id="addUser" parameterType="com.mazaiting.po.User">
        <selectKey keyProperty="id" resultType="int" order="AFTER">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>
  • keyProperty:返回的主键存储在pojo中的哪个属性(即其对应pojo的主键属性)。获取主键,实际上是将主键取出来之后封装到了pojo的主键属性当中。
  • resultType:返回的主键是什么类型(即其对应pojo的主键的数据类型)。
  • order:selectKey的执行顺序,是相对于insert语句来说的,由于mysql的自增原理,执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为AFTER。

II. 添加测试代码

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    @Test
    public void testAddUser1() {
        // 创建Session对象
        SqlSession session = factory.openSession();
        // 创建对象
        User user = new User();
        user.setUsername("mazaiting");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("科学院");
        
        // 插入数据
        session.insert("addUser1", user);
        System.out.println("插入的id:" + user.getId());
        // 提交事务
        session.commit();
        // 关闭Session
        session.close();
    }
}

III. 执行测试代码,打印结果:


图14.png

3). 删除用户
I. user.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="test">
    <!-- 删除数据 -->
    <delete id="deleteUser" parameterType="int">
        delete from user where id = #{id}
    </delete>
    
</mapper>

II. 测试代码

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    @Test
    public void testDeleteUser() {
        // 创建会话
        SqlSession session = factory.openSession();
        // 删除数据
        session.delete("deleteUser", 29);
        // 提交事务
        session.commit();
        // 关闭会话
        session.close();
    }

}

III. 打印结果:


图15.png

4). 更新数据
I. user.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="test">   
    <!-- 修改用户信息 -->
    <update id="updateUser" parameterType="com.mazaiting.po.User">
        update user set username = #{username} where id = #{id}
    </update>
</mapper>

II. 测试代码

public class MybatisTest {
    private SqlSessionFactory factory;
    
    @Before
    public void init() throws IOException {
        // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 2. 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 3. 创建SqlSessionFactory对象
        factory = builder.build(inputStream);
    }
    
    public void testUpdateUser(){
        // 创建会话
        SqlSession session = factory.openSession();
        User user = new User();
        user.setId(10);
        user.setUsername("张某某");
        // 更新数据
        session.update("updateUser", user);
        // 提交事务
        session.commit();
        // 关闭会话
        session.close();
    }
}

III. 打印结果:


图16.png

5. Mybatis与Hibernate不同

  • MyBatis学习成本低,入门门槛低。MyBatis需要程序员自己写sql,对sql修改和优化就比较灵活。MyBatis是不完全的ORM框架,MyBatis需要程序员编写sql,但是MyBatis也存在映射(输入映射、输出映射)适用场景:需求变化较快的项目开发,比如互联网项目、电商。
  • Hibernate学习成本高,入门门槛高,Hibernate是ORM框架,不需要程序员编写sql,自动根据对象映射生成sql。适用场景:需求固定的中小型项目,如OA系统、ERP系统。

代码下载

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

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,288评论 0 4
  • Java数据持久化之mybatis 一. mybatis简介 1.1 原始的JDBC操作: Java 通过 Jav...
    小Q逛逛阅读 4,822评论 0 16
  • 非本人总结的笔记,抄点笔记复习复习。感谢传智博客及黑马程序猿成长 什么是Mybatis ​ MyBatis 本...
    键盘瞎阅读 1,248评论 0 4
  • #创建文件,打开文件 w:创建文件 # fp = open("hello.txt","w") # fp.write...
    lqkin阅读 215评论 0 0
  • ①uint3复习✔ ②uint3视频课✔ ③kk每日一句✔ ④泛读一篇✔ ⑤实验报告物化(抄写)✘ ⑥uint4视...
    小米Ariel阅读 158评论 0 0