Mapper映射语句高阶应用——ResultMap

    resultMap 元素是 MyBatis 中最重要最强大的元素。它就是让你远离 90% 的需要从结果 集中取出数据的 JDBC 代码的那个东西 , 而且在一些情形下允许你做一些 JDBC 不支持的事 情。 事实上 , 编写相似于对复杂语句联合映射这些等同的代码, 也许可以跨过上千行的代码。 ResultMap 的设计就是简单语句不需要明确的结果映射 , 而很多复杂语句确实需要描述它们 的关系。

    我们通过一个连续的例子,来逐步讲解 ReusltMap 。

    要进行 ResultMap 的实验,先设计数据库:

   

上述是数据库的 E-R 图。

create database if not exists mybatis3;

use mybatis3;

drop table if exists tag;
create table if not exists tag(
  id int primary key not null,
  name varchar(100) not null
);

drop table if exists author;
create table if not exists author(
  id int primary key not null,
  username varchar(100) not null,
  password varchar(100) not null,
  email varchar(100),
  bio varchar(100),
  favourite_section varchar(100)
);

drop table if exists blog;
create table if not exists blog(
  id int primary key not null,
  title varchar(100) not null,
  author_id int not null,
  constraint blog_author_fk foreign key(author_id) references author(id)
    on update cascade on delete cascade
);

drop table if exists post;
create table if not exists post(
  id int primary key not null,
  blog_id int not null,
  author_id int not null,
  create_on date not null,
  section varchar(100),
  subject varchar(100),
  draft varchar(100),
  body varchar(200),
  constraint post_blog_fk foreign key(blog_id) references blog(id)
    on update cascade on delete cascade,
  constraint post_author_fk foreign key(author_id) references author(id)
    on update cascade on delete cascade
);

drop table if exists post_tag;
create table if not exists post_tag(
  post_id int not null,
  tag_id int not null,
  primary key(post_id,tag_id),
  constraint postTag_post_fk foreign key(post_id) references post(id)
    on update cascade on delete cascade,
  constraint postTag_tag_fk foreign key(tag_id) references tag(id)
    on update cascade on delete cascade
);

drop table if exists comment;
create table if not exists comment(
  id int primary key not null,
  post_id int not null,
  name varchar(100) not null,
  comment varchar(300),
  constraint comment_post_fk foreign key(post_id) references post(id)
    on update cascade on delete cascade
);

insert into tag values(111,'科技');
insert into tag values(222,'文学');
insert into tag values(333,'文档');

insert into author values(1,'zjl','123','123@123.com','no','spring');
insert into author values(2,'ddt','123','ddt@123.com','no','auto');
insert into author values(3,'woya','123','woya@123.com','no','no');
insert into author values(4,'yoiu','123','yoiu@123.com','no','what');
insert into author values(5,'dwks','123','dwks@123.com','no','are');

insert into blog values(1,'博客1',1);
insert into blog values(2,'博客2',1);
insert into blog values(3,'博客3',1);
insert into blog values(4,'博客4',2);
insert into blog values(5,'博客5',2);
insert into blog values(6,'博客6',3);
insert into blog values(7,'博客7',4);
insert into blog values(8,'博客8',5);

insert into post values(1,1,1,20130729,'section1','subject1','draft1','body1');
insert into post values(2,1,1,20130729,'section2','subject2','draft2','body2');
insert into post values(3,1,1,20130729,'section3','subject3','draft3','body3');
insert into post values(4,2,1,20130729,'section4','subject4','draft4','body4');
insert into post values(5,2,4,20130729,'section5','subject5','draft5','body5');
insert into post values(6,2,2,20130729,'section6','subject6','draft6','body6');
insert into post values(7,3,2,20130729,'section7','subject7','draft7','body7');
insert into post values(8,3,4,20130729,'section8','subject8','draft8','body8');
insert into post values(9,4,2,20130729,'section9','subject9','draft9','body9');
insert into post values(10,5,5,20130729,'section10','subject10','draft10','body10');
insert into post values(11,6,5,20130729,'section11','subject11','draft11','body11');
insert into post values(12,7,5,20130729,'section12','subject12','draft12','body12');
insert into post values(13,8,3,20130729,'section13','subject13','draft13','body13');

