Mybatis - XML映射文件

1. 关于参数

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

接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值

先看parameterType

  • 传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)

  • parameterType写int、INT、INTEGER、integer、java.lang.Integer都可以。因为 Mybatis 给这些类型起了别名

再看参数符号

  • 这里的参数符号#{id},这就告诉 MyBatis 创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:
// 近似的 JDBC 代码,非 MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);

这样可以防止sql注入问题

  • 如果参数是基本类型或者基本类型的包装类,且只有一个参数,那么参数符号可以随便写 。也就是说,虽然 Mapper 接口中的方法声明为 HashMap selectPerson(Integer id) ,但是映射文件中既可以写 #{id},也可以写 #{aaaa}

  • 如果我们使用类作为参数,其中的参数符号#{username},#{birthday},#{birthday},#{sex},#{address}必须和User类的每个属性名一一对应,不可以乱写

其实这里应该说一下OGNL 表达式,对象图导航语言;Mybatis就是使用OGNL表达式来解析对象字段的名称

<insert id="saveUser" parameterType="com.minifull.pojo.User">
        INSERT INTO user(username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
    </insert>

它是通过对象的取值方法来获取数据。在写法上把get给省略了,也就是说我们的 user.getName()可以直接写成user.name(),但我们发现在上面的代码并没有写user.,这是因为我们在parameterType就已经提供了属性所属的类

2. 关于返回值

resultType
resultType期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型

<select id="selectUsers" resultType="com.someapp.model.User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

类型别名是你的好帮手。使用它们,你就可以不用输入类的全限定名了。比如

<!-- mybatis-config.xml 中 -->
<typeAlias type="com.someapp.model.User" alias="User"/>

<!-- SQL 映射 XML 中 -->
<select id="selectUsers" resultType="User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

在这些情况下,MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上。而且一旦指定了别名,那么别名就不再区分大小写
也就是说,此时我们可以在映射文件中这样写 resultType="user" ,也可以写 resultType="USER"

如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。比如:

<select id="selectUsers" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select>

resultMap
对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。 resultTyperesultMap 之间只能同时使用一个

上面使用ResultTyped的返回值属性名转换使用的是由Mybatis隐式的配置resultMap ,那么显式使用外部的 resultMap 怎么做呢

配置resultMap

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

然后在引用它的语句中设置 resultMap 属性就行了(注意我们去掉了 resultType 属性)

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

3. 关于主键

如果数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就 OK 了

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

那我怎么再添加后获取自增的主键值呢
使用 <selectKey></selectKey> 标签

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
  	SELECT LAST_INSERT_ID()
  </selectKey>
  insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})
</insert>
keyProperty 表示 selectKey 语句结果应该被设置的目标属性(对应实体类)

keyColumn 表示匹配属性的返回结果集中的列名称(对应数据库结果集)

order 可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先生成主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后再执行 selectKey 中的语句

注意这里返回的主键值是注入到了对象中,而不是方法的返回值

4. sql

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

<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>
发布了167 篇原创文章 · 获赞 3 · 访问量 5405

猜你喜欢

转载自blog.csdn.net/weixin_43907800/article/details/104875372
今日推荐