Mybatis实战2:标签详解

2020-02-08  本文已影响0人  万物归于简
image.png

一、select标签

1.标签属性

2.查询示例

1.简单查询

mapper接口

    // 根据 id 获得数据库中的 username 字段的值
    String getUserNameById(Integer id);

mapper.xml

<!-- 
        指定 resultType 返回值类型时 String 类型的,
        string 在这里是一个别名,代表的是 java.lang.String 

        对于引用数据类型,都是将大写字母转小写,比如 HashMap 对应的别名是 'hashmap'
        基本数据类型考虑到重复的问题,会在其前面加上 '_',比如 byte 对应的别名是 '_byte'
    -->
    <select id="getUserNameById" resultType="java.lang.String">
    select user_name from user_info where id = #{id}
  </select>
2.查询返回JavaBean

返回Java实体类可以使用resultType属性
多个查询条件,可以使用@Param 来指定
mapper接口

// 多个查询条件,可以使用
UserInfo selectByNamePwd(@Param("userName") String userName, @Param("password") String password);
  <!--通过用户名和密码查询-->
  <select id="selectByNamePwd" resultType="com.gqlofe.userinfo.bean.entity.UserInfo">
    select
    <include refid="Base_Column_List" />
    from user_info
    where user_name = #{userName} and password = #{password}
  </select>
3.返回list类型

mapper方法返回类型是List,则查询的结果就是List,xml中resultType指定的是返回List的元素的类型

List<UserInfo> selectAll();
  <select id="selectAll" resultType="com.gqlofe.userinfo.bean.entity.UserInfo">
    select * from user_info
  </select>
4.返回Map类型
    //  根据 id 查询信息,并把结果信息封装成 Map
    Map<String, Object> getMapById(Integer id);
  <select id="getMapById" resultType="hashmap">
    select * from user_info where id = #{id}
  </select>
    @MapKey("id")
    Map<Integer, UserInfo> getAllUserInfoAsMap();
  <!--本可以使用resultType="com.gqlofe.userinfo.bean.entity.UserInfo"-->
  <!--但由于数据库字段名和实体类属性名不一致,所以使用resultMap,表示map的value的类型-->
  <select id="getAllUserInfoAsMap" resultMap="BaseResultMap">
    select * from user_info
  </select>

二、insert,update,delete标签

