继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

hadoop读写mysql数据库

料青山看我应如是
关注TA
已关注
手记 332
粉丝 97
获赞 353

需求描述

我们有两张表“成绩表”和“总分表”,从成绩表中计算出每个学生的总成绩,记录到总分表中。

表结构


//成绩表记录学生id,课程id,这科分数
CREATE TABLE `score` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sid` int(11) DEFAULT NULL,
  `cid` int(11) DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
//总分表记录学生id和学生总成绩
CREATE TABLE `topscore` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sid` int(11) DEFAULT NULL,
  `totalscore` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

成绩如下:


自定义类实现序列化和DBWritable接口

实现序列化方法和数据库读写方法,这里我们读写是两张表。

import com.alibaba.fastjson.JSONObject;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.lib.db.DBWritable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MysqlDb_scoreWritable implements Writable,DBWritable {

    private int id;
    private int sid;
    private int cid;
    private int score;
    private int totalscore;

    /**
     *数据序列化
     */
    public void write(DataOutput out) throws IOException {
        out.writeInt(id);
        out.writeInt(sid);
        out.writeInt(cid);
        out.writeInt(score);
        out.writeInt(totalscore);
    }

    public void readFields(DataInput in) throws IOException {
        this.id = in.readInt();
        this.sid = in.readInt();
        this.cid = in.readInt();
        this.score = in.readInt();
        this.totalscore = in.readInt();
    }

    /**
     * 数据库读写
     * 向topscore中写入值
     */
    public void write(PreparedStatement statement) throws SQLException {
        statement.setInt(1,sid);
        statement.setInt(2,totalscore);
    }
    //从score中读取成绩
    public void readFields(ResultSet resultSet) throws SQLException {
        id = resultSet.getInt(1);
        sid = resultSet.getInt(2);
        cid = resultSet.getInt(3);
        score = resultSet.getInt(4);
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public int getCid() {
        return cid;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getTotalscore() {
        return totalscore;
    }
    public void setTotalscore(int totalscore) {
        this.totalscore = totalscore;
    }
    @Override
    public String toString() {
        JSONObject json = new JSONObject();
        json.put("id",id);
        json.put("sid",sid);
        json.put("cid",cid);
        json.put("score",score);
        return json.toString();
    }
}

mapper类

map方法读取mysql表中一行行的数据,map的输入key,value分别是longWritable,上面我们自定义的mysql读写实体类。输入key是学生的id,value是自定义实体类。reduce的时候我们取出学生的各科成绩相加求总成绩。

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class MysqlDbMapper extends Mapper<LongWritable,MysqlDb_scoreWritable,IntWritable,MysqlDb_scoreWritable> {

    protected void map(LongWritable key, MysqlDb_scoreWritable value, Context context) throws IOException, InterruptedException {
        System.out.println(value.toString());
        int sid = value.getSid();
        context.write(new IntWritable(sid),value);
    }
}

reducer类

reduce的时候我们取出学生的各科成绩相加求总成绩。输出key是我们自定义实体类向mysql表中写数据,value为空。

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class MysqlDbReducer extends Reducer<IntWritable,MysqlDb_scoreWritable,MysqlDb_scoreWritable,NullWritable> {

    protected void reduce(IntWritable key, Iterable<MysqlDb_scoreWritable> values, Context context) 
                throws IOException, InterruptedException {
        int totalScore = 0;
        for(MysqlDb_scoreWritable m : values){
            totalScore += m.getScore();
        }
        MysqlDb_scoreWritable score = new MysqlDb_scoreWritable();
        score.setSid(key.get());
        score.setTotalscore(totalScore);
        context.write(score,NullWritable.get());
    }
}

运行app类

  1. import org.apache.hadoop.conf.Configuration;  

  2. import org.apache.hadoop.io.IntWritable;  

  3. import org.apache.hadoop.io.NullWritable;  

  4. import org.apache.hadoop.mapreduce.Job;  

  5. import org.apache.hadoop.mapreduce.lib.db.DBConfiguration;  

  6. import org.apache.hadoop.mapreduce.lib.db.DBInputFormat;  

  7. import org.apache.hadoop.mapreduce.lib.db.DBOutputFormat;  

  8.   

  9. public class DbApp {  

  10.   

  11.     public static void main(String[] args) throws Exception{  

  12.         Configuration conf = new Configuration();  

  13.         Job job = Job.getInstance(conf);  

  14.   

  15.         job.setJarByClass(DbApp.class);  

  16.         job.setJobName("mysql read write");  

  17.         job.setMapperClass(MysqlDbMapper.class);  

  18.         job.setReducerClass(MysqlDbReducer.class);  

  19.         job.setMapOutputKeyClass(IntWritable.class);  

  20.         job.setMapOutputValueClass(MysqlDb_scoreWritable.class);  

  21.         job.setOutputKeyClass(MysqlDb_scoreWritable.class);  

  22.         job.setOutputValueClass(NullWritable.class);  

  23.   

  24.   

  25.         //配置数据库信息  

  26.         String driverclass = "com.mysql.jdbc.Driver";  

  27.         String url = "jdbc:mysql://192.168.1.215:3306/school";  

  28.         String username = "root";  

  29.         String passwd = "root";  

  30.   

  31.         DBConfiguration.configureDB(job.getConfiguration(),driverclass,url,username,passwd);  

  32.         //设置输入内容  

  33.         DBInputFormat.setInput(job,MysqlDb_scoreWritable.class,"select * from score","select count(id) from score");  

  34.   

  35.         //设置输出内容,第一个string是表名,后面可以跟多个string是表字段名  

  36.         DBOutputFormat.setOutput(job,"topscore","sid","totalscore");  

  37.         job.waitForCompletion(true);  

  38.   

  39.     }  

  40. }  

原文出处

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP