IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> jdk和mysql源码中的桥接模式 -> 正文阅读

[大数据]jdk和mysql源码中的桥接模式

当一件事情有多个维度的变化的可能性时,桥接模式就派上用场了。如下图,一个消息系统中,发送消息的方式 和消息的类型都是可以独立变化的,两个维度的变化互不影响,比如消息可以通过邮件发送,而消息类型可以使普通消息,加急消息, 还可以通过短信来发送普通消息或者加急消息,这样的系统就很适合桥接模式来实现。
在这里插入图片描述
每个独立变化的维度分别抽象出一个独立的接口,然后通过一个“桥”来持有这两个维度的顶层接口,来实现自己的业务逻辑:

消息发送接口:

package com.lchtest.pattern.birdge.message;

public interface IMessage {
    // 发送消息:消息内容和接收者
    void send(String msg, String reciever);
}

消息发送方式:

package com.lchtest.pattern.birdge.message;

/**
 * 消息发送方式1 邮件消息
 */
public class EmailMessage implements IMessage {
    @Override
    public void send(String msg, String reciever) {
        System.out.println(String.format("使用邮件发送消息 %s 给 %s ", msg, reciever));
    }
}

package com.lchtest.pattern.birdge.message;
/**
 * 消息发送方式2-系统消息
 */
public class SystemMessage implements IMessage {
    @Override
    public void send(String msg, String reciever) {
        System.out.println(String.format("使用内部消息系统发送消息 %s 给 %s ", msg, reciever));
    }
}

建立桥接:

package com.lchtest.pattern.birdge.message;

public abstract class AbstractMessage {
    private IMessage message;

    public AbstractMessage(IMessage message) {
        this.message = message;
    }

    void send(String msg, String reciever){
        this.message.send(msg, reciever);
    }
}

消息级别:

package com.lchtest.pattern.birdge.message;

/**
 * 消息紧急程度- 普通消息
 */
public class NormalMessage extends AbstractMessage {
    public NormalMessage(IMessage message) {
        super(message);
    }

    @Override
    void send(String msg, String reciever) {
        // 普通消息,直接调用父类方法发送消息
        super.send(msg, reciever);
    }
}
package com.lchtest.pattern.birdge.message;
/**
 * 消息紧急程度- 紧急消息
 */
public class UrgencyMessage extends AbstractMessage {

    public UrgencyMessage(IMessage message) {
        super(message);
    }

    @Override
    void send(String msg, String reciever) {
        // 加急消息特殊处理
        String urgencyMessage  = "【加急】" + msg;
        super.send(urgencyMessage, reciever);
    }
}

测试类:

package com.lchtest.pattern.birdge.message;
public class Test {
    public static void main(String[] args) {
        IMessage message = new EmailMessage();
        AbstractMessage abstractMessage = new NormalMessage(message);
        AbstractMessage urgencyMessage = new UrgencyMessage(message);
        abstractMessage.send("便携式测温仪采购申请","采购经理");
        urgencyMessage.send("紧急事务处理款项申请","老板");

        message = new SystemMessage();
        abstractMessage = new UrgencyMessage(message);
        abstractMessage.send("便携式测温仪采购申请","公司老板");
    }
}

以JDBC API的抽象维度和实现维度 为例,来说明源码中的桥接是怎么使用的
在这里插入图片描述

package com.lchtest.pattern.birdge;

import lombok.Data;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JDBCBridge {

    public static void main(String[] args) {
        try {
            // Driver类没有实现,只是一个抽象
            Class.forName("com.mysql.jdbc.Driver");
            // DriverManager就是这个桥,把目标数据库的driver进行了实现
            Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "lchadmin");
            String sql = "select * from user where id= ?";
            PreparedStatement pstmt = connection.prepareStatement(sql); // 预编译sql
            pstmt.setInt(1, 1);  // 参数下标1,参数值1
            pstmt.execute(); // 执行查询
            ResultSet rs = pstmt.getResultSet(); // 获取结果集
            while (rs.next()){
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setAge(rs.getInt("age"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                System.out.println(user.toString()); //User(id=1, username=lisi, password=12345, age=19)
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

@Data
class User {
    private  int id;
    private String username;
    private  String password;
    private int age;

}
/*CREATE TABLE `user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) NOT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4*/

Class.forName代码的作用

Class.forName(“com.mysql.jdbc.Driver”) 加载Driver类的时候就会执行如下的静态代码块
在这里插入图片描述
最终调用了下面的方法:
在这里插入图片描述

 // List of registered JDBC drivers
    private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();

代码的核心就是把Driver的实例放到了registeredDrivers 这个list里面去了,而不管是哪种数据库的Driver实例,都给封装成了DriverInfo对象,

DriverManager.getConnection的底层逻辑

getConnection核心逻辑如下,遍历那个registeredDrivers ,调用driver自己的connect方法,而这个driver就是之前的com.mysql.jdbc.Driver 的实例,
在这里插入图片描述
调用的connect是 driver的父类NonRegisteringDriver中的connect方法,返回的Connection对象也是实现了java.sql.Connection接口的实例。
在这里插入图片描述

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:18:09  更:2022-04-04 12:20:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:48:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码