MapReduce程序中在reduce端进行join

合并两个表的数据:

 

代码如下所示:

RJoin 类实现map函数和reduce函数,并进行数据的整合处理

package com.jym.hadoop.mr.rjoin;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;


public class RJoin {
  
    static class RJoinMapper extends Mapper<LongWritable, Text, Text, InfoBean>
    {
        InfoBean bean = new InfoBean();
        Text k = new Text();
        
        @Override
        protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException 
        {
            String line = value.toString();
            
            FileSplit inputSplit = (FileSplit) context.getInputSplit();
            String name = inputSplit.getPath().getName();
            
            String pid = "";
            //通过文件名判断是哪种数据,在进行数据切分操作
            if (name.startsWith("order")) 
            {
                String[] fields = line.split(",");
                pid = fields[2];
                //id   date   pid   amount
                bean.set(Integer.parseInt(fields[0]),fields[1], fields[2], Integer.parseInt(fields[3]), "", 0, 0, "0");
            }else 
            {
                String[] fields = line.split(",");
                pid = fields[0];
                bean.set(0,"",pid,0,fields[1],Integer.parseInt(fields[2]),Float.parseFloat(fields[3]),"1");
            }    
            
            k.set(pid);
            context.write(k, bean);
        }
    }
    
    static class RJoinReducer extends Reducer<Text, InfoBean, InfoBean, NullWritable>
    {
        InfoBean pdBean = new InfoBean();
        ArrayList<InfoBean> orderBeans = new ArrayList<>();
        
        @Override
        protected void reduce(Text pid, Iterable<InfoBean> beans,Context context) throws IOException, InterruptedException 
        {
            for(InfoBean bean : beans)
            {
                if ("1".equals(bean.getFlag())) 
                {
                    try 
                    {
                        BeanUtils.copyProperties(pdBean,bean);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }else 
                {
                    InfoBean odBean = new InfoBean();
                    try 
                    {
                        BeanUtils.copyProperties(odBean,bean);
                        orderBeans.add(odBean);
                    } catch (IllegalAccessException e) 
                    {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) 
                    {
                        e.printStackTrace();
                    }
                }
            }
            
            //拼接两类数据形成最终结果
            for(InfoBean bean:orderBeans)
            {
                bean.setPname(pdBean.getPname());
                bean.setCategory_id(pdBean.getCategory_id());
                bean.setPrice(pdBean.getPrice());
                
                context.write(bean, NullWritable.get());
            }
        }
    }
    
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException
    {
        Configuration conf=new Configuration();
        Job job = Job.getInstance(conf);
        
        //指定本程序的jar包所在的本地路径
        job.setJarByClass(RJoin.class);
        
        //指定本业务job要使用的mapper/reducer业务类
        job.setMapperClass(RJoinMapper.class);
        job.setReducerClass(RJoinReducer.class);
        
        //指定mapper输出数据的kv类型;
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(InfoBean.class);
        
        //指定最终输出的数据的kv类型
        job.setOutputKeyClass(InfoBean.class);
        job.setOutputValueClass(NullWritable.class);
        
        //指定job的输入原始文件所在目录
        //FileInputFormat.setInputPaths(job, new Path(args[0]));                                                //传一个路径参数
        FileInputFormat.setInputPaths(job, new Path("G:/wordcount/mapreduce/input"));          //传一个路径

        //指定job的输出结果所在目录
        //FileOutputFormat.setOutputPath(job, new Path(args[1]));         //传一个参数进来作为输出的路径参数
        FileOutputFormat.setOutputPath(job, new Path("G:/wordcount/mapreduce/output"));         //传一个参数进来作为输出的路径参数

        //将job中配置的相关参数,以及job所用的Java类所在的jar包,提交给yarn去运行;
        boolean res = job.waitForCompletion(true);
        System.exit(res?0:1);
    }
}
 

 

InfoBean类作为一种自定义的数据结构(需要继承接口Writable): 

package com.jym.hadoop.mr.rjoin;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.Writable;

public class InfoBean implements Writable
{
    private int order_id;              //订单id
    private String dateString;
    private String p_id;
    private int amount;
    private String pname;
    private int category_id;
    private float price;
    
    //flag=0表示这个对象是封装->订单表记录
    //flag=1表示这个对象是封装->产品信息记录
    private String flag;
    
    public InfoBean() { }
    
    public void set(int order_id,String dateString,String p_id,int amount,String pname,int category_id,float price,String flag)
    {
        this.order_id = order_id;
        this.dateString = dateString;
        this.p_id = p_id;
        this.amount = amount;
        this.pname=pname;
        this.category_id = category_id;
        this.price = price;
        this.flag=flag;
    }
    
    public void setFlag(String flag) 
    {
        this.flag = flag;
    }

    public String getFlag() 
    {
        return flag;
    }
    
    public void setPrice(float price) 
    {
        this.price = price;
    }
    
    public float getPrice() 
    {
        return price;
    }
    
    public void setAmount(int amount) 
    {
        this.amount = amount;
    }
    
    public int getAmount() {
        return amount;
    }
    
    public void setCategory_id(int category_id) {
        this.category_id = category_id;
    }
    
    public int getCategory_id() {
        return category_id;
    }
    
    public void setPname(String pname) {
        this.pname = pname;
    }
    
    public String getPname() {
        return pname;
    }
    
    public void setP_id(String p_id) {
        this.p_id = p_id;
    }
    
    public String getP_id() {
        return p_id;
    }
    
    public void setOrder_id(int order_id) {
        this.order_id = order_id;
    }
    public int getOrder_id() {
        return order_id;
    }
    public void setDateString(String dateString) {
        this.dateString = dateString;
    }
    public String getDateString() {
        return dateString;
    }
    

     /**实现接口Writable接口的两个序列化方法*/
    @Override
    public void readFields(DataInput in) throws IOException 
    {
        this.order_id = in.readInt();
        this.dateString = in.readUTF();
        this.p_id = in.readUTF();
        this.amount = in.readInt();
        this.pname = in.readUTF();
        this.category_id = in.readInt();
        this.price = in.readFloat();
        this.flag = in.readUTF();
    }
    @Override
    public void write(DataOutput out) throws IOException 
    {
        out.writeInt(order_id);
        out.writeUTF(dateString);
        out.writeUTF(p_id);
        out.writeInt(amount);
        out.writeUTF(pname);
        out.writeInt(category_id);
        out.writeFloat(price);
        out.writeUTF(flag);
    }
    
    @Override
    public String toString() 
    {
        return "order_id="+order_id+", dateString="+dateString+", p_id="+p_id+", amount="+amount+", pname="+pname+", category_id="+category_id+", price="+price+", flag="+flag;
    }
}
 

 

测试数据:

测试结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值