Mybatis---01

Mybatis 重点

1、概述及地位

​ 官网:http://www.mybatis.org/mybatis-3/zh/index.html

1.1 框架

​ 一个半成品的项目,我们使用该项目,进行二次开发,能够提高开发效率

2.1 是一个 ORM 框架

​ 对象关系映射

​ 数据库表名 JavaBean类名

​ 字段名(列名) 属性名

​ 记录(行) 对象

2.3 角色:Dao层

​ 与 数据库进行 交互,封装的是 JDBC 的实现

2、基于配置文件开发

1、开发环境搭建

1. 新建maven 打包方式jar
2. 导入依赖
3. 配置文件    
    主配置文件  SqlMapConfig.xml      配置mybatis所需要的环境
    Sql映射文件   接口名.xml          管理sql语句
        1、XML文件必须跟接口在同一个目录中
        2、XML文件中 mapper节点的namespace属性的值必须是 接口的全限定类名
        3、select标签的 id属性的值为 接口的方法名
        4、resultType 值为 接口方法的返回值,若返回集合,则指定集合中元素的全类名
        5、paramterType 值为 接口方法的形参类型。该参数可以省略不写
4. 编写与数据库表对应的 JavaBean
5. 编写 dao 接口
6. 建立 dao接口与Sql映射文件的关系
7. 测试

​ 备注:可参考官方文档(别死记硬背)

2、核心配置文件

​ 现在掌握,将来了解(学会 Spring后),整合 Spring 后,可以是一个空文件,甚至没有

3、sql 映射文件

精通:常用标签、属性

​ 标签:mapper、select、insert、update、delete、resultMap、sql、include、cache、selectKey

​ select 标签

​ 查询所有

<?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="dao接口全限定类名">
    <!--List<User> findAll();-->
    <!--配置查询所有-->
    <select id="dao接口的方法名" resultType="JavaBean的全限定类名">
        select * from user <!--原生SQL语句-->
    </select>
</mapper>

​ 查询单个

<select id="dao接口的方法名" resultType="JavaBean的全限定类名">
     select * from user where id = #{id}
</select>

​ 模糊查询

<select id="dao接口的方法名" resultType="JavaBean的全限定类名">
     select * from user where username like #{username}
</select>
<!-- 当调用接口方法时,需要为传入参数前后加上 %,如 username="%王%" -->

​ 查询返回单行单列,返回一个值

<select id="dao接口的方法名" resultType="long">
     select count(1) from user
</select>

​ insert 标签

​ 子标签:selectKey

<!--
    insert: 代表新增
    parameterType:可以省略不写,推荐写上