insert into post_tag values(1,111);
insert into post_tag values(1,333);
insert into post_tag values(1,222);
insert into post_tag values(2,111);
insert into post_tag values(2,222);
insert into post_tag values(2,333);
insert into post_tag values(3,333);
insert into post_tag values(4,333);
insert into post_tag values(4,222);
insert into post_tag values(4,111);
insert into post_tag values(5,333);
insert into post_tag values(6,333);
insert into post_tag values(6,222);
insert into post_tag values(7,333);
insert into post_tag values(7,222);
insert into post_tag values(7,111);
insert into post_tag values(8,222);
insert into post_tag values(9,222);
insert into post_tag values(10,222);
insert into post_tag values(11,222);
insert into post_tag values(12,111);
insert into post_tag values(13,111);
insert into post_tag values(13,222);
insert into post_tag values(13,333);

insert into comment values(1,1,'评论1','评论内容1');
insert into comment values(2,1,'评论2','评论内容2');
insert into comment values(3,2,'评论3','评论内容3');
insert into comment values(4,2,'评论4','评论内容4');
insert into comment values(5,2,'评论5','评论内容5');
insert into comment values(6,3,'评论6','评论内容6');
insert into comment values(7,4,'评论7','评论内容7');
insert into comment values(8,5,'评论8','评论内容8');
insert into comment values(9,6,'评论9','评论内容9');
insert into comment values(10,7,'评论10','评论内容10');
insert into comment values(11,8,'评论11','评论内容11');
insert into comment values(12,9,'评论12','评论内容12');
insert into comment values(13,10,'评论13','评论内容13');
insert into comment values(14,11,'评论14','评论内容14');
insert into comment values(15,12,'评论15','评论内容15');
insert into comment values(16,12,'评论16','评论内容16');
insert into comment values(17,13,'评论17','评论内容17');

因为是进行 MyBatis 的 ResultMap 的相关实验,所以我也就不详细描述数据库设计的相关过程了,只是尽量做到数据库的复杂,包括一些一对一,一对多,多对一以及多对多联系。

所有的数据库涉及到了 5 个类,这些类为: Blog 、 Comment 、 Post 、 Tag 、 Author 。不过这些类中的具体属形成员咱们暂时不添加,因为这关系到 ResultMap 的具体描述,这里我们不做具体解释,这些都会在之后的测试实验中提到。

前提工作已经做好了,现在可以开始测试:

基础 ResultMap

我们先来看个简单的例子,这个例子只是包括了最简单的一些描述,没有复杂的联系(即外键)。

通过数据库,我们选择 Tag 这个类,因为它比较简单,就只有一个 id 和 name 的属性。

将 Tag 补充如下:

package net.mybatis.model;

public class Tag {
  private int id;
  private String name;

  public int getId() {
    return id;
  }

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

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return this.getClass().getName() + ":[id:" + this.id + ",name:"
        + this.name + "]";
  }
}

 

我们接下来要进行的是进行 SQL 语句的映射:

<select id="test1" parameterType="int" resultType="Tag">
        select id,name from tag where id = #{id}
</select>

以之前的挤出来说,我们很容易就可以写出上述的语句,不过这个跟 ResultMap 又有什么关系呢?

MyBatis 其实已经在幕后自动创建了一个 ResultMap 与之对应,而我们不需要手动进行编写,它的规则是基于属性名来映射列到 JavaBean 的属性上。

当列名与 JavaBean 的属性名不一致的时候,可以使用 as 来设定一个别名,因为这个比较简单,我就直接套用 MyBatis 的文档来描述:

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

很容易就知道 as 的具体用法了。

不过,我们也可以用 ResultMap 来定义,这个时候为了方便,我先用 as 来重新设定列名,再根据 ResultMap 更改回去:

<select id="test1" parameterType="int" resultMap="test1Map">
        select
        	id as tag_id,
        	name
        from
        	tag
        where
        	id = #{id}
</select>
<resultMap type="Tag" id="test1Map">
        <id column="tag_id" property="id"/>
        <result column="name" property="name"/>