属性名称 释义 示例
id 唯一的名称,对应dao中mapper的接口名称 selectById
paramterType 定义传入的参数类型 long
flushCache 将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false fasle
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动),若设置10,则表示10秒内数据库没有返回结果就抛出异常 10
statementType STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED PREPARED
useGeneratedKeys (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server这样的关系数据库管理系统的自动递增字段, oracle使用序列是不支持的,通过selectKey可以返回主键),默认值:false。 true
keyProperty (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 id
keyColumn (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 id
databaseId 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

三、sql标签

定义一些常用的sql语句片段

<sql id="selectParam">
    id, username, password, sex, birthday, address
</sql>

四、include 标签

引用其他的常量,通常和sql一起使用

<select>
    select <include refid="selectParam"></include>
    from user_info
</select>

五、if 标签

基本都是用来判断值是否为空,注意Integer的判断,mybatis会默认把0变成 ‘’

<if test="item != null and item != ''"></if>

<!-- 如果是Integer类型的需要把and后面去掉或是加上or-->
<if test="item != null"></if>
<if test="item != null and item != '' or item == 0"></if>

六、别名typeAliases标签

经常使用的类型可以定义别名,方便使用,mybatis也注册了很多别名方便我们使用,详情见底部

<typeAliases>
     <typeAlias type="com.gqlofe.userinfo.bean.entity.UserInfo" alias="User"/>
</typeAliases>

七、where标签

当使用if标签进行条件判断时有可能第一个条件不满足,会导致where语句中多一个and 或者or,如下:

  <select id="selectByNamePwd" resultType="com.gqlofe.userinfo.bean.entity.UserInfo">
    select
    <include refid="Base_Column_List" />
    from user_info
    where
    <if test="userName != null">
      user_name = #{userName}
    </if>
    <if test="password != null">
      and password = #{password}
    </if>
  </select>

如果userName= null,则sql语句就变成

select * from user_info where and password = #{password}

显然有问题,where标签可以去除where语句中的第一个and 或 or。
用法:

  <select id="selectByNamePwd" resultType="com.gqlofe.userinfo.bean.entity.UserInfo">
    select
    <include refid="Base_Column_List" />
    from user_info
    <where>
      <if test="userName != null">
        user_name = #{userName}
      </if>
      <if test="password != null">
        and password = #{password}
      </if>
    </where>
  </select>

八、set标签

update语句中,set标签可以去除多余的逗号,用法:

<update id="updateByPrimaryKeySelective" parameterType="com.gqlofe.userinfo.bean.entity.UserInfo">
    update user_info
    <set>
      <if test="userName != null">
        user_name = #{userName,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="phone != null">
        phone = #{phone,jdbcType=VARCHAR},
      </if>
      <if test="icon != null">
        icon = #{icon,jdbcType=VARCHAR},
      </if>
      <if test="sex != null">
        sex = #{sex,jdbcType=INTEGER},
      </if>
      <if test="age != null">
        age = #{age,jdbcType=INTEGER},
      </if>
      <if test="birthday != null">
        birthday = #{birthday,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=BIGINT},
      </if>
      <if test="updateTime != null">
        update_time = #{updateTime,jdbcType=BIGINT},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>

九、trim标签

where标签只能去除第一个and或or,不够灵活,trim标签功能更加强大。
trim标签的属性如下:

<insert id="insertSelective" parameterType="UserInfo" useGeneratedKeys="true" keyProperty="id">
    insert into user_info
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="userName != null">
        user_name,
      </if>
      <if test="password != null">
        password,
      </if>
      <if test="phone != null">
        phone,
      </if>
      <if test="icon != null">
        icon,
      </if>
      <if test="sex != null">
        sex,
      </if>
      <if test="age != null">
        age,
      </if>
      <if test="birthday != null">
        birthday,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="updateTime != null">
        update_time,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="userName != null">
        #{userName,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="phone != null">
        #{phone,jdbcType=VARCHAR},
      </if>
      <if test="icon != null">
        #{icon,jdbcType=VARCHAR},
      </if>
      <if test="sex != null">
        #{sex,jdbcType=INTEGER},
      </if>
      <if test="age != null">
        #{age,jdbcType=INTEGER},
      </if>
      <if test="birthday != null">
        #{birthday,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=BIGINT},
      </if>
      <if test="updateTime != null">
        #{updateTime,jdbcType=BIGINT},
      </if>
    </trim>
  </insert>

十、foreach标签

foreach元素的属性主要有item,index,collection,open,separator,close.

<select id="countByUserList" resultType="_int" parameterType="list">
select count(*) from user_info
  <where>
    id in
    <foreach item="item" collection="list" separator="," open="(" close=")" index="">
      #{item.id, jdbcType=NUMERIC}
    </foreach>
  </where>
</select>

<select id="dynamicForeach2Test" resultType="Blog">
     select * from t_blog where id in
     <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
          #{item}
     </foreach>
</select>

十一、choose,when,otherwise标签

功能有点类似于Java中的 swicth - case - default

<select id="getUser" resultType="com.cat.pojo.User">
  SELECT * FROM user 
  <where>
  <choose>
    <when test="id != null and test.trim() != '' ">
      id = #{id}
    </when> 
    <when test="name != null and name.trim() != '' ">
      name = #{name}
    </when> 
    <otherwise>
      age = 17  
    </otherwise>
  </choose>
</where>
</select>

七、resultMap标签

在平时的开发中,我们没有办法一定能保证表中的字段名和表对应实体类的属性名称是完全相同的,resultMap可以解决表字段和实体属性名不一致的问题
表结构

CREATE TABLE `user_info` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户名',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '密码',
  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机',
  `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '头像链接地址',
  `sex` int(5) NOT NULL DEFAULT '3' COMMENT '性别: 1 男,2 女, 3 保密',
  `age` int(5) NOT NULL DEFAULT '0' COMMENT '年龄',
  `birthday` bigint(15) DEFAULT '0' COMMENT '出生年月',
  `create_time` bigint(15) NOT NULL DEFAULT '0' COMMENT '创建时间',
  `update_time` bigint(15) NOT NULL DEFAULT '0' COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `index_name` (`user_name`) USING BTREE COMMENT '用户名唯一索引',
  KEY `index_phone` (`phone`) USING BTREE COMMENT '手机号索引'
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户表';

实体类

@Data
@Accessors(chain = true)
public class UserInfo implements Serializable {
    // 用户id
    private Integer id;
    // 用户名
    private String userName;
    // 密码
    private String password;
    // 手机
    private String phone;
    // 头像链接地址
    private String icon;
    // 性别: 1 男,2 女, 3 保密
    private Integer sex;
    // 年龄
    private Integer age;
    // 出生年月
    private Long birthday;
    // 创建时间
    private Long createTime;
    // 更新时间
    private Long updateTime;
    private static final long serialVersionUID = 1L;
}

可以看出数据库字段一般是以下划线的格式,而Java实体类是以驼峰格式,为了保证能正确映射,就需要使用resultMap标签

 <resultMap id="BaseResultMap" type="com.gqlofe.userinfo.bean.entity.UserInfo">
   <id column="id" jdbcType="INTEGER" property="id" />
   <result column="user_name" jdbcType="VARCHAR" property="userName" />
   <result column="password" jdbcType="VARCHAR" property="password" />
   <result column="phone" jdbcType="VARCHAR" property="phone" />
   <result column="icon" jdbcType="VARCHAR" property="icon" />
   <result column="sex" jdbcType="INTEGER" property="sex" />
   <result column="age" jdbcType="INTEGER" property="age" />
   <result column="birthday" jdbcType="BIGINT" property="birthday" />
   <result column="create_time" jdbcType="BIGINT" property="createTime" />
   <result column="update_time" jdbcType="BIGINT" property="updateTime" />
 </resultMap>

 <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
   select 
   <include refid="Base_Column_List" />
   from user_info
   where id = #{id,jdbcType=INTEGER}
 </select>

使用resultMap将数据库字段名和Java实体类属性名一一映射,在查询sql中使用resultMap=BaseResultMap,其中 BaseResultMap 是resultMap的id。

上一篇下一篇

猜你喜欢

热点阅读