MyBatis的XML映射文件

MyBatis的XML映射文件只有几个顶级元素:
cache:对给定命名空间缓存配置
cache-ref:对其他命名空间缓存配置的引用
resultMap:最复杂的元素,用以描述如何从数据库结果集中加载对象
sql:可被其他语句引用的可重用语句块
insert:映射插入语句
update:映射更新语句
delete:映射删除语句
select:映射查询语句

select:

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

该语句称作selectPerson,接受一个int(或Integer)类型的参数,并返回一个HashMap类型的对象。其中#{id}告诉MyBatis创建一个预处理语句(PreparedStatement)参数,上面的select映射大致等于(省略返回结果):

String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);

从中可以看出使用MyBatis映射更加简单方便。
下面介绍select的属性:

<select
 <!--命名空间中唯一标识符,可以被用来引用这条语句8 -->
  id="selectPerson"
   <!--可选属性,传入语句的参数类完全限定名或别名,可通过类型处理器推断具体传入语句的参数,默认值为unset -->
  parameterType="int"
   <!--返回期望类型的类的完全限定名或别名,如果返回的是集合,应该设置为集合包含的类型,而不是集合本身, resultType 或 resultMap不能同时使用-->
  resultType="hashmap"
   <!-同上- -->
  resultMap="personResultMap"
   <!--如果设置为true,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值为false -->
  flushCache="false"
   <!--设置为true后,将会导致本条语句的结果被二级缓存,默认值为true -->
  useCache="true"
   <!-- 驱动程序等待数据库返回请求结果的秒数,默认值为unset,依赖驱动-->
  timeout="10"
   <!--驱动提示,尝试让驱动程序每次批量返回的结果行数和这个设置值相等,默认值为未设置(依赖驱动) -->
  fetchSize="256"
   <!--STATEMENT,PREPARED 或 CALLABLE 中的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED -->
  statementType="PREPARED"
   <!--FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖驱动) -->
  resultSetType="FORWARD_ONLY">

insert,update和delete:
属性介绍:
id:命名空间中唯一标识符,可被用来代表这条语句
parameterType:将要传入语句的参数的完全限定类名或别名,可选
flushCache:设置为true,都会导致本地缓存和二级缓存被清空,默认值为true
timeout:在抛出异常以前,驱动程序等待数据库返回请求结果的秒数,默认值为未设置(unset)
useGeneratedKeys:这会令MyBatis使用JDBC的getGeneratedKeys方法来取出数据库内部生成的主键,默认值为false
keyProperty:(仅对insert和update有用),唯一标记一个属性,MyBatis会通过getGeneratedKeys的返回值或者通过insert语句的selectKey 子元素设置它的键值
keyColumn:(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望使用多个生成的列,也可以设置为逗号分隔的属性名称列表。
databaseId:如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就 OK 了。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>

如果你的数据库还支持多行插入, 也可以传入一个 Author 数组或集合,并返回自动生成的主键:

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>

sql:
该元素被用来定义可重用的SQL代码段,这些SQL代码可以被包含在其他语句中,它可以被静态地设置参数。在不同的包含语句中可以设置不同的值到参数占位符上:

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

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

参数:
简单参数传递举例:

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

复杂对象传递举例:

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

参数中指定特殊数据类型:

#{property,javaType=int,jdbcType=NUMERIC}

指定小数点后保留位数设置:

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

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

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

字符串替换:
直接在 SQL 语句中插入一个不转义的字符串。 比如,像 ORDER BY,可以这样来使用:

ORDER BY ${columnName}

当 SQL 语句中的元数据(如表名或列名)是动态生成的时候,字符串替换将会非常有用。 举个例子,如果你想通过任何一列从表中 select 数据时,不需要像下面这样写:

@Select("select * from user where id = #{id}")
User findById(@Param("id") long id);

@Select("select * from user where name = #{name}")
User findByName(@Param("name") String name);

@Select("select * from user where email = #{email}")
User findByEmail(@Param("email") String email);

可以只写一个方法:

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);

其中 ${column} 会被直接替换,而 #{value} 会被使用 ? 预处理。 因此可以像下面这样来达到上述功能:

User userOfId1 = userMapper.findByColumn("id", 1L);
User userOfNameKid = userMapper.findByColumn("name", "kid");
User userOfEmail = userMapper.findByColumn("email", "[email protected]");

结果映射:
ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了
举例:

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

猜你喜欢

转载自blog.csdn.net/weixin_43638314/article/details/93378040
今日推荐