Flink之JDBCSink连接MySQL

输出到MySQL

  1. 添加依赖
xml 复制代码
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-connector-jdbc</artifactId>
  <version>3.1.0-1.17</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.32</version>
</dependency>
  1. 启动MySQL, 在test库下建表clicks
sql 复制代码
CREATE TABLE `clicks` (
  `user` VARCHAR(100) NOT NULL,
  `url` VARCHAR(100) DEFAULT NULL,
  `ts` BIGINT DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8
  1. 示例代码
java 复制代码
public class Flink04_JdbcSink {
    public static void main(String[] args) {
        //1.创建运行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //默认是最大并行度
        env.setParallelism(1);

        DataStreamSource<Event> ds = Flink06_EventSource.getEventSource(env);

        //
        SinkFunction<Event> sink = JdbcSink.sink(
                "insert into clicks(user, url, ts) values (?,?,?)"
                , new JdbcStatementBuilder<Event>() {
                    @Override
                    public void accept(PreparedStatement preparedStatement, Event event) throws SQLException {
                        //给SQL的占位符赋值
                        preparedStatement.setString(1, event.getUser());
                        preparedStatement.setString(2, event.getUrl());
                        preparedStatement.setLong(3, event.getTs());
                    }
                },
                JdbcExecutionOptions.builder()
                        .withBatchSize(5)
                        .withBatchIntervalMs(10000)
                        .withMaxRetries(3)
                        .build()
                ,
                new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
                        .withDriverName("com.mysql.cj.jdbc.Driver")
                        .withUsername("root")
                        .withPassword("000000")
                        .withUrl("jdbc:mysql://hadoop102:3306/flink")
                        .build()
        );

        ds.addSink(sink);

        try {
            env.execute();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

MySQL的幂等性处理

  1. 将插入关键字替换为replace,如果主键重复,将除了主键外的所有字段都替换。
  2. 使用on duplicate key update 字段名 = values(字段名)语法,如果主键重复,可以选择部分字段进行替换,其余字段保持不变。
  3. 示例代码
java 复制代码
public class Flink05_JdbcSinkReplace {
    public static void main(String[] args) {
        //1.创建运行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //默认是最大并行度
        env.setParallelism(1);

        DataStreamSource<Event> ds = Flink06_EventSource.getEventSource(env);

        SingleOutputStreamOperator<WordCount> countDs =
                ds.map(event -> new WordCount(event.getUrl(), 1))
                .keyBy(WordCount::getWord)
                .sum("count");

        //
        SinkFunction<WordCount> sink = JdbcSink.sink(
//                "replace into url_count(url, cnt) values (?,?)"
                "insert into url_count(url, cnt) values(?,?) on duplicate key update cnt = values(cnt)"
                ,
                new JdbcStatementBuilder<WordCount>() {
                    @Override
                    public void accept(PreparedStatement preparedStatement, WordCount wordCount) throws SQLException {
                        //注意:这里的起始下标是1
                        preparedStatement.setString(1, wordCount.getWord());
                        preparedStatement.setInt(2, wordCount.getCount());
                    }
                }
                ,
                JdbcExecutionOptions.builder()
                        .withBatchSize(5)
                        .withBatchIntervalMs(10000)
                        .withMaxRetries(3)
                        .build()
                ,
                new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
                        .withDriverName("com.mysql.cj.jdbc.Driver")
                        .withUsername("root")
                        .withPassword("000000")
                        .withUrl("jdbc:mysql://hadoop102:3306/flink")
                        .build()
        );

        countDs.addSink(sink);

        try {
            env.execute();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
相关推荐
阿星AI工作室6 小时前
刘润年中大课笔记:一句话说清AI落地之战的本质
大数据·人工智能·创业创新·商业
rising start6 小时前
二、全面理解MySQL架构
mysql·架构
bqq198610267 小时前
MySQL性能优化
mysql·mysql优化
雨辰AI8 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
长城20248 小时前
关于MySql的ONLY_FULL_GROUP_BY问题
数据库·mysql·聚合列
常常有9 小时前
MySQL 底层执行原理:输入SQL语句到两阶段提交
数据库·sql·mysql
189228048619 小时前
NY352固态MT29F32T08GWLBHD6-24QJ:B
大数据·服务器·人工智能·科技·缓存
不开大的凯207710 小时前
麦当秀AiPPT战略转向:从SaaS订阅迈向Token经济,AI办公定价模式迎来新探索
大数据·人工智能
海市公约10 小时前
MySQL更新语句执行全流程:从Buffer Pool修改到二阶段提交
数据库·mysql·binlog·innodb·undo log·二阶段提交·update执行原理
程序鉴定师10 小时前
西安小程序制作的可靠选择与发展前景
大数据·小程序