Mapper类详解

[java]  view plain  copy
  1. <span style="font-family:SimSun;font-size:14px;">public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {  
  2.   
  3.   public class Context   
  4.     extends MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {  
  5.     public Context(Configuration conf, TaskAttemptID taskid,  
  6.                    RecordReader<KEYIN,VALUEIN> reader,  
  7.                    RecordWriter<KEYOUT,VALUEOUT> writer,  
  8.                    OutputCommitter committer,  
  9.                    StatusReporter reporter,  
  10.                    InputSplit split) throws IOException, InterruptedException {  
  11.       super(conf, taskid, reader, writer, committer, reporter, split);  
  12.     }  
  13.   }  
  14.     
  15.   /** 
  16.    * Called once at the beginning of the task. 
  17.    */  
  18.   protected void setup(Context context  
  19.                        ) throws IOException, InterruptedException {  
  20.     // NOTHING  
  21.   }  
  22.   
  23.   /** 
  24.    * Called once for each key/value pair in the input split. Most applications 
  25.    * should override this, but the default is the identity function. 
  26.    */  
  27.   @SuppressWarnings("unchecked")  
  28.   protected void map(KEYIN key, VALUEIN value,   
  29.                      Context context) throws IOException, InterruptedException {  
  30.     context.write((KEYOUT) key, (VALUEOUT) value);  
  31.   }  
  32.   
  33.   /** 
  34.    * Called once at the end of the task. 
  35.    */  
  36.   protected void cleanup(Context context  
  37.                          ) throws IOException, InterruptedException {  
  38.     // NOTHING  
  39.   }  
  40.     
  41.   /** 
  42.    * Expert users can override this method for more complete control over the 
  43.    * execution of the Mapper. 
  44.    * @param context 
  45.    * @throws IOException 
  46.    */  
  47.   public void run(Context context) throws IOException, InterruptedException {  
  48.     setup(context);  
  49.     while (context.nextKeyValue()) {  
  50.       map(context.getCurrentKey(), context.getCurrentValue(), context);  
  51.     }  
  52.     cleanup(context);  
  53.   }  
  54. }</span>  

       Mapper共有setup(),map(),cleanup()和run()四个方法。其中setup()一般是用来进行一些map()前的准备工作,map()则一般承担主要的处理工作,cleanup()则是收尾工作如关闭文件或者执行map()后的K-V分发等。run()方法提供了setup->map->cleanup()的执行模板。从上面run方法可以看出,K/V对是从传入的Context获取的。我们也可以从下面的map方法看出,输出结果K/V对也是通过Context来完成的。至于Context暂且放着。  

我们先来看看三个Mapper子类,它们位src\mapred\org\apache\Hadoop\mapreduce\lib\map:

 1、TokenCounterMapper

[java]  view plain  copy
  1. <span style="font-family:SimSun;font-size:14px;">public class TokenCounterMapper extends Mapper<Object, Text, Text, IntWritable>{    
  2.             
  3.       private final static IntWritable one = new IntWritable(1);    
  4.       private Text word = new Text();    
  5.           
  6.       @Override    
  7.       public void map(Object key, Text value, Context context    
  8.                       ) throws IOException, InterruptedException {    
  9.         StringTokenizer itr = new StringTokenizer(value.toString());    
  10.         while (itr.hasMoreTokens()) {    
  11.           word.set(itr.nextToken());    
  12.           context.write(word, one);    
  13.         }    
  14.       }    
  15.   } </span>  

       我们看到,对于一个输入的K-V对,它使用StringTokenizer来获取value中的tokens,然后对每一个token,分发出一个<token,one>对,这将在reduce端被收集,同一个token对应的K-V对都会被收集到同一个reducer上,这样我们就可以计算出所有mapper分发出来的以某个token为key的<token,one>的数量,然后只要在reduce函数中加起来,就得到了token的计数。这就是为什么这个类叫做TokenCounterMapper的原因。     

       在MapReduce的“Hello world”:WordCount例子中,我们完全可以直接使用这个TokenCounterMapper作为MapperClass,仅需用job.setMapperClass(TokenCounterMapper.class)进行设置即可。

2.InverseMapper

[java]  view plain  copy
  1. <span style="font-family:SimSun;font-size:14px;"public class InverseMapper<K, V> extends Mapper<K,V,V,K> {    
  2.         
  3.         
  4.     /** The inverse function.  Input keys and values are swapped.*/    
  5.     @Override    
  6.     public void map(K key, V value, Context context    
  7.                     ) throws IOException, InterruptedException {    
  8.       context.write(value, key);    
  9.   }  </span>  

 这个类更加简单,它紧紧是调换Key和Value,然后直接分发出去。举个例子:数据格式是<某商家,某商品>,我们既可能需要计算一个商家对应的所有商品种类,也可能需要计算某个商品的销售商家数量,后者的情形,就可以使用InverseMapper来达到目的,使得相同商品被分发到相同reducer。       

http://blog.csdn.NET/posa88/article/details/7901304

### Mapper 的概念及其实现 #### 什么是 MapperMapper 是一种用于数据映射的核心组件,在许多框架和技术栈中都扮演着重要角色。它的主要功能是将数据库中的表结构或其他形式的数据源与程序中的对象模型建立对应关系[^1]。 在 Java 领域,尤其是 MyBatis 这样的持久层框架中,Mapper 被用来定义 SQL 查询语句以及这些查询的结果如何被转换成 Java 对象。通过 XML 文件或者注解的方式,开发者可以指定具体的 SQL 操作逻辑及其返回值处理方式[^2]。 #### Mapper 的实现机制 MyBatis 中的 Mapper 实际上是由接口驱动的设计模式来支持的。当开发人员编写了一个带有方法声明的接口时,MyBatis 自动为其生成代理实例并绑定相应的 SQL 执行逻辑。这种设计使得业务代码更加简洁明了,同时也增强了可维护性和扩展性[^3]。 以下是基于 MyBatis 的一个简单 Mapper 接口示例: ```java public interface UserMapper { @Select("SELECT * FROM users WHERE id = #{id}") User findById(int id); @Insert("INSERT INTO users (name, age) VALUES (#{name}, #{age})") void insertUser(User user); } ``` 上述代码片段展示了两个常用的操作:`findById` 方法用于根据主键查找记录;而 `insertUser` 则负责向数据库插入新条目。值得注意的是,这里采用了注解的形式直接嵌入 SQL 语句,当然也可以选择外部化到单独的 XML 映射文件里去管理更为复杂的场景需求[^4]。 对于稍显复杂的情况,则推荐使用 XML 来描述 mapper 定义。下面给出一段典型的例子作为补充说明: ```xml <mapper namespace="com.example.mapper.UserMapper"> <select id="findAllUsers" resultType="com.example.model.User"> SELECT * FROM users; </select> </mapper> ``` 此部分配置指定了名为 `findAllUsers` 的查询操作,并将其结果集自动转化为列表型的 `User` 对象集合[^5]。 --- ### 相关术语解释 为了加深理解,有必要提及几个密切相关的概念: - **SQL Session**: 提供执行 CRUD 命令所需的基础环境和服务。 - **Result Map**: 描述从数据库字段至实体属性间的转化规则。 - **Parameter Type**: 表达传递给存储过程或函数调用参数的具体别信息。 以上各项共同构成了完整的 ORM 解决方案体系架构图景的一部分[^6]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值