</resultMap>

在这里我先将 id 的列名利用数据库的 as 别名为 tag_id ,之后,在映射的时候,通过 ResultMap 将, tag_id 重新映射为 id 的属性名。

之前的 select 标签属性中的 resultType 则需要更改为 resultMap ,它的值为引用 ResultMap 标签的 id 值。

resultMap 标签包含的子标签的具体属性,这里先简要介绍一下:

column :数据库返回过来的列名

property :要映射对象即( JavaBean )的属性名。

至于其他的具体属性将会在之后介绍。

 

高级结果映射

 

           ResultMap 中包含的子标签有如下几种:

   

constructor


构造方法


id


一个 ID 结果


result


普通属性字段


association


一个复杂的类型关联,为一对多的形式


collection


复杂类型的集合,为多对一的形式


discriminator


根据结果值引用不同的 ResultMap

 

                 上述的子标签会在之后详细介绍,现在模糊不懂没有什么关系。

 

MyBatis 建议我们的最佳实践也是让我们一步步进行了解,如果一下子进行过于复杂的结果映射,那么不出错是不可能的。

 

id&result

id 标签为定义一个唯一标识,也就是数据库中诉说的主键

result 则为一个普通的属性

id 与 result 的标签的属性:

   

property


映射到 javaBean 的字段属性名


column


数据库返回的列名


javaType


该值( id 或 result )对应的 java 类型


jdbcType


该值在数据库中的类型


typeHandler


覆盖默认的类型处理器

 

               

                 构造方法

除了使用 id 和 result 来注入 javaBean 属性外,我们还可以通过构造方法的形式来注入属性,比如,我们将 Tag 类中的 id 和 name 都通过构造方法来构建:

package net.mybatis.model;

public class Tag {
  private Integer id;
  private String name;

  public Tag(Integer id,String name){
    this.id = id;
    this.name = name;
  }

  @Override
  public String toString() {
    return this.getClass().getName() + ":[id:" + this.id + ",name:"
        + this.name + "]";
  }
}
<resultMap type="Tag" id="test1Map">
        <constructor>
            <idArg column="tag_id" javaType="int"/>
            <arg column="name" javaType="string"/>
        </constructor>
</resultMap>

 

    其中, idArg 为主键, arg 为普通属性。

   

    注意:在定义构造方法的时候要注意的是,必须以类的形式作为构造函数的参数。比如 int ,在构造的时候,必须更改为 Integer ,具体的原因是 javaType声明的为 int ,这个在 TypeAlianses 中反射到的 java 类型为 Integer ,如果真的只想用 int 来使用构造,那么需要将 javaType 的 int 更改为 _int ,这个问题在文档中也没有提及,以至于在文档它的实际结果也是错误的。

 

   

    我们的数据库是一个博客数据库,因此,一片博文会对应一个作者,而一个作者拥有多篇博文,这在数据库中的关系为多对一。

    而表示这种关系,我们可以使用 association 。

    我们定义 Author 类:

package net.mybatis.model;

public class Author {
  private int id;
  private String username;
  private String password;
  private String email;
  private String bio;
  private String favouriteSection;

  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 getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public String getBio() {
    return bio;
  }

  public void setBio(String bio) {
    this.bio = bio;
  }

  public String getFavouriteSection() {
    return favouriteSection;
  }

  public void setFavouriteSection(String favouriteSection) {
    this.favouriteSection = favouriteSection;
  }

  @Override
  public String toString() {
    return this.getClass().getName() + ":[id:" + this.id + ",username:"
        + this.username + ",password:" + this.password + ",email:"
        + this.email + ",bio:" + this.bio + ",favouriteSection:"
        + this.favouriteSection + "]";
  }

}

 

    接着定义 Blog 类:

package net.mybatis.model;

public class Blog {
  private int id;
  private String title;
  private Author author;

  public int getId() {
    return id;
  }

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

