Table of Contents

一、CRUD 标签

可以发现除了一些基本配置外,Mybatis的精华就在于Mapper(映射)部分。Mybatis是针对映射器构造的SQL构建的轻量级框架,并且可以通过配置生成对应的JavaBean给调用者。在Mybatis中可以灵活使用SQL来满足各种不同场景的需求,所以在互联网企业内更偏爱于使用Mybatis来应对高速变化的需求,而传统企业更偏向于使用Hibernate。

来自:https://juejin.cn/post/6844903556286267400

1.1 select

select – 书写查询sql语句

select中的几个属性说明:

id属性:当前名称空间下的statement的唯一标识。必须。要求id和

mapper接口中的方法的名字一致。

resultType:将结果集映射为java的对象类型。必须(和 resultMap 二选一)

parameterType:传入参数类型。可以省略

select元素是我们最常用的元素,正如在SQL里是查询功能也是最主要的功能之一。在我们常识里,查询语句通常都是根据一个或者多个条件,查询数据库返回一个,多个或者所有字段。之前我们举得getAllCommodity没有查询条件,返回所有字段。

在Mybatis里,我们可以传入简单的参数类型,像int,float,String这些,也可以传入一些复杂的类型,比如JavaBean、Map之流的,Mybatis把这些参数转换成SQL语句需要的类型后,返回结果,并且通过映射,将结果集自动绑定到JavaBean中,所以JDBC里面那一套一个一个从ResultSet获取值的操作都被省略了。

1
2
3
4
5
6
7
8
<!-- 官网例子 -->
<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

<select id="getCommodityById" parameterType="int" resultType="com.mybatis02.pojo.Commodity">
        select * from commodity where id = #{id}
</select>

1.2 输入映射

  • 通过Map 传递参数

    这种做法很常见,方便,不过提倡。

    在使用map之前,看一个错误例子。传递两个输入参数id、name

    1
    2
    3
    
    <select id="getCommodityById" resultType="com.mybatis02.pojo.Commodity">
        select * from commodity where id = #{id} and name = #{name}
    </select>
    

    报错:

    1
    2
    3
    
    org.apache.ibatis.exceptions.PersistenceException: 
    ### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
    ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
    

    再来看看Map的方式

    1
    2
    3
    
    <select id="getCommodityById" parameterType="map" resultType="com.mybatis02.pojo.Commodity">
        select * from commodity where id = #{id} and name = #{name}
    </select>
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    @Test
    public void testGetCommodityById() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        try {
            CommodityMapper commodityMapper = sqlSession.getMapper(CommodityMapper.class);
            Map<String, Object> map = new HashMap<>();
            map.put("id", 1001);
            map.put("name", "野葡萄烤饼");
            Commodity commodity = commodityMapper.getCommodityById(map);
            System.out.println(commodity.toString());
        } finally {
            sqlSession.close();
        }
    }
    

    虽然Map很简单,但是光是看传入参数Map,你不知道包含了怎样的内容,若是深入还得看如何设置Map的,而且使用时还要一项项指定Map的Key的名字,所以不怎么提倡使用了。

  • 使用注解方式传递参数

    1
    
    List<Commodity> getCommodityByAnnotation(@Param("name") String name, @Param("price") Double price);
    
  • 使用 POJO传递参数

    1
    2
    3
    
    <select id="getCommodityByPOJO" parameterType="com.shuqing28.pojo.Commodity" resultType="com.shuqing28.pojo.Commodity">
        SELECT * FROM commodity WHERE name like '%${name}%' AND price&lt;#{price}
    </select>
    

1.3 输出映射

  • resultType

    上面的例子有,可以是简单类型,也可以是 POJO对象或POJO列表。

    不管是POJO对象还是POJO列表,我们在resultType中的定义都是一样的,只不过接口定义不一样

  • resultMap

    img

    img

1.4 insert

insert 的几个属性说明:

id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致

parameterType:参数的类型,使用动态代理之后和方法的参数类型一致

useGeneratedKeys:开启主键回写

keyColumn:指定数据库的主键

keyProperty:主键对应的pojo属性名

标签内部:具体的sql语句。

1
2
3
4
5
<insert id="insertCommodity" useGeneratedKeys="true"
   keyProperty="id">
   insert into commodity (name,price,description)
   values (#{name},#{price},#{description})
</insert>

1.5 update

id属性:当前名称空间下的statement的唯一标识(必须属性);

parameterType:传入的参数类型,可以省略。

标签内部:具体的sql语句。

1
2
3
4
5
6
7
<update id="updateCommodity" parameterType="commodity">
    update commodity set 
    name=#{name},
    price=#{price},
    description=#{description}
    where id=#{id}
</update>

1.6 delete

delete 的几个属性说明:

id属性:当前名称空间下的statement的唯一标识(必须属性);

parameterType:传入的参数类型,可以省略。

标签内部:具体的sql语句。

1
2
3
<delete id="deleteCommodity" parameterType="int">
    delete from commodity where id=#{id}
</delete>

二、resultMap 标签

[见上文](#1.3 输出映射)

三、sql 标签

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。比如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<sql id="commonSql"> 
	id, user_name, password, name, age,
</sql> 

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>

四、#{} 和 $

注意: #{} 只是替换?,相当于PreparedStatement使用占位符去替换参数,可以防止sql注入${} 是进行字符串拼接,相当于sql语句中的Statement,使用字符串去拼接sql;$可以是sql中的任一部分传入到Statement中,不能防止sql注入。

使用${} 去取出参数值信息,需要使用${value} #{} 只是表示占位,与参数的名字无关,如果只有一个参数,会自动对应。