0
点赞
收藏
分享

微信扫一扫

MyBatis基础映射

boom莎卡拉卡 2022-01-23 阅读 110

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

  • cache – 该命名空间的缓存配置。
  • cache-ref – 引用其它命名空间的缓存配置。
  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
  • sql – 可被其它语句引用的可重用语句块。
  • insert – 映射插入语句。
  • update – 映射更新语句。
  • delete – 映射删除语句。
  • select – 映射查询语句。

查看dtd文件也能了解到包含这些标签:

<!ELEMENT mapper (cache-ref | cache | resultMap* | parameterMap* | sql* | insert* | update* | delete* | select* )+>

下面的例子我们对象都使用了别名,在全局配置文件配置就可以了

<?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>

    <settings>
        <!-- 使用驼峰命名法转换字段 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
         <!-- 扫描的包,自己定义 -->
        <package name="com.example.springboot_mybatis.model"></package>
    </typeAliases>

</configuration>

输入参数

传递简单类型

//查询用户
User findById(Integer id);

<select id="selectUsers" resultType="User" parameterType="integer">
  select id, username, password
  from users
  where id = #{id}
</select>

传递pojo

使用#{对象属性}的方式,假设包含了一个部门对象属性dept,也可以用#{dept.xxx}来获取包含对象的属性值

//添加用户
int save(User user);

<insert id="insertUser" parameterType="User">
  insert into users (id, username, password)
  values (#{id}, #{username}, #{password})
</insert>

HashMap参数

HashMap作为参数的时候,我们显示执行javaType 来确保正确的类型处理器(TypeHandler)被使用

提示 JDBC 要求,如果一个列允许使用 null 值,并且会使用值为 null 的参数,就必须要指定 JDBC 类型(jdbcType)。

要更进一步地自定义类型处理方式,可以指定一个特殊的类型处理器类(或别名)

#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}

数值类型:还可以设置 numericScale 指定小数点后保留的位数。

#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

最后,mode 属性允许你指定 INOUTINOUT 参数。如果参数的 modeOUTINOUT,将会修改参数对象的属性值,以便作为输出参数返回。 如果 modeOUT(或 INOUT),而且 jdbcTypeCURSOR(也就是 Oracle 的 REFCURSOR),你必须指定一个 resultMap 引用来将结果集 ResultMap 映射到参数的类型上。要注意这里的 javaType 属性是可选的,如果留空并且 jdbcType 是 CURSOR,它会被自动地被设为 ResultMap

#{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentResultMap}

MyBatis 也支持很多高级的数据类型,比如结构体(structs),但是当使用 out 参数时,你必须显式设置类型的名称。比如(再次提示,在实际中要像这样不能换行):

#{middleInitial, mode=OUT, jdbcType=STRUCT, jdbcTypeName=MY_TYPE, resultMap=departmentResultMap}

尽管上面这些选项很强大,但大多时候,你只须简单指定属性名,顶多要为可能为空的列指定 jdbcType,其他的事情交给 MyBatis 自己去推断就行了。

简单使用: #{key}

List<User> findListByHashMap(HashMap<String, Object> map)
<select id="findListByHashMap" resultType="com.pojo.User">
      select * from user where username = #{username} and status = #{status}
</select>

集合和数组

一般我们使用<foreach>标签去遍历

/**
* 批量插入
* @param userList
* @return
*/
int batchSave(@Param("userList") List userList);
<insert id="batchSave" parameterType="list">
    INSERT INTO t_user(username,email,addr) VALUES
    <foreach item="item" collection="userList" separator=",">
        (#{item.username}, #{item.email}, #{item.addr})
    </foreach>
</insert>

如果我们想取集合的第一条的话:比如我们取user集合的第一条的user对象的id去查询:#{list[0].id}

/**
* 查询用户
* @param users
* @return
*/
User findById(List<User> users);
<select id="findById" parameterType="integer" resultType="com.pojo.User" resultMap="userMap">
    select id, username, email, addr from t_user where id = #{list[0].id} limit 1
</select>

类似这种形式的话是有一定规律的:

  • Collection - collection[索引值]

  • LIst - list[索引值]

  • 数组 - array[索引值]

public static Object wrapToMapIfCollection(Object object, String actualParamName) {
    if (object instanceof Collection) {
        ParamMap<Object> map = new ParamMap<>();
        map.put("collection", object);
        if (object instanceof List) {
            map.put("list", object);
        }
        Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object));
        return map;
    } else if (object != null && object.getClass().isArray()) {
        ParamMap<Object> map = new ParamMap<>();
        map.put("array", object);
        Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object));
        return map;
    }
    return object;
}

输出参数

输出简单类型

我们获取用户表的总记录数

UserMapper:

/**
 * 获取总记录
 * @return 总记录
 */
int getTotal();

UserMapper.xml:

<select id="getTotal" resultType="java.lang.Integer">
    select count(1) from t_user
</select>

输出pojo

UserMapper:

/**
 * 获取总记录
 * @return 总记录
 */
int getTotal();

UserMapper.xml:

<select id="getTotal" resultType="java.lang.Integer">
    select count(1) from t_user
</select>

输出pojo列表

比如我们根据用户名去模糊查询用户

UserMapper:

/**
     *  根据用户名模糊查询
     * @param username 用户名
     * @return list
     */
List<User> getListByName(@Param("username") String username);

UserMapper.xml:

<select id="getListByName" resultType="User">
    select * from t_user t where instr(t.username, #{username}) > 0
</select>

输出Map集合

还是上面的例子,但是我们只需要查询id和用户名这2个字段

UserMapper:

/**
 * 根据用户名模糊查询
 * @param username 用户名
 * @return list
 */
List<Map<String, Object>> getListByName(@Param("username") String username);

UserMapper.xml:

<select id="getListByName" resultType="map">
    select t.id, t.username from t_user t where instr(t.username, #{username}) > 0
</select>

测试:

@Test
public void getList(){
    List<Map<String, Object>> users = userMapper.getListByName("x");
    users.stream().forEach(System.out::println);
}

//map的key对应数据库中的列名
{id=15, username=xx}
{id=16, username=xx}
{id=17, username=xx}
{id=18, username=xx}
{id=19, username=xx}

结果映射

resultMap初识

之前的查询语句大部分数据库列名都和实体保持一致, 但是如果不一致呢,经常我实体属性和数据表属性都是按照驼峰命名的,比如实体类叫,叫creTime,数据库命名cre_time那么就需要我们手动的建立一一映射的关系了。

方法有两种:

一种是:使用as起别名

<select id="getList" resultType="User">
  select
    user_id as id,
    user_name as userName
  from t_user
  where user_id = #{id}
</select>

第二种是: 使用resultMap: select标签通过resultMap属性指定我们要使用的映射map

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="userName" column="user_name"/>
</resultMap>

<select id="findById" parameterType="integer" resultMap="userResultMap">
        select * from t_user where id = #{id}
</select>
  • id用来唯一标识这个resultMap, type指的是映射的实体类
  • id标签一般用来代表主键映射,result标签其他列映射
  • property: 对象的属性名, column:数据库列名
举报

相关推荐

MyBatis映射

MYbatis映射

mybatis高级映射

MyBatis高级映射

MyBatis关系映射

Mybatis 映射文件

MyBatis映射文件

0 条评论