  public int getId() {
    return id;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public Author getAuthor() {
    return author;
  }

  public void setAuthor(Author author) {
    this.author = author;
  }

  @Override
  public String toString() {
    return this.getClass().getName() + ":[id:" + this.id + ",title:"
        + this.title + ",author:" + this.author + ",posts:" + "]";
  }
}

我们在 Blog 类中加了一个 Author 的对象,这个是用来关联 Author 类的。

 

因为 MyBatis 在定义 SQL 映射后自动映射的过程中,需要 JAVABean 有一个联系的属性。

<select id="test2" parameterType="int" resultMap="test2Map" >
        select
        	B.id as blog_id,
        	B.title as blog_title,
        	B.author_id as blog_author_id,
        	A.id as author_id,
        	A.username as author_username,
        	A.password as author_password,
        	A.email as author_email,
        	A.bio as author_bio,
        	A.favourite_section as author_favourite_section
        from
        	Blog B
        	left join Author A on (B.author_id = A.id)
        where
        	B.id = #{id}
    </select>
    <resultMap type="Blog" id="test2Map">
        <id property="id" column="blog_id" javaType="int"/>
        <result property="title" column="blog_title" javaType="string"/>
        <association property="author" column="blog_author_id" javaType="Author">
            <id property="id" column="author_id" javaType="_int"/>
      <result property="username" column="author_username" javaType="string"/>
      <result property="password" column="author_password" javaType="string"/>
      <result property="email" column="author_email" javaType="string"/>
      <result property="bio" column="author_bio" javaType="string"/>
      <result property="favouriteSection" column="author_favourite_section" javaType="string"/>
        </association>
</resultMap>

 

在 <resultMap> 标签中,存在着的 association 标签即为关联。

association 的处理有两种方式,一种是 select 的嵌套查询,另一种是嵌套 ResultMap 结果。

嵌套 ResultMap 结果就是上述的例子,在这个例子中,还可以将 <association> 标签中的 Author 剥离开来,重新形成一个 id 为 authorResult 的 resultMap ,那么这个 authorResult 的 resultMap 就可以重用。而 <assocation> 只需要引用 resultMap 这个属性值为 authorResult 即可。

另外一种 select 的嵌套,如,可将上述的例子分解为:

<resultMap type="Blog" id="test2Map">
        <id property="id" column="blog_id" javaType="int"/>
        <result property="title" column="blog_title" javaType="string"/>
        <association property="author" column="blog_author_id" javaType="Author" select="test2DivideSelect">
        </association>
    </resultMap>
    <select id="test2DivideSelect" parameterType="int" resultType="Author">
        select * from author where id = #{id}
</select>

这种方式简单并且容易理解,不过它却有个致命的缺点,那就是如果查询的为大型数据集合和列表的情况下,那么所需要查询的 SQL 语句条数的数量会是惊人的。即是: “N+1” 的情况,即需要对返回回来的 N 条数据进行细节添加。

        如果 Blog 中存在一个相同的属性,这个属性,属性名字不同,但是类型相同,比如, Blog 中存在一个 author ,如果还存在一个 co-author 又该如何,在这种情况 

下,我们可以使用 columnPrefix 属性:

<resultMap id="blogResult" type="Blog">
    <id property="id" column="blog_id" />
    <result property="title" column="blog_title" />
    <association property="author" resultMap="authorResult" />
    <association property="coAuthor" resultMap="authorResult"
      columnPrefix="co_" />
</resultMap>

 

 

多对一映射

相对于上面的一对多映射,还有一种就是多对一映射,上述就说过,一篇博文对应有一个作者,那么一个作者必然对应有多篇博文。这个关系就是多对一的关系,而想要使用这个关系,那么就需要用到 collection 的标签。

 

将 Author 的类修改如下:

package net.mybatis.model;

import java.util.List;

public class Author {
  private int id;
  private String username;
  private String password;
  private String email;
  private String bio;
  private String favouriteSection;

  private List<Blog> blogs;

  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 getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public String getBio() {
    return bio;
  }

  public void setBio(String bio) {
    this.bio = bio;
  }

  public String getFavouriteSection() {
    return favouriteSection;
  }

  public void setFavouriteSection(String favouriteSection) {
    this.favouriteSection = favouriteSection;
  }

  public List<Blog> getBlogs() {
    return blogs;
  }

