`
liyixing1
  • 浏览: 940964 次
  • 性别: Icon_minigender_1
  • 来自: 江西上饶
社区版块
存档分类
最新评论

sql映射文件

阅读更多
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.AccountDao">

</mapper>

包括子元素:
 cache - 配置给定命名空间的缓存。
 cache-ref – 从其他命名空间引用缓存配置。
 resultMap – 最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载你的对象。
 parameterMap – 已经被废弃了!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除。这里不会记录。
 sql – 可以重用的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使用JDBC创建一个参数,这样的一个参数在SQL中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:
// Similar JDBC code, NOT MyBatis…
String selectPerson = “SELECT * FROM PERSON WHERE ID=?”;
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);

select有很多参数
id
在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType
将会传入这条语句的参数类的完全限定名或别名。
parameterMap
这是引用外部parameterMap的已经被废弃的方法。使用内联参数映射和parameterType属性。
resultType
从这条语句中返回的期望类型的类的完全限定名或别名。注意集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用resultType或resultMap,但不能同时使用。
resultMap
命名引用外部的resultMap。返回map是MyBatis最具力量的特性,对其有一个很好的理解的话,许多复杂映射的情形就能被解决了。使用resultMap或resultType,但不能同时使用。
flushCache
将其设置为true,不论语句什么时候被带哦用,都会导致缓存被清空。默认值:false。
useCache
将其设置为true,将会导致本条语句的结果被缓存。默认值:true。
timeout
这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)。
fetchSize
这是暗示驱动程序每次批量返回的结果行数。默认不设置(驱动自行处理)。
statementType
STATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis使用选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED。
resultSetType
FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE中的一种。默认是不设置(驱动自行处理)。

insert,update,delete
属性
id
在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType
将会传入这条语句的参数类的完全限定名或别名。
parameterMap
这是引用外部parameterMap的已经被废弃的方法。使用内联参数映射和parameterType属性。
flushCache
将其设置为true,不论语句什么时候被带哦用,都会导致缓存被清空。默认值:false。
timeout
这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)。
statementType
STATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis使用选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED。
useGeneratedKeys
(仅对insert有用)这会告诉MyBatis使用JDBC的getGeneratedKeys方法来取出由数据(比如:像MySQL和SQL Server这样的数据库管理系统的自动递增字段)内部生成的主键。默认值:false。
keyProperty
(仅对insert有用)标记一个属性,MyBatis会通过getGeneratedKeys或者通过insert语句的selectKey子元素设置它的值。默认:不设置。
例子:

<insert id="insertAuthor" parameterType="domain.blog.Author">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor" parameterType="domain.blog.Author">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
</update>
<delete id="deleteAuthor” parameterType="int">
delete from Author where id = #{id}
</delete>

如果你的数据库支持自动生成主键的字段(比如MySQL和SQL Server),那么你可以设置useGeneratedKeys=”true”,而且设置keyProperty到你已经做好的目标属性上。例如,如果上面的Author表已经对id使用了自动生成的列类型,那么语句可以修改为:
<insert id="insertAuthor" parameterType="domain.blog.Author"
useGeneratedKeys=”true” keyProperty=”id”>
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>

MyBatis有另外一种方法来处理数据库不支持自动生成类型,或者可能JDBC驱动不支持自动生成主键时的主键生成问题。
这里有一个简单(甚至很傻)的示例,它可以生成一个随机ID(可能你不会这么做,但是这展示了MyBatis处理问题的灵活性,因为它并不真的关心ID的生成):
<insert id="insertAuthor" parameterType="domain.blog.Author">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
insert into Author
(id, username, password, email,bio, favourite_section)
values
(#{id}, #{username}, #{password}, #{email}, #{bio},
#{favouriteSection,jdbcType=VARCHAR}
)
</insert>
在上面的示例中,selectKey元素将会首先运行,Author的id会被设置,然后插入语句会被调用。这给你了一个简单的行为在你的数据库中来处理自动生成的主键,而不需要使你的Java代码变得复杂。
selectKey元素描述如下:
keyProperty
selectKey语句结果应该被设置的目标属性。
resultType
结果的类型。MyBatis通常可以算出来,但是写上也没有问题。MyBatis允许任何简单类型用作主键的类型,包括字符串。
order
这可以被设置为BEFORE或AFTER。如果设置为BEFORE,那么它会首先选择主键,设置keyProperty然后执行插入语句。如果设置为AFTER,那么先执行插入语句,然后是selectKey元素-这和如Oracle数据库相似,可以在插入语句中嵌入序列调用。
statementType
和前面的相同,MyBatis支持STATEMENT,PREPARED和CALLABLE语句的映射类型,分别代表PreparedStatement和CallableStatement类型。

sql
这个元素可以被用来定义可重用的SQL代码段,可以包含在其他语句中。比如:
<sql id=”userColumns”> id,username,password </sql>
这个SQL片段可以被包含在其他语句中,例如:
<select id=”selectUsers” parameterType=”int” resultType=”hashmap”>
select <include refid=”userColumns”/>
from some_table
where id = #{id}
</select>

Parameters
简单的参数传递
<select id=”selectUsers” parameterType=”int” resultType=”User”>
select id, username, password
from users
where id = #{id}
</select>
然而,如果你传递了一个复杂的对象,那么MyBatis的处理方式就会有一点不同。比如:
<insert id=”insertUser” parameterType=”User” >
insert into users (id, username, password)
values (#{id}, #{username}, #{password})
</insert>
如果User类型的参数对象传递到了语句中,它的id、username和password属性将会被查找,然后它们的值就被传递到参数中。

这点对于传递参数到语句中非常好。但是对于参数映射也有一些其他的特性。
首先,像MyBatis的其他功能,参数可以指定一个确定的数据类型。
#{propertyName,javaType=int,jdbcType=NUMERIC}
如果参数对象是一个hashMap,javaType应该被保证使用正确类型处理器。

如果查询某个值为空的列null,JDBCType就需要写了。

如果使用自定义类型处理器,你需要指定一个类型处理器的类名或者缩写别名,如
#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

最后,mode属性允许你指定IN,OUT或INOUT参数。如果参数为OUT或INOUT,参数对象属性的值将会被改变,否则保持不变。 注意!要确保始终只使用 JDBC 标准的存储过程语法。参考 JDBC 的 CallableStatement 文档以获得更详细的信息。

字符串替换
#{}格式的语法会创建参数华。如果不想创建参数化,使用
${columnName}
方式,将直接用参数值替换sql中的该部分内容。

resultMap
首先需要了解resultType的作用。
<select id=”selectUsers” parameterType=”int” resultType=”hashmap”>
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
或者使用javabean
package com.someapp.model;
public class User {
private int id;
private String username;
private String hashedPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getHashedPassword() {
return hashedPassword;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
}
<select id=”selectUsers” parameterType=”int”
resultType=”com.someapp.model.User”>
select id, username, hashedPassword
from some_table
where id = #{id}
</select>

因为数据库字段和属性一一对应,所有会自动匹配。如果添加的类型别名定义。那么可以使用别名来设置。
<!-- In Config XML file -->
<typeAlias type=”com.someapp.model.User” alias=”User”/>
<!-- In SQL Mapping XML file -->
<select id=”selectUsers” parameterType=”int”
resultType=”User”>
select id, username, hashedPassword
from some_table
where id = #{id}
</select>

如果字段名和数据库列名不是一一对应的,可以使用sql语句的as语法,来定义列别名,让它和字段对应
<select id=”selectUsers” parameterType=”int” resultType=”User”>
select
user_id as id,
user_name as userName,
hashed_password as hashedPassword
from some_table
where id = #{id}
</select>
而resultMap则可以更好的解决上面的问题
//实体类
package com.liyixing.ibatis.model;

import java.io.Serializable;

public class Account implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

private int id;
private String userName;
private int age;

public Account() {
super();
}

public Account(int id, String userName, int age) {
super();
this.id = id;
this.userName = userName;
this.age = age;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

映射配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liyixing.ibatis.dao.IAccountDao">
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<id property="id" column="ID" />
<result property="userName" column="USER_NAME" />
<result property="age" column="AGE" />
</resultMap>
<select id="getAccount" parameterType="int" resultMap="account">
SELECT
ID, USER_NAME, AGE FROM account
WHERE ID = #{id}
</select>
<!---->
<!-- <select id="getAccount" parameterType="string"-->
<!-- resultType="com.liyixing.ibatis.model.Account">-->
<!-- SELECT ID, USER_NAME, AGE FROM account-->
<!-- WHERE USER_NAME = #{userName}-->
<!-- </select>-->
<insert id="addAccount" parameterType="com.liyixing.ibatis.model.Account">
INSERT INTO account
(USER_NAME, AGE)
VALUES
(#{userName},#{age})

<selectKey resultType="int" keyProperty="id">
select
last_insert_id() as ID from account limit 1
</selectKey>
</insert>
</mapper>
以上映射配置中可以看到一个resultMap元素
而select的配置中,不再使用resultType,而是改为resultMap
表结构
CREATE TABLE `account` (
  `ID` int(11) NOT NULL auto_increment,
  `USER_NAME` varchar(50) default NULL,
  `AGE` int(11) default NULL,
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

这里不再使用resultType,而是使用了resultMap。

resultMap也用来做关联关系等操作。

resultMap元素子元素
 constructor – 类在实例化时,用来注入结果到构造方法中
  idArg – ID参数;标记结果作为ID可以帮助提高整体效能
  arg – 注入到构造方法的一个普通结果
 id – 一个ID结果;标记结果作为ID可以帮助提高整体效能
 result – 注入到字段或JavaBean属性的普通结果
 association – 一个复杂的类型关联;许多结果将包成这种类型
 嵌入结果映射 – 结果映射自身的关联,或者参考一个
 collection – 复杂类型的集
 嵌入结果映射 – 结果映射自身的集,或者参考一个
 discriminator – 使用结果值来决定使用哪个结果映射
  case – 基于某些值的结果映射
  嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相同的元素,或者它可以参照一个外部的结果映射。

id,result
这些是结果映射最基本内容。id和result都映射一个单独列的值到简单数据类型(字符串,整型,双精度浮点数,日期等)的单独属性或字段。
这两者之间的唯一不同是id表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是缓存和关联关系映射。
他们的属性:
property
映射到列结果的字段或属性。如果匹配的是存在的,和给定名称相同的JavaBeans的属性,那么就会使用。否则MyBatis将会寻找给定名称的字段。这两种情形你可以使用通常点式的复杂属性导航。比如,你可以这样映射一些东西:“username”,或者映射到一些复杂的东西:“address.street.number”。
column
从数据库中得到的列名,或者是列名的重命名标签。这也是通常和会传递给resultSet.getString(columnName)方法参数中相同的字符串。
javaType
一个Java类的完全限定名,或一个类型别名(参加上面内建类型别名的列表)。如果你映射到一个JavaBean,MyBatis通常可以断定类型。然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证所需的行为。
jdbcType
在这个表格之后的所支持的JDBC类型列表中的类型。JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。这是JDBC的需要,而不是MyBatis的。如果你直接使用JDBC编程,你需要指定这个类型-但仅仅对可能为空的值。
typeHandler
我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。这个属性值是类的完全限定名或者是一个类型处理器的实现,或者是类型别名。
支持的JDBC类型
BIT
FLOAT
CHAR
TIMESTAMP
OTHER
UNDEFINED
TINYINT
REAL
VARCHAR
BINARY
BLOB
NVARCHAR
SMALLINT
DOUBLE
LONGVARCHAR
VARBINARY
CLOB
NCHAR
INTEGER
NUMERIC
DATE
LONGVARBINARY
BOOLEAN
NCLOB
BIGINT
DECIMAL
TIME
NULL
CURSOR
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<id property="id" column="ID" />
<result property="userName" column="USER_NAME" />
<result property="age" column="AGE" />
</resultMap>


constructor构造方法
<constructor>
<idArg column="id" javaType="int"/>
<arg column=”username” javaType=”String”/>
</constructor>
构造方法注入允许你在初始化时为类设置属性的值,而不用暴露出公有方法。MyBatis也支持私有属性和私有JavaBeans属性来达到这个目的,但是我们可能更青睐构造方法注入。
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<constructor>
<idArg column="ID" javaType="_int" />
<arg column="USER_NAME" javaType="string" />
</constructor>
<id property="id" column="ID" />
<result property="userName" column="USER_NAME" />
<result property="age" column="AGE" />
</resultMap>
注意上面的情况,我们不仅仅在构造定义了构造,而且定义了属性id,和username,这个时候ibatis会在构造的时候把id和userName两个参数传递进去,因为后面还定义了id 属性值id,和result 属性值userName,那么它还会再构造完毕后,再次把id和userName传递进去。

还有一点就是参数定义的顺序要和我们在constructor中定义的顺序一样,因为java反射机制无法获取参数的名字的。

他们的属性:
column
来自数据库的类名,或重命名的列标签。这和通常传递给resultSet.getString(columnName)方法的字符串是相同的。
javaType
一个Java类的完全限定名,或一个类型别名(参加上面内建类型别名的列表)。如果你映射到一个JavaBean,MyBatis通常可以断定类型。然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证所需的行为。
jdbcType
在这个表格之前的所支持的JDBC类型列表中的类型。JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。这是JDBC的需要,而不是MyBatis的。如果你直接使用JDBC编程,你需要指定这个类型-但仅仅对可能为空的值。
typeHandler
我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。这个属性值是类的完全限定名或者是一个类型处理器的实现,或者是类型别名。

association一对一关联。
添加表address
CREATE TABLE `address` (
  `ID` int(11) NOT NULL auto_increment,
  `ADDRESS` varchar(200) default NULL,
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


修改account表结构
CREATE TABLE `account` (
  `ID` int(11) NOT NULL auto_increment,
  `USER_NAME` varchar(50) default NULL,
  `AGE` int(11) default NULL,
  `ADDRESS_ID` int(11) NOT NULL,
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
增加了一个ADDRESS_ID字段
添加类Address

package com.liyixing.ibatis.model;

import java.io.Serializable;

public class Address implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

private int id;
private String address;

public Address() {
super();
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

修改Account实体,添加属性
private Address address;

Account映射中的resultMap
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<constructor>
<idArg column="ACCOUNT_ID" javaType="_int" />
<arg column="ACCOUNT_USER_NAME" javaType="string" />
</constructor>
<id property="id" column="ACCOUNT_ID" />
<result property="userName" column="ACCOUNT_USER_NAME" />
<result property="age" column="ACCOUNT_AGE" />

<association property="address" column="ACCOUNT_ADDRESS_ID"
javaType="com.liyixing.ibatis.model.Address">
<id property="id" column="ADDRESS_ID" />
<result property="address" column="ADDRESS" />
</association>
</resultMap>
<association property="address" column="ACCOUNT_ADDRESS_ID"
javaType="com.liyixing.ibatis.model.Address">这里的javaType,官方文档说是会自动算出类型,但是我不写javaType发现它获取的Class type是null。抛出了空指针异常。所以我写上了。安全一些。
column="ACCOUNT_ADDRESS_ID"这个属性主要是应用于嵌套查询方式。
select
<select id="getAccount" parameterType="int" resultMap="account">
SELECT
a.ID as ACCOUNT_ID,
a.USER_NAME as ACCOUNT_USER_NAME,
a.AGE as
ACCOUNT_AGE,
a.ADDRESS_ID as ACCOUNT_ADDRESS_ID,
ad.ID as
ADDRESS_ID,
ad.ADDRESS as ADDRESS
FROM account as a
left join address as ad
on ad.ID
= a.ADDRESS_ID
WHERE a.ID = #{id}
</select>
我们需要告诉batis如何加载关联。有两种方式。
嵌套查询,通过执行另一个sql映射语句来返回。
嵌套结果,使用嵌套结果映射来同时返回本对象和关联的对象。我上面使用的就是这一种。

association属性:
property
映射到列结果的字段或属性。如果匹配的是存在的,和给定名称相同的JavaBeans的属性,那么就会使用。否则MyBatis将会寻找给定名称的字段。这两种情形你可以使用通常点式的复杂属性导航。比如,你可以这样映射一些东西:“username”,或者映射到一些复杂的东西:“address.street.number”。
column
应用于嵌套查询语句方式。来自数据库的类名,或重命名的列标签。这和通常传递给resultSet.getString(columnName)方法的字符串是相同的。
注意:要处理复合主键,你可以指定多个列名通过column=”{prop1=col1,prop2=col2}”这种语法来传递给嵌套查询语句。这会引起prop1和prop2以参数对象形式来设置给目标嵌套查询语句。
javaType
一个Java类的完全限定名,或一个类型别名(参加上面内建类型别名的列表)。如果你映射到一个JavaBean,MyBatis通常可以断定类型。然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证所需的行为。
jdbcType
在这个表格之前的所支持的JDBC类型列表中的类型。JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。这是JDBC的需要,而不是MyBatis的。如果你直接使用JDBC编程,你需要指定这个类型-但仅仅对可能为空的值。
typeHandler
我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。这个属性值是类的完全限定名或者是一个类型处理器的实现,或者是类型别名。

嵌套查询方式:
select属性
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<constructor>
<idArg column="ID" javaType="_int" />
<arg column="USER_NAME" javaType="string" />
</constructor>
<id property="id" column="ACCOUNT_ID" />
<result property="userName" column="USER_NAME" />
<result property="age" column="AGE" />

<association property="address" column="ADDRESS_ID"
javaType="com.liyixing.ibatis.model.Address" select="getAddress">
</association>
</resultMap>
这里的关联配置中,使用select属性,值是getAddress,batis会调用这个id=getAddress的select,也就是说会执行两个sql语句。
association property="address" column="ADDRESS_ID"的column属性会作为参数传递给参数语句中id为getAddress的参数语句。

<select id="getAddress" parameterType="int"
resultType="com.liyixing.ibatis.model.Address">
select * from address where id = #{id}
</select>

<select id="getAccount" parameterType="int" resultMap="account">
SELECT ID,
USER_NAME,
AGE,
ADDRESS_ID
FROM account
WHERE ID = #{id}
</select>
这种方式会造成sql语句执行过多。

如果我们想在address中,对account进行关联。表结构,模型都不变,添加address的映射文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liyixing.ibatis.dao.AddressDao">
<resultMap type="com.liyixing.ibatis.model.Address" id="address">
<id property="id" column="ID" />
<result property="address" column="ADDRESS" />

<association property="account" column="ID"
javaType="com.liyixing.ibatis.model.Account" select="getAccount">
</association>
</resultMap>

<select id="getAddress" parameterType="int" resultMap="address">
select *
from address where id = #{id}
</select>

<select id="getAccount" parameterType="int"
resultType="com.liyixing.ibatis.model.Account">
select * from account where ADDRESS_ID = #{id}
</select>
</mapper>
可以从上面的例子中看出来。<association property="account" column="ID"
javaType="com.liyixing.ibatis.model.Account" select="getAccount">这个元素的column属性会被作为参数传递过去给对应的sql。


collection集合
添加表message,是account用户的发言
CREATE TABLE `message` (
  `ID` int(11) NOT NULL auto_increment,
  `ACCOUNT_ID` int(11) NOT NULL,
  `MESSAGE` varchar(255) default NULL,
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<constructor>
<idArg column="ID" javaType="_int" />
<arg column="USER_NAME" javaType="string" />
</constructor>
<id property="id" column="ACCOUNT_ID" />
<result property="userName" column="USER_NAME" />
<result property="age" column="AGE" />

<association property="address" column="ADDRESS_ID"
javaType="com.liyixing.ibatis.model.Address" select="getAddress">
</association>

<collection property="messages" javaType="ArrayList"
column="ID" ofType="com.liyixing.ibatis.model.Message"
select="selectMyMessages">
<id property="id" column="ID"/>
<result property="message" column="MESSAGE"/>
</collection>
</resultMap>
<select id="selectMyMessages" parameterType="int"
resultType="com.liyixing.ibatis.model.Message">
select * from message where ACCOUNT_ID = #{accountId}
</select>

以上的配置<collection property="messages" javaType="ArrayList"
column="ID" ofType="com.liyixing.ibatis.model.Message"
select="selectMyMessages">中依然可以看到column会被做为参数传递过去。

一个嵌套结果的方式
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<constructor>
<idArg column="ACOUNT_ID" javaType="_int" />
<arg column="ACOUNT_USER_NAME" javaType="string" />
</constructor>
<id property="id" column="ACCOUNT_ID" />
<result property="userName" column="ACOUNT_USER_NAME" />
<result property="age" column="ACOUNT_AGE" />

<collection property="messages" javaType="ArrayList"
ofType="com.liyixing.ibatis.model.Message">
<id property="id" column="MESSAGE_ID" />
<result property="message" column="MESSAGE" />
</collection>
</resultMap>
这里的column可以省略。

ofType属性:
这个属性用来区分JavaBean(或字段)属性类型,是用来指定集合中的包含(泛型)类型的。

discriminator鉴别器
类似于java的switch可以根据结果制定实际的映射器
有一个Message类

package com.liyixing.ibatis.model;

import java.io.Serializable;

public class Message implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

private int id;
private Account account;
private String message;
private short messageType = (short) -1;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Account getAccount() {
return account;
}

public void setAccount(Account account) {
this.account = account;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public short getMessageType() {
return messageType;
}

public void setMessageType(short messageType) {
this.messageType = messageType;
}
}

这里的messageType = -1,是因为数据库中我的测试数据,是一条message记录的messageType=0,另一条messageType=1;而java的short自动初始化的时候,值也是0.改成-1就能更清楚的看到结果。
message.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liyixing.ibatis.dao.IMessageDao">
<resultMap type="com.liyixing.ibatis.model.Message" id="message">
<id property="id" column="ID" />
<discriminator javaType="_int" column="MESSAGE_TYPE">
<case value="1" resultMap="messageType"></case>
</discriminator>
</resultMap>

<resultMap type="com.liyixing.ibatis.model.Message" id="messageType">
<result property="messageType" column="MESSAGE_TYPE" />
</resultMap>
</mapper>
这里有<discriminator javaType="_int" column="MESSAGE_TYPE">
<case value="1" resultMap="messageType"></case>
</discriminator>
当值为1才会映射MESSAGE_TYPE
Account.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liyixing.ibatis.dao.IAccountDao">
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<id property="id" column="ID" />
<result property="userName" column="USER_NAME" />
<collection property="messages" javaType="ArrayList"
column="ID" ofType="com.liyixing.ibatis.model.Message" select="getMyMessage">
</collection>
</resultMap>

<select id="getMyMessage" parameterType="_int"
resultMap="message">
SELECT ID,
USER_ID,
MESSAGE,
MESSAGE_TYPE
FROM message
WHERE USER_ID = #{id}
</select>

<select id="getAccount" parameterType="_int" resultMap="account">
SELECT *
FROM account WHERE ID = #{id}
</select>
</mapper>
这里我同时测试了collection和跨文件访问resultMap,发现跨文件访问resultMap是允许的。

调用getAccount的select,发现当message_type字段值为1,才会调用id=messageType的resultMap
分享到:
评论

相关推荐

    MyBatis SQL映射文件

    SQL映射文件的几个顶级元素(按照定义的顺序) 1.mapper - namespace 2.cache - 配置给定命名空间的缓存 3.cache-ref – 从其他命名空间引用缓存配置 4.resultMap –用来描述数据库结果集和对象的对应关系 5.sql – ...

    Mybatis-03 SQL映射文件

    详解MyBatis框架中SQL映射文件的具体配置,包括实现增删改查操作、根据主键生成方式获取主键值、针对单个参数、多个参数和命名参数的处理与参数值获取以及select标签中resultMap的详解

    ibatis SQL映射文件、DAO、model自动生成工具源码

    ibatis SQL映射文件、DAO、model自动生成工具源码 1.没有注释,生成的代码非常简单,不像其他自动生成工具生成一大堆无用的东西 2.配置简单,只需配置表明,数据库连接,生成的路径即可

    SQL语句映射文件

    SQL 映射XML 文件是所有sql语句放置的地方。需要定义一个workspace,一般定义为对应的接口类的路径。写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用。

    Mybatis核心组成部分之SQL映射文件揭秘详解

    MyBatis真正的力量是在映射语句中,下面这篇文章主要给大家介绍了关于Mybatis核心组成部分之SQL映射文件揭秘的相关资料,现在分享给大家,给大家做个参考。一起跟随小编过来看看吧

    mybatis动态sqlSQL 映射 XML 文件是所有 sql 语句

    mybatis动态sql:SQL 映射 XML 文件是所有 sql 语句放置的地方。需要定义一个 workspace,一般定义为对应的接口类的路径。写好 SQL 语句映射文件后需要在 MyBAtis 配置文件 mappers 标签中引用。

    SQL实验报告 主要用于查询语句

    一些实验语句,一些实验题目,希望有所帮组。还有附加截屏 在做题以及数据库开发有所用处。主要用于查询语句,有很多心血

    iBATIS-SqlMaps,ibatis映射文件

    iBATIS-SqlMaps,ibatis映射文件

    MyBatis动态SQL.pdf

    在数据库操作中,经常需要根据不同的业务逻辑和条件来构建动态的SQL语句。传统的硬编码SQL语句在面对复杂的业务逻辑时...这样,同一个SQL映射文件就可以处理多种不同的业务场景,极大地提高了代码的复用性和可维护性。

    MyBatis基本了解

    MyBatis基本了解

    自己整理的Mybatis必须掌握的知识。从原生方式的使用再到常用的Mapper文件的使用解析,共48页

    2.2 SQL映射文件 三、 准备 3.1 加载配置文件 3.2 log4j.properties 四、 原生方式增删改查 4.1 注意 4.2 增删查改 4.3 原生方式的坏处 五、 接口方式增删改查 5.1 接口方式的好处 5.2 规则 5.3 步骤 六、 三大核心...

    MyBatis逆向工程.zip

    MyBatis官方为我们提供了一个逆向工程,通过这个逆向工程,只需要建立好数据表,MyBatis就会根据这个表自动生成pojo类、mapper接口、sql映射文件 加入Mybatis逆向工程的依赖 设计数据表 配置逆向工程配置信息 运行...

    深入探索MyBatis:全局配置文件解析及应用优化策略

    关键的配置元素如environments定义了数据库连接及事务管理,而mappers则指定了SQL映射文件的位置。此外,插件和类型处理器的配置提供了自定义处理逻辑的能力,增强了MyBatis的灵活性。通过对这些元素的深入理解,...

    c# 做成数据库生成 nhibernate映射文件程序,包括oracle 和sql server

    c# 做成数据库生成 nhibernate映射文件程序,包括oracle 和sql server数据库,很好用,很省时间,省去程序员许多麻烦。

    Mybatis框架看了就会

    mybatis支持自定义 SQL、存储过程以及高级映射,可以通过sql映射文件实现sql语句的编写,支持动态sql,用条件判断进行查询可以实现sql复用。 2、mybatis优势 通过参数映射方式,可以将参数灵活的配置在SQL语句中的...

    Spring Boot整合MyBatis连接 SQL Server(2)

    基于XML的SQL映射文件操作数据库

    SQL异地备份工具,映射网络硬盘,设定时间,自动备份

    3.异机参数:设置存放备份文件机器的参数,映射,映射成功以后在服务器"我的电脑" 中产生Z盘.映射只需做一次,如果不需要了,则删除映射. 4.自动备份出的文件存放在Z盘,文件名包括数据库名和年月日时分秒. 5.点右上角的...

    mybatis资料,传统方式创建mybatis项目1.创建java项目2.导入mybatis资源3.创建主配置文件…………

    创建sql映射文件:接口名称.xml 9.编写测试类,测试接口方法:接口名称+方法+Test.class cn.edu.xxxx. util 存放工具类包 类/接口的格式:名称+Util pojo 存放实体类包 类/接口的格式:表名称 ...

    myBatis相关全部jar包

    没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何...

    Hibernate使用xdoclet生成映射文件和sql语句

    NULL 博文链接:https://javatozhang.iteye.com/blog/2045875

Global site tag (gtag.js) - Google Analytics