-->
<insert id="接口方法名" parameterType="接口方法中形参的全类名">
    <!-- 
        keyProperty : 返回的值 赋值给 JavaBean 的哪个属性
        keyColumn : 返回的哪个列的值
        resultType : select LAST_INSERT_ID() 返回值类型
        order 表示 : select LAST_INSERT_ID() 的执行时机 
            AFTER 代表在插入语句执行成功之后执行   适用场景:自增主键
            BEFORE 代表在插入语句执行之前执行    适用场景:非自增主键,主键是UUID()获取的字符串
    -->
    <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
        select LAST_INSERT_ID()
    </selectKey>
     <!-- user 是表名 -->
    insert into user (username,address) values (#{username},#{address})
</insert>

<!-- 
    返回自增主键值的另一种写法
    useGeneratedKeys : 是否支持主键自增    true : 支持    false : 不支持
    keyProperty : 返回的值 赋值给 JavaBean 的哪个属性
    keyColumn : 返回的哪个列的值
    * 该方式支持 批量插入返回主键
-->
<insert id="saveReturnId" parameterType="com.itheima.domain.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    INSERT INTO USER (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
</insert>

<!-- 
    返回非自增主键的值
    以 UUID() 为例
-->
<insert id="接口方法名" parameterType="com.itheima.domain.User">
    <!-- BEFORE 代表在插入语句执行之前  执行    用于主键是 UUID() 的情况 -->
    <selectKey keyProperty="id" keyColumn="id" resultType="string" order="BEFORE">
        select UUID()
    </selectKey>
     <!-- user_info 是表名 -->
    insert into user_info (id,username) values (#{id},#{username})
</insert>

​ 修改和删除

<!-- 更新用户 -->
<update id="updateUser" parameterType="com.itheima.domain.User">
    update user set username=#{username},address=#{address},sex=#{sex},
        birthday=#{birthday} where id=#{id}
</update>

<!-- 删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
    <!--
        当入参参数为 8大基本数据类型或其包装类型,还有 String 类型时,入参参数在 sql映射文件中,
    使用ONGL表达式取值,可以指定随意名称,只表示占位符,但是推荐使用方法形参名,提高可读性
    -->
    delete from user where id = #{id}
</delete>

select :

​ 需求:查询的结果集列名 跟 属性名 不一致的情况下,我们需要进行映射

​ 第一种方式:可以把 查询结果集的列名 取 别名(跟 javabean 属性名一致)

<select id="findAll" resultType="com.itheima.domain.User">
    select id as userId,username as userName,address as userAddress,sex as userSex,
        birthday as userBirthday from user
</select>

​ 第二种方式 :使用 resultMap 自定义结果集映射

​ 手动指定 主键列名 与 普通列名 跟 javabean 属性进行一一映射

​ (就算结果集列名跟属性名一致,推荐也是进行映射)

<!--自定义结果集
    1. resultMap
        id:唯一标识,用于被 select 标签中的 resultMap 属性所引用
        type:指当前结果集中的列名跟哪个 JavaBean 的属性去对应,最终映射到哪个 JavaBean 中
    2. 子标签:
        id: 代表映射主键列名
            property: JavaBean中的属性名
            column:结果集列名
        result:映射普通列
            property: JavaBean中的属性名
            column:结果集列名
-->
<!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
<resultMap id="userMap" type="com.itheima.domain.User">
    <!-- 主键字段的对应 -->
    <id property="userId" column="id"></id>
    <!--非主键字段的对应-->
    <result property="userName" column="username"></result>
    <result property="userAddress" column="address"></result>
    <result property="userSex" column="sex"></result>
    <result property="userBirthday" column="birthday"></result>
</resultMap>
<select id="findAll" resultMap="userMap">    
    select * from user
</select>

​ sql 的子节点:if、where、foreach、trim、set、choose、when、otherwise

​ 属性:namespace、id、resultType、resultMap、parameterType

备注:可以参看逆向工程生成的文件

4、输入映射 (参数封装)parameterType

​ 简单参数(8大基本数据类型或其包装类型,还有 String 类型)

​ #{key} key随意,一般key与形参名称一致

​ pojo #{key} key名必须与 pojo 的属性名一致,具体参看 增删改配置

​ 包装 pojo(QueryVo) 参数名必须与 包装 pojo 的属性一致(可以使用 . 的形式访问其属性)

​ #{user.username} 该 user 是 queryVo 的一个属性, username 是 user 的一个属性

​ 上述ONGL表达式获取到的是 QueryVo中的user中的 username 的值

​ 例如:

class QueryVo{
    private User user;
    //省略 getter/setter 方法
}

​ @param注解 多个参数前,使用@param("name") 修饰形参,在 xml 中使用 #{name} 映射绑定形参

​ 例如:

<!--
    UserInfo login(@Param("username") String username, @Param("password")String password);
        @Param("key") 该注解为入参参数指定 key    #{key}
-->
<select id="login" resultType="com.itheima.domain.UserInfo">
    SELECT * FROM user_info where username = #{username} and password = #{password}
</select>

5、输出映射(结果封装)

resultType:底层是 resultMap

​ 简单类型:int、double、String 等,直接返回 类型全类名 或者 别名

​ 譬如:int、java.lang.String 等

​ pojo:可以是全类名,也可以是别名。推荐使用全类名:包名.类名

​ 譬如:com.itheima.domain.User

​ List 集合:是集合中元素的具体类型,格式同 pojo

​ map集合:java.util.map 或者 map

resultMap

​ 查询结果集与映射pojo属性不一致时,可以使用resultMap指定结果集列名与pojo的属性名进行手动映射

<!--自定义结果集
    1. resultMap
        id:唯一标识,用于被 select 标签中的 resultMap 属性所引用
        type:指当前结果集中的列名跟哪个 JavaBean 的属性去对应
    2. 子标签:
        id: 代表映射主键列名
            property: JavaBean中的属性名
            column:结果集列名
        result:映射普通列
            property: JavaBean中的属性名
            column:结果集列名
-->
<!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
<resultMap id="userMap" type="com.itheima.domain.User">
    <!-- 主键字段的对应 -->
    <id property="userId" column="id"></id>
    <!--非主键字段的对应-->
    <result property="userName" column="username"></result>
    <result property="userAddress" column="address"></result>
    <result property="userSex" column="sex"></result>
    <result property="userBirthday" column="birthday"></result>
</resultMap>

​ 后期还可以映射关联关系

​ 一对一:association

​ 一对多:collection

6、动态sql

​ if、where、foreach、sql片段

​ if 、 where

<!--
    List<User> findByCondition(User user);
-->
<select id="findByCondition" parameterType="com.itheima.domain.User" resultType="com.itheima.domain.User">
    select * from user
    <where>
        <if test="username != null and username != ''">
            and username = #{username}
        </if>
    <!--
        3.4.5 不支持以下写法
             <if test="sex == '男' or sex == '女'">
                 and sex = #{sex}
             </if>
    -->
        <!-- 单引号中包含 双引号的形式 -->
        <!--
            <if test='sex == "男" or sex == "女"'>
                and sex = #{sex}
            </if>
        -->

        <!-- 把 传入的值 使用 toString() 转成 字符串 -->
        <if test="sex == '男'.toString() or sex == '女'.toString()">
            and sex = #{sex}
        </if>
    </where>
</select>
<!--
    where 会自动过滤其中条件成立的多余最前面的 and 或者 or
    if
       test 表示条件判断
       写的是 ognl 表达式,其中 判断的参数为 Javabean 的属性名
       注意 :不能写特殊符号   譬如  &&  >  <
       等值判断写法,需要是 单引号中包含 双引号的形式
    -->

​ foreach

<!--
    foreach  循环
        collection :  循环的集合
        item : 当前正在遍历的对象
        open : 开始的部分
        close : 结束的部分 
        separator : 当前正在遍历的每个对象之间的分隔符
-->
<!--
    List<User> findByIds(@Param("ids") List<Integer> ids);
-->
<select id="findByIds" parameterType="list" resultType="com.itheima.domain.User">
    select * from user
    <where>
        <if test="ids != null and ids.size() > 0">
            <foreach collection="ids" item="userId" open="and id in (" close=")" separator=",">
                #{userId}
            </foreach>
        </if>
    </where>
</select>

<!--
    int saveManyUser(@Param("users") List<User> users);
    判断 集合是否为空,可以在 service 层进行业务处理
-->
<insert id="saveManyUser" parameterType="list">
    INSERT INTO USER (username,birthday,sex,address) VALUES
    <foreach collection="users" item="user" open="" close="" separator=",">
        (#{user.username},#{user.birthday},#{user.sex},#{user.address})
    </foreach>
</insert>

​ trim

<!--
    trim
        prefix : 条件拼接成立后要加的 前缀
        prefixOverrides : 条件拼接成立后要去掉的前面多余的 字符串
        suffix : 条件拼接成立后要加的 后缀
        suffixOverrides : 条件拼接成立后要去掉的后面多余的 字符串
-->
<select id="findByCondition" parameterType="com.itheima.domain.User" resultType="com.itheima.domain.User">
    select * from user
    <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and">
        <if test="username != null and username != ''">
            username = #{username} and
        </if>
        <if test="sex != null and sex != ''">
            sex = #{sex} and
        </if>
    </trim>
</select>

​ set

<!--
    set : 只能用于 update 标签中
        会自动过滤条件成立 多余的部分(,)
-->
<update id="updateUser" parameterType="com.itheima.domain.User">
    UPDATE USER
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="birthday != null">
            birthday = #{birthday},
        </if>
        <if test="sex != null">
            sex = #{sex},
        </if>
        <if test="address != null">
            address = #{address},
        </if>
    </set>
    <where>
        <if test="id != null">
            id = #{id}
        </if>
    </where>
</update>

​ sql 片段

<!-- 定义 sql片段,该片段可以是 mapper.xml 中的任何内容 -->
<sql id="base_column">
  username,birthday,sex,address
</sql>

<!--
    int saveManyUser(@Param("users") List<User> users);
    判断 集合中是否为空,可以在 service 层进行业务处理
-->
<insert id="saveManyUser" parameterType="list">
    INSERT INTO USER (
    <!-- include 标签 的 refid 属性用于引用 当前 mapper.xml 中已经定义的 sql 片段 -->
      <include refid="base_column"></include>
    ) VALUES
    <foreach collection="users" item="user" open="" close="" separator=",">
        (#{user.username},#{user.birthday},#{user.sex},#{user.address})
    </foreach>
</insert>

7、关联关系

​ 根据具体业务需要分析表与表之间的关系(实体与实体之间的关系)

​ 使用 resultMap 进行映射。

​ 一对一(多对一):association

​ javaType:指定具体关联的属性类型

<!--
    自定义结果集封装
        映射 一对一 或者 多对一
-->
<resultMap id="accountAndUserResultMap" type="com.itheima.domain.Account">
    <!--
         帐户信息 封装成功
    -->
    <id property="id" column="id"></id>
    <result property="money" column="money"></result>
    <result property="uid" column="uid"></result>
    <!--
        association : 映射 一对一 的关联关系
            property : 关联信息的 属性
            column : 关联属性对应的列名
            javaType : 关联属性的具体类型
    -->
    <association property="user" column="uid" javaType="com.itheima.domain.User">
        <id property="id" column="uid"></id>
        <result property="username" column="username"/>
        <result property="birthday" column="birthday"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
    </association>
</resultMap>

<!--
    List<Account> findAccountAndUser();
-->
<select id="findAccountAndUser" resultMap="accountAndUserResultMap">
    SELECT
      a.id,
      a.money,
      u.id uid,
      u.username,
      u.birthday,
      u.sex,
      u.address
    FROM
      account a
      LEFT JOIN USER u
        ON a.uid = u.id
</select>

​ 一对多:collection

​ ofType:指定具体关联的集合中元素的类型

<!--
     resultMap 标签可以被继承 extends="baseResultMap"
            baseResultMap 是指 mapper.xml 中某一个 resultMap 的 id
-->
<resultMap id="userAndAccountsResultMap" type="com.itheima.domain.User">
    <id property="id" column="id"></id>
    <result property="username" column="username"/>
    <result property="birthday" column="birthday"/>
    <result property="sex" column="sex"/>
    <result property="address" column="address"/>
    <!--
        collection : 映射一对多关联关系
        property : 关联信息的 属性
        column : 关联属性对应的列名
        javaType : 关联属性的类型
        ofType : 集合中元素的具体类型
    -->
    <collection property="accounts" column="id" ofType="com.itheima.domain.Account">
        <id property="id" column="aid"></id>
        <result property="money" column="money"></result>
        <result property="uid" column="uid"></result>
    </collection>
</resultMap>

<!--
    List<User> findUserAndAccounts();
-->
<select id="findUserAndAccounts" resultMap="userAndAccountsResultMap">
    SELECT
      u.id,
      u.username,
      u.birthday,
      u.sex,
      u.address,
      a.id aid,
      a.money,
      a.uid
    FROM
      USER u
      LEFT JOIN
      account a
        ON a.uid = u.id
</select>

​ 多对多映射:collection,在 mybatis 中其实也是看成 一对多

​ 需要借助 中间表

​ userid roleid 联合主键

​ 1 1

​ 2 1

​ 1 2


<!--定义role表的ResultMap-->
<resultMap id="roleMap" type="role">
    <id property="roleId" column="rid"></id>
    <result property="roleName" column="role_name"></result>
    <result property="roleDesc" column="role_desc"></result>
    <collection property="users" ofType="user">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="address" property="address"></result>
        <result column="sex" property="sex"></result>
        <result column="birthday" property="birthday"></result>
    </collection>
</resultMap>

<!--
    查询所有
    List<Role> findAll();
-->
<select id="findAll" resultMap="roleMap">
   select u.*,r.id as rid,r.role_name,r.role_desc from role r
    left outer join user_role ur  on r.id = ur.rid
    left outer join user u on u.id = ur.uid
</select>

8、延迟加载(懒加载)

​ 在关联查询的基础上才可能出现延迟加载(发送两条或两条以上的SQL)

​ 多对一(一对一)或者一对多 都可以使用懒加载

​ AccountPlusMapper.java

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 */
public interface AccountPlusMapper {

    /**
     * 查询帐户关联用户信息
     * @return
     */
    List<Account> findAll();
    
    /**
     * 根据用户id查询账户列表
     * @param id
     * @return
     */
    List<Account> findByUid(Integer uid);
}

​ UserPlusMapper.java

/**
 * 也是操作 User类的持久化接口
 * @author ghy
 */
public interface UserPlusMapper {

    /**
     * 根据 id 查询用户
     * @param id
     * @return
     */
    User findById(Integer id);

    /**
     * 更新
     * 没有返回值
     * @param user
     */
    void update(User user);

}

​ 一对一 UserPlusMapper.xml

​ 查询 账户时,关联查询用户信息(用户信息实现延迟加载)

<resultMap id="baseResultMap" type="com.itheima.domain.Account">
    <id property="id" column="id"></id>
    <result property="money" column="money"></result>
    <result property="uid" column="uid"></result>
    <!--
        select : 指定要执行的查询 SQL 语句所在的 statementId
        column : 指的是 select 属性的值所需要的参数
        fetchType : 抓取策略   
            lazy : 延迟加载   eager : 立即加载
    -->
    <association property="user" javaType="com.itheima.domain.User" column="uid"
                 select="com.itheima.dao.UserPlusMapper.findById" fetchType="lazy"></association>
</resultMap>

<!--
    List<Account> findAll();
-->
<select id="findAll" resultMap="baseResultMap">
    SELECT * FROM account
</select>
<!--
    List<Account> findByUid(Integer uid);
-->
<select id="findByUid" resultMap="baseResultMap">
    SELECT * FROM account where uid = #{uid}
</select>

​ 需要在全局配置文件中配置延迟加载

<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>

​ 一对多 UserPlusMapper.xml

<resultMap id="baseResultMap" type="com.itheima.domain.User">
    <id property="id" column="id"></id>
    <result property="username" column="username"/>
    <result property="birthday" column="birthday"/>
    <result property="sex" column="sex"/>
    <result property="address" column="address"/>
    <collection property="accounts" column="id" javaType="list" ofType="com.itheima.domain.Account"
        select="com.itheima.dao.AccountPlusMapper.findByUid" fetchType="eager"></collection>
</resultMap>

<!--
    User findById(Integer id);
-->
<select id="findById" resultMap="baseResultMap">
    SELECT * FROM USER WHERE id = #{id}
</select>

<update id="update">
    UPDATE USER SET username = #{username},birthday=#{birthday},sex=#{sex},address=#{address} WHERE id = #{id}
</update>

9、缓存

/**
 * 测试一级缓存
 *      注意:只有两次相同查询操作才会有缓存.
 *  1.二级缓存是 SqlSession 级别,也就是只有同一个 SqlSession 才具备相同的缓存。一级缓存存放的数据是 对象的副本
 *  2.一级缓存默认开启,程序员无法关闭。一级缓存的介质通常是内存
 *
 *  3.当 SqlSession 对象执行以上方法时,缓存失效
 *      close
 *      clearCache
 *      commit
 *      增删改方法,不管是否提交事务
 */
@Test
public void testFirstLevelCache(){
    User u1 = userPlusMapper.findById(88);
    System.out.println(u1);

    //session.commit();
    User user = new User();
    user.setId(87);
    user.setUsername("87改一下");
    userPlusMapper.update(user);


    User u2 = userPlusMapper.findById(88);
    System.out.println(u2);
    System.out.println(u1 == u2);
}


/**
 * 测试二级缓存
 *      注意:在 SqlSession 关闭之后,数据才会保存到二级缓存中
 *      1.二级缓存是 SqlSessionFactory 级别,由同一个 SqlSessionFactory 生产的 SqlSession 共享一个二级缓存。
 *          二级缓存存放的数据是 散装数据
 *      2.二级缓存默认开启(3.4.5版本,之前的版本默认是有关闭的),程序员可以手动开启。二级缓存的介质可以是内存或者硬盘
 *      3.二级缓存使用步骤
 *          3.1 要缓存的类必须实现 Serializable 接口
 *          3.2 全局配置文件中开启
 *          3.3 在要使用二级缓存的 Mapper.xml文件中 使用 <cache/>
 *
 *  当用户发送查询需求时,查询操作是怎么执行的?
 */
@Test
public void testSecondLevelCache(){
    SqlSession session1 = sqlSessionFactory.openSession();
    UserPlusMapper userPlusMapper1 = session1.getMapper(UserPlusMapper.class);
    User user1 = userPlusMapper1.findById(79);
    session1.close();

    SqlSession session2 = sqlSessionFactory.openSession();
    UserPlusMapper userPlusMapper2 = session2.getMapper(UserPlusMapper.class);
    User user2 = userPlusMapper2.findById(79);
    session2.close();

    System.out.println(user1 == user2); // false
}

[图片上传失败...(image-a8f13e-1569651548520)]

​ 面试题:

​ 一级缓存跟二级缓存的区别?

3、基于注解开发

  • @Insert:实现新增
  • @Update:实现更新
  • @Delete:实现删除
  • @Select:实现查询
  • @Result:实现结果集封装
  • @Results:可以与@Result 一起使用,封装多个结果集 (等同于 xml 中的 ResultMap)
  • @ResultMap:实现引用@Results 定义的封装
  • @One:实现一对一结果集封装
  • @Many:实现一对多结果集封装
  • @SelectProvider: 实现动态 SQL 映射
  • @CacheNamespace:实现注解二级缓存的使用

​ 一对一

/**
 * 查询所有账户,并且获取每个账户所属的用户信息
 * @return
 */
@Select("select * from account")
@Results(id="accountMap",value = {
        @Result(id=true,column = "id",property = "id"),
        @Result(column = "uid",property = "uid"),
        @Result(column = "money",property = "money"),
        @Result(property = "user",column = "uid",
                one=@One(select="com.itheima.dao.IUserDao.findById",fetchType= FetchType.EAGER))
})
List<Account> findAll();

​ 一对多

/**
 * @Results  等同于 Sql映射文件(mapper.xml) 中 resultMap 节点
 *      id : 唯一标识,以便其他@Select注解标记的方法引用结果集
 *          等同于 Sql映射文件(mapper.xml) 中 resultMap 节点中的 id属性
 *      value : 指定如何映射结果集
 *          @Result
 *              id : 代表映射是否是主键    true:是     false:不是 (默认值)
 *
 * @ResultMap 表示引用 其他 @Results的 id属性的值
 * @return
 */
@Select("select * from user")
@Results(id="userMap",value={
        @Result(id=true,column = "id",property = "userId"),
        @Result(column = "username",property = "userName"),
        @Result(column = "address",property = "userAddress"),
        @Result(column = "sex",property = "userSex"),
        @Result(column = "birthday",property = "userBirthday"),
        @Result(property = "accounts",column = "id",
                many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
                            fetchType = FetchType.LAZY))
})
List<User> findAll();

4、逆向工程(Mybatis官方提供的)

​ 概念:就是由 数据库表 生成 pojo,mapper接口,mapper.xml (只能生成单表CRUD)

​ eclipse : 需要一个普通的Java项目。

​ idea : 需要一个Maven项目。

​ 我们要做的:

​ 1、改数据库的连接信息

​ 2、改包名

​ 3、指定要逆向生成的表名与类名

​ tb_user (表名) ---- TbUser (默认的类名) ---- User (自定义类名)

​ 4、右键 run ---- eclispe

​ 双击运行插件 ---- idea

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

推荐阅读更多精彩内容