  public void setBlogs(List<Blog> blogs) {
    this.blogs = blogs;
  }

  @Override
  public String toString() {
    return this.getClass().getName() + ":[id:" + this.id + ",username:"
        + this.username + ",password:" + this.password + ",email:"
        + this.email + ",bio:" + this.bio + ",favouriteSection:"
        + this.favouriteSection + ",blogs:"+this.blogs+"]";
  }

}

 

我们添加了:

private List<Blog> blogs;

这个属性,然后设置了它的 setter 和 getter 方法。

下面,如果我们要通过一个作者获取到他写了哪些博文,那么该如何做呢?

<select id="test3" parameterType="int" resultMap="test3Map">
        select
        	A.id as author_id,
        	A.username as author_username,
        	A.email as author_email,
        	B.id as blog_id,
        	B.title as blog_title,
        	B.author_id as blog_author_id
        from
        	Author A
        	left join Blog B on (A.id = B.author_id)
        where
        	A.id = #{id}
    </select>
    <resultMap type="Author" id="test3Map">
        <id column="author_id" property="id" javaType="_int"/>
        <result column="author_username" property="username" javaType="string"/>
        <result column="author_email" property="email" javaType="string"/>
        <collection column="blog_author_id" property="blogs" javaType="ArrayList" ofType="Blog">
            <id column="blog_id" property="id" javaType="_int"/>
            <result column="blog_title" property="title" javaType="string"/>
        </collection>
</resultMap>

 

 

就如上述所说, collection 即表示“多个 ” 的关系, 必须注意的是,一定要指定 ofType 属性,这个 ofType 属性指的是集合的元素类型,缺少这个属性, MyBatis 会报出设定参数错误的提示 

 

就如同 association 一样, collection 也分两种:一种为嵌套查询 select ,另一种为嵌套结果 resultMap ,用法也跟 association 一致,在这里就不再详细述说。

 

 

 

对于上述所说的一对多,多对一,数据库当然还有另外一种形式:多对多。这种关系在前面的基础上,应该已经能够猜的出来了,其实也就是在对多对的两个类中添加一个对方的私有 List 集合属性。这样在 select 映射中,不管用哪种为主体,都可以成功映射。

 

 

 

最后来个复杂的,包括了以上所有的描述:

<select id="selectBlogDetails" parameterType="int"
    resultMap="detailedBlogResultMap">
      select
           B.id as blog_id,
           B.title as blog_title,
           B.author_id as blog_author_id,
           A.id as author_id,
           A.username as author_username,
           A.password as author_password,
           A.email as author_email,
           A.bio as author_bio,
           A.favourite_section as author_favourite_section,
           P.id as post_id,
           P.blog_id as post_blog_id,
           P.author_id as post_author_id,
           P.create_on as post_create_on,
           P.section as post_section,
           P.subject as post_subject,
           P.draft as draft,
           P.body as post_body,
           C.id as comment_id,
           C.post_id as comment_post_id,
           C.name as comment_name,
           C.comment as comment_text,
           T.id as tag_id,
           T.name as tag_name
      from Blog B
           left join Author A on B.author_id = A.id
           left join Post P on B.id = P.blog_id
           left join Comment C on P.id = C.post_id
           left join Post_Tag PT on PT.post_id = P.id
           left join Tag T on PT.tag_id = T.id
      where B.id = #{id}
  </select>
  <resultMap id="detailedBlogResultMap" type="Blog">
    <constructor>
      <idArg column="blog_id" javaType="int" />
    </constructor>
    <result property="title" column="blog_title" />
    <association property="author" column="blog_author_id" javaType="Author">
      <id property="id" column="author_id" />
      <result property="username" column="author_username" />
      <result property="password" column="author_password" />
      <result property="email" column="author_email" />
      <result property="bio" column="author_bio" />
      <result property="favouriteSection" column="author_favourite_section" />
    </association>
    <!-- <association property="author" column="author_id" javaType="Author" select="selectAuthor"></association> -->
    <collection property="posts" javaType="ArrayList" column="post_blog_id" ofType="Post">
      <id property="id" column="post_id" />
      <result property="subject" column="post_subject" />
      <association property="author" column="post_author_id" javaType="Author" />
      <collection property="comments" javaType="ArrayList" column="comment_post_id" ofType="Comment">
        <id property="id" column="comment_id" />
      </collection>
      <collection property="tags" javaType="ArrayList" ofType="Tag">
        <id property="id" column="tag_id" />
        <result property="name" column="tag_name"/>
      </collection>
    </collection>
</resultMap>

 

 

对于同一个数据库来说,我们往往通过不同的查询会返回不同的结果(即返回数据库的列不同)。在这种情况下,鉴别器的作用就凸显出来了。我们通过比较不同的鉴别器类型的值来判断使用哪个 resultMap 。

为了举这个例子,我们创建一个新的表:

drop table if exists dis;
create table if not exists dis(
  id int primary key not null,
  name varchar(100) not null,
  type_id int not null,
  test1 varchar(100),
  test2 varchar(100),
  test3 varchar(100)
);

insert into dis values(1,'dis1',1,'test11','test21','test31');
insert into dis values(2,'dis2',1,'test12','test22','test32');
insert into dis values(3,'dis3',2,'test13','test23','test33');
insert into dis values(4,'dis4',2,'test14','test24','test34');
insert into dis values(5,'dis5',2,'test15','test25','test35');
insert into dis values(6,'dis6',3,'test16','test26','test36');
insert into dis values(7,'dis7',3,'test17','test27','test37');

创建 Dis 类

package net.mybatis.model;

public class Dis {
  private int id;
  private String name;
  private int type_id;
  private String test1;
  private String test2;
  private String test3;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getType_id() {
    return type_id;
  }
  public void setType_id(int type_id) {
    this.type_id = type_id;
  }
  public String getTest1() {
    return test1;
  }
  public void setTest1(String test1) {
    this.test1 = test1;
  }
  public String getTest2() {
    return test2;
  }
  public void setTest2(String test2) {
    this.test2 = test2;
  }
  public String getTest3() {
    return test3;
  }
  public void setTest3(String test3) {
    this.test3 = test3;
  }

}

 

接下来就是 SQL 的映射:

<select id="test4" resultMap="test4Map">
        select
        	id,
        	name,
        	type_id as type,
        	test1,
        	test2,
        	test3
        from
        	dis
    </select>
    <resultMap type="Dis" id="test4Map">
        <id column="id" property="id" javaType="_int"/>
        <result column="name" property="name" javaType="string"/>
        <discriminator javaType="_int" column="type" >
            <case value="1" resultType="string">
                <result column="test1" property="test1" javaType="string"/>
            </case>
            <case value="2" resultType="string">
                <result column="test2" property="test2" javaType="string"/>
            </case>
            <case value="3" resultType="string">
                <result column="test3" property="test3" javaType="string"/>
            </case>
        </discriminator>
</resultMap>

在这里需要注意的是,选择的列必须要在类中写出来,而且每个 case 标签中的resultType 属性必须设置,否则 MyBatis 会报空参数异常。

 

到现在为止, Mapper 的高阶应用到此为止。

http://www.tuicool.com/articles/j6ZVFb

http://blog.csdn.net/dearday/article/details/9621113

 

时间: 2024-09-13 03:28:54

Mapper映射语句高阶应用——ResultMap的相关文章

深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap good

上篇<深入浅出Mybatis系列(七)---mapper映射文件配置之insert.update.delete>介绍了insert.update.delete的用法,本篇将介绍select.resultMap的用法.select无疑是我们最常用,也是最复杂的,mybatis通过resultMap能帮助我们很好地进行高级映射.下面就开始看看select 以及 resultMap的用法: 先看select的配置吧: <select <!-- 1. id (必须配置) id是命名空间中的

匿名方法,Lambda表达式,高阶函数

原文:匿名方法,Lambda表达式,高阶函数 匿名方法 c#2.0引入匿名方法,不必创建单独的方法,因此减少了所需的编码系统开销. 常用于将委托和匿名方法关联,例如 1. 使用委托和方法关联: this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click);private void btnRefresh_Click(object sender, EventArgs e){    BindData();} 2. 使用委

Java的MyBatis框架中Mapper映射配置的使用及原理解析_java

Mapper的内置方法model层就是实体类,对应数据库的表.controller层是Servlet,主要是负责业务模块流程的控制,调用service接口的方法,在struts2就是Action.Service层主要做逻辑判断,Dao层是数据访问层,与数据库进行对接.至于Mapper是mybtis框架的映射用到,mapper映射文件在dao层用. 下面是介绍一下Mapper的内置方法: 1.countByExample ===>根据条件查询数量 int countByExample(UserEx

高阶函数、委托与匿名方法

高阶函数(higher-order function)是指把另一个函数作为参数或返回值的函数.例如 在JavaScript语言中,Function是顶级类型.一个函数就是类型为 Function的顶级对象,自 然就可以作为另一个函数的参数或返回值.例如在Microsoft AJAX Library(ASP.NET AJAX 的客户端类库)中有一个被广泛使用的createDelegate方法.该方法接受一个对象A和一个函 数F作为参数,并返回一个函数R.当调用函 数R时,F函数将被调用,并且保证无

Kotlin 简单优雅的高阶函数

Kotlin 简单优雅的高阶函数 最新上架!!!< Kotlin极简教程> 陈光剑 (机械工业出版社) 可直接打开京东,淘宝,当当===> 搜索: Kotlin 极简教程http://www.jianshu.com/p/35b487734339 函数代表一种关系 f 的蕴涵逻辑流.这种蕴涵逻辑流,其实就是映射(Mapping). 一切皆是映射. 我们说组合是编程的本质,其实,组合就是建立映射关系. 我们说, 程序 = 算法+数据结构 我们把程序看做图论里面的一张图G,这里的数据结构就是图

【Scheme归纳】4 高阶函数

高阶函数的介绍 高阶函数的英文名称是Higher Order Function,它们是以函数为参数的函数.主要用于映射(mapping).过滤(filtering).归档(folding)和排序(sorting)表.高阶函数让程序更具模块性,让函数更加通用. 函数sort具有2个参数,一个是需要排序的表,另一个是定序(Ordering)函数.下面展示了按照大小将一个整数表正序排序.而<函数就是本例中函数的定序函数. (sort'(420 -130 138 983 0298 783 -783) <

JS编程建议——74:使用高阶函数

建议74:使用高阶函数高阶函数作为函数式编程众多风格中的一项显著特征,经常被使用.实际上,高阶函数即对函数的进一步抽象.高阶函数至少满足下列条件之一:接受函数作为输入.输出一个函数. 在函数式语言中,函数不但是一种特殊的对象,还是一种类型,因此函数本身是一个可以传来传去的值.也就是说,某个函数在刚开始执行的时候,总可以送入一个函数的参数.传入的参数本身就是一个函数.当然,这个输入的函数相当于某个函数的另外一个函数.当函数执行完毕之后,又可以返回另外一个新的函数,这个返回函数取决于return f

高阶函数与JavaScript

简单的 JavaScript? Web 语言 JavaScript 的原意被很多人曲解了,绝大部分的人(包括以前我在做项目的时候)其实都没有正确地使用 HTML 和 CSS.几乎没有人是通过FP的特性规范来学习 JavaScript 的,他们都是通过流行的 OO 设计教材和阅读以前遗留的代码来学习的.很遗憾的是 OO 这两种学习途径对于他们真正理解 JavaScript 理念都没有多少帮助,甚至还存在着大量的误导.比如在编码中仍未摆脱大量的过程式编程,或着更"高级一点",大量使用伪类来

F#教程:高阶函数

所谓高阶函数就是将某个函数作为输入参数或者返回值的函数.从名字上来看挺难理解的,不过从C#的角度来看就是传入或返回delegate之类的. 在我们自己定义高阶函数之前我们还是先学会使用高阶函数. List中定义了很多高阶函数,这回就学习下其中的几个.首先试下find函数. let list = [15; 7; 8; 3; 6; 10] let even n = n % 2 = 0 let x = List.find even list printfn "%A" x 其中,find的第一