MyBatis映射文件

MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。

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

  • cache给定命名空间的缓存配置。
  • cache-ref其他命名空间缓存配置的引用。
  • resultMap是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
  • parameterMap已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。
  • sql可被其他语句引用的可重用语句块。
  • insert映射插入语句
  • update映射更新语句
  • delete映射删除语句
  • select映射查询语句

 

以下为映射文件中常见元素的常见属性详解:

  1. select属性

id

在命名空间中唯一的标识符,可以被用来引用这条语句。

parameterType

将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset

parameterMap

这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。

resultType

从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType resultMap,但不能同时使用。

resultMap

外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap resultType,但不能同时使用。

flushCache

将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false

useCache

将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true

timeout

这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。

fetchSize

这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。

statementType

STATEMENTPREPARED CALLABLE 的一个。这会让 MyBatis 分别使用 StatementPreparedStatement CallableStatement,默认值:PREPARED

resultSetType

FORWARD_ONLYSCROLL_SENSITIVE SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。

databaseId

如果配置了 databaseIdProviderMyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

resultOrdered

这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false

resultSets

这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称是逗号分隔的。

2select-selectKey属性

keyProperty

selectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

keyColumn

匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

resultType

结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map

order

这可以被设置为 BEFORE AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。

statementType

与前面相同,MyBatis 支持 STATEMENTPREPARED CALLABLE 语句的映射类型,分别代表 PreparedStatement CallableStatement 类型。

3Insert, Update, Delete属性

id

命名空间中的唯一标识符,可被用来代表这条语句。

parameterType

将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset

parameterMap

这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。

flushCache

将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)。

timeout

这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。

statementType

STATEMENTPREPARED CALLABLE 的一个。这会让 MyBatis 分别使用 StatementPreparedStatement CallableStatement,默认值:PREPARED

useGeneratedKeys

(仅对 insert update 有用)这会令 MyBatis 使用 JDBC getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false

keyProperty

(仅对 insert update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

keyColumn

(仅对 insert update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

databaseId

如果配置了 databaseIdProviderMyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

4ResultMap属性

id

当前命名空间中的一个唯一标识,用于标识一个result map.

type

类的完全限定名, 或者一个类型别名 (内置的别名可以参考上面的表格).

autoMapping

如果设置这个属性,MyBatis将会为这个ResultMap开启或者关闭自动映射。这个属性会覆盖全局的属性 autoMappingBehavior。默认值为:unset

5ResultMap-Id属性

property

映射到列结果的字段或属性。如果用来匹配的 JavaBeans 存在给定名字的属性,那么它将会被使用。否则 MyBatis 将会寻找给定名称 property 的字段。 无论是哪一种情形,你都可以使用通常的点式分隔形式进行复杂属性导航。比如,你可以这样映射一些简单的东西: “username” ,或者映射到一些复杂的东西: “address.street.number”

column

数据库中的列名,或者是列的别名。一般情况下,这和 传递给 resultSet.getString(columnName) 方法的参数一样。

javaType

一个 Java 类的完全限定名,或一个类型别名(参考上面内建类型别名 的列表) 。如果你映射到一个 JavaBean,MyBatis 通常可以断定类型。 然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证期望的行为。

jdbcType

JDBC 类型,所支持的 JDBC 类型参见这个表格之后的支持的 JDBC 类型 只需要在可能执行插入、更新和删除的允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能为 null 的值指定这个类型。

typeHandler

我们在前面讨论过的默认类型处理器。使用这个属性,你可以覆盖默 认的类型处理器。这个属性值是一个类型处理 器实现类的完全限定名,或者是类型别名。

 

以下为映射文件中常用到的知识点:

知识点一、insert获取主键方式

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

<!-- public void addEmp(Employee employee); -->

       <!-- parameterType:参数类型,可以省略,

       获取自增主键的值:

              mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys()

              useGeneratedKeys="true";使用自增主键获取主键值策略

              keyProperty;指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性

       -->

       <insert id="addEmp" parameterType="com.atguigu.mybatis.bean.Employee"

              useGeneratedKeys="true" keyProperty="id" databaseId="mysql">

              insert into tbl_employee(last_name,email,gender)

              values(#{lastName},#{email},#{gender})

       </insert>

 

2、数据库或可能不支持自动生成主键的 JDBC 驱动,MyBatis 有另外一种方法来生成主键。 这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(你最好不要这么做,但这里展示了 MyBatis 处理问题的灵活性及其所关心的广度):

<!--

         获取非自增主键的值:

                   Oracle不支持自增;Oracle使用序列来模拟自增;

                   每次插入的数据的主键是从序列中拿到的值;如何获取到这个值;

          -->

         <insert id="addEmp" databaseId="oracle">

                   <!--

                   keyProperty:查出的主键值封装给javaBean的哪个属性

                   order="BEFORE":当前sql在插入sql之前运行

                               AFTER:当前sql在插入sql之后运行

                   resultType:查出的数据的返回值类型

                  

                   BEFORE运行顺序:

                            先运行selectKey查询id的sql;查出id值封装给javaBean的id属性

                            在运行插入的sql;就可以取出id属性对应的值

                   AFTER运行顺序:

                            先运行插入的sql(从序列中取出新值作为id);

                            再运行selectKey查询id的sql;

                    -->

                   <selectKey keyProperty="id" order="BEFORE" resultType="Integer">

                            <!-- 编写查询主键的sql语句 -->

                            <!-- BEFORE-->

                            select EMPLOYEES_SEQ.nextval from dual

                            <!-- AFTER

                             select EMPLOYEES_SEQ.currval from dual -->

                   </selectKey>

                  

                   <!-- 插入时的主键是从序列中拿到的 -->

                   <!-- BEFORE:-->

                   insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)

                   values(#{id},#{lastName},#{email<!-- ,jdbcType=NULL -->})

                   <!-- AFTER:

                   insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)

                   values(employees_seq.nextval,#{lastName},#{email}) -->

         </insert>

 

知识点二、参数处理

• 单个参数

– 可以接受基本类型,对象类型,集合类型的值。这种情况

MyBatis可直接使用这个参数,不需要经过任何处理。

• 多个参数

– 任意多个参数,都会被MyBatis重新包装成一个Map传入。

Map的key是param1,param2,0,1…,值就是参数的值。

• 命名参数

– 为参数使用@Param起一个名字,MyBatis就会将这些参数封

装进map中,key就是我们自己指定的名字

• POJO

– 当这些参数属于我们业务POJO时,我们直接传递POJO

• Map

– 我们也可以封装多个参数为map,直接传递

 

1、#和$取值的区别:

#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入

         ${}:取出的值直接拼装在sql语句中;会有安全问题;

         大多情况下,我们去参数的值都应该去使用#{};

 

猜你喜欢

转载自blog.csdn.net/liberty12345678/article/details/82021686
今日推荐