`
Donald_Draper
  • 浏览: 980230 次
社区版块
存档分类
最新评论

WrapperConnectionPoolDataSource初始化

    博客分类:
  • C3P0
阅读更多
C3P0 ComboPooledDataSource初始化:http://donald-draper.iteye.com/blog/2343522
C3P0 DriverManagerDataSource初始化:http://donald-draper.iteye.com/blog/2343564
WrapperConnectionPoolDataSource初始化:http://donald-draper.iteye.com/blog/2345008
C3P0属性设置和数据库连接池的获取:http://donald-draper.iteye.com/blog/2345084
在前篇几篇我们讲过ComboPooledDataSource和初始化DriverManagerDataSource,今天来看一下数据库连接池WrapperConnectionPoolDataSource;在初始化AbstractComboPooledDataSource的构造函数中,有这么几句,上一篇讲了DriverManagerDataSource,这一篇我们来看一下WrapperConnectionPoolDataSource
//AbstractComboPooledDataSource
public AbstractComboPooledDataSource(boolean autoregister)
    {
        //
        super(autoregister);
	//新建驱动数据源管理器
        dmds = new DriverManagerDataSource();
	//新建数据库连接池
        wcpds = new WrapperConnectionPoolDataSource();
	//设置数据连接池的数据源驱动管理器
        wcpds.setNestedDataSource(dmds);
        try
        {
            setConnectionPoolDataSource(wcpds);
        }
        catch(PropertyVetoException e)
        {
            logger.log(MLevel.WARNING, "Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet!", e);
            throw new RuntimeException((new StringBuilder()).append("Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet! ").append(e).toString());
        }
        setUpPropertyEvents();
    }

//新建数据库连接池
wcpds = new WrapperConnectionPoolDataSource();

//WrapperConnectionPoolDataSource
public final class WrapperConnectionPoolDataSource extends WrapperConnectionPoolDataSourceBase
    implements ConnectionPoolDataSource
{
    ConnectionTester connectionTester;
    Map userOverrides;
    public WrapperConnectionPoolDataSource()
    {
        this(true);
    }
    public WrapperConnectionPoolDataSource(boolean autoregister)
    {
        //初始化WrapperConnectionPoolDataSourceBase
        super(autoregister);
	//获取数据库连接测试类,com.mchange.v2.c3p0.impl.DefaultConnectionTester
        connectionTester = C3P0Registry.getDefaultConnectionTester();
        setUpPropertyListeners();
        try
        {
            userOverrides = C3P0ImplUtils.parseUserOverridesAsString(getUserOverridesAsString());
        }
    }
    //设置属性值改变监听器
      private void setUpPropertyListeners()
    {
        VetoableChangeListener setConnectionTesterListener = new VetoableChangeListener() {
            public void vetoableChange(PropertyChangeEvent evt)
                throws PropertyVetoException
            {
                String propName = evt.getPropertyName();
                Object val = evt.getNewValue();
                if("connectionTesterClassName".equals(propName))
                    try
                    {
		        //重新创建连接测试类
                        recreateConnectionTester((String)val);
                    }
                else
                if("userOverridesAsString".equals(propName))
                    try
                    {
                        userOverrides = C3P0ImplUtils.parseUserOverridesAsString((String)val);
                    }
                  
            }
            final WrapperConnectionPoolDataSource this$0;            
            {
                this.this$0 = WrapperConnectionPoolDataSource.this;
                super();
            }
        };
        addVetoableChangeListener(setConnectionTesterListener);
    }

下面来看
//WrapperConnectionPoolDataSourceBase
public abstract class WrapperConnectionPoolDataSourceBase extends IdentityTokenResolvable
    implements Referenceable, Serializable
{  

    protected PropertyChangeSupport pcs;//属性值改变辅助工具
    protected VetoableChangeSupport vcs;//bean属性改变辅助工具
    private int acquireIncrement;//
    private int acquireRetryAttempts;//获取连接尝试次数
    private int acquireRetryDelay;
    private boolean autoCommitOnClose;//是否自动提交
    private String automaticTestTable;
    private boolean breakAfterAcquireFailure;//在获取连接失败时,是否断开
    private int checkoutTimeout;
    private String connectionCustomizerClassName;
    private String connectionTesterClassName;
    private String contextClassLoaderSource;
    private boolean debugUnreturnedConnectionStackTraces;
    private String factoryClassLocation;
    private boolean forceIgnoreUnresolvedTransactions;
    private boolean forceSynchronousCheckins;
    private volatile String identityToken;//class唯一token
    private int idleConnectionTestPeriod;
    private int initialPoolSize;//初始化连接池大小
    private int maxAdministrativeTaskTime;
    private int maxConnectionAge;
    private int maxIdleTime;//最大空闲时间
    private int maxIdleTimeExcessConnections;
    private int maxPoolSize;//连接池最大连接数
    private int maxStatements;
    private int maxStatementsPerConnection;
    private int minPoolSize;//连接池最小连接数
    private DataSource nestedDataSource;//数据源
    private String overrideDefaultPassword;
    private String overrideDefaultUser;
    private String preferredTestQuery;
    private boolean privilegeSpawnedThreads;
    private int propertyCycle;
    private int statementCacheNumDeferredCloseThreads;
    private boolean testConnectionOnCheckin;
    private boolean testConnectionOnCheckout;
    private int unreturnedConnectionTimeout;
    private String userOverridesAsString;
    private boolean usesTraditionalReflectiveProxies;
    private static final long serialVersionUID = 1L;
    private static final short VERSION = 1;
    static final JavaBeanReferenceMaker referenceMaker;

    static 
    {
        referenceMaker = new JavaBeanReferenceMaker();
        referenceMaker.setFactoryClassName("com.mchange.v2.c3p0.impl.C3P0JavaBeanObjectFactory");
        referenceMaker.addReferenceProperty("acquireIncrement");
        referenceMaker.addReferenceProperty("acquireRetryAttempts");
        referenceMaker.addReferenceProperty("acquireRetryDelay");
        referenceMaker.addReferenceProperty("autoCommitOnClose");
        referenceMaker.addReferenceProperty("automaticTestTable");
        referenceMaker.addReferenceProperty("breakAfterAcquireFailure");
        referenceMaker.addReferenceProperty("checkoutTimeout");
        referenceMaker.addReferenceProperty("connectionCustomizerClassName");
        referenceMaker.addReferenceProperty("connectionTesterClassName");
        referenceMaker.addReferenceProperty("contextClassLoaderSource");
        referenceMaker.addReferenceProperty("debugUnreturnedConnectionStackTraces");
        referenceMaker.addReferenceProperty("factoryClassLocation");
        referenceMaker.addReferenceProperty("forceIgnoreUnresolvedTransactions");
        referenceMaker.addReferenceProperty("forceSynchronousCheckins");
        referenceMaker.addReferenceProperty("identityToken");
        referenceMaker.addReferenceProperty("idleConnectionTestPeriod");
        referenceMaker.addReferenceProperty("initialPoolSize");
        referenceMaker.addReferenceProperty("maxAdministrativeTaskTime");
        referenceMaker.addReferenceProperty("maxConnectionAge");
        referenceMaker.addReferenceProperty("maxIdleTime");
        referenceMaker.addReferenceProperty("maxIdleTimeExcessConnections");
        referenceMaker.addReferenceProperty("maxPoolSize");
        referenceMaker.addReferenceProperty("maxStatements");
        referenceMaker.addReferenceProperty("maxStatementsPerConnection");
        referenceMaker.addReferenceProperty("minPoolSize");
        referenceMaker.addReferenceProperty("nestedDataSource");
        referenceMaker.addReferenceProperty("overrideDefaultPassword");
        referenceMaker.addReferenceProperty("overrideDefaultUser");
        referenceMaker.addReferenceProperty("preferredTestQuery");
        referenceMaker.addReferenceProperty("privilegeSpawnedThreads");
        referenceMaker.addReferenceProperty("propertyCycle");
        referenceMaker.addReferenceProperty("statementCacheNumDeferredCloseThreads");
        referenceMaker.addReferenceProperty("testConnectionOnCheckin");
        referenceMaker.addReferenceProperty("testConnectionOnCheckout");
        referenceMaker.addReferenceProperty("unreturnedConnectionTimeout");
        referenceMaker.addReferenceProperty("userOverridesAsString");
        referenceMaker.addReferenceProperty("usesTraditionalReflectiveProxies");
    }
    
    protected abstract PooledConnection getPooledConnection(ConnectionCustomizer connectioncustomizer, String s)
        throws SQLException;
    //获取数据库连接池,待AbstractComboPooledDataSource父类扩展
    protected abstract PooledConnection getPooledConnection(String s, String s1, ConnectionCustomizer connectioncustomizer, String s2)
        throws SQLException;
    //初始化数据库连接池,连接数,statment数,失败尝试连接数等属性
     public WrapperConnectionPoolDataSourceBase(boolean autoregister)
    {
        pcs = new PropertyChangeSupport(this);
        vcs = new VetoableChangeSupport(this);
        acquireIncrement = C3P0Config.initializeIntPropertyVar("acquireIncrement", C3P0Defaults.acquireIncrement());
        acquireRetryAttempts = C3P0Config.initializeIntPropertyVar("acquireRetryAttempts", C3P0Defaults.acquireRetryAttempts());
        acquireRetryDelay = C3P0Config.initializeIntPropertyVar("acquireRetryDelay", C3P0Defaults.acquireRetryDelay());
        autoCommitOnClose = C3P0Config.initializeBooleanPropertyVar("autoCommitOnClose", C3P0Defaults.autoCommitOnClose());
        automaticTestTable = C3P0Config.initializeStringPropertyVar("automaticTestTable", C3P0Defaults.automaticTestTable());
        breakAfterAcquireFailure = C3P0Config.initializeBooleanPropertyVar("breakAfterAcquireFailure", C3P0Defaults.breakAfterAcquireFailure());
        checkoutTimeout = C3P0Config.initializeIntPropertyVar("checkoutTimeout", C3P0Defaults.checkoutTimeout());
        connectionCustomizerClassName = C3P0Config.initializeStringPropertyVar("connectionCustomizerClassName", C3P0Defaults.connectionCustomizerClassName());
        connectionTesterClassName = C3P0Config.initializeStringPropertyVar("connectionTesterClassName", C3P0Defaults.connectionTesterClassName());
        contextClassLoaderSource = C3P0Config.initializeStringPropertyVar("contextClassLoaderSource", C3P0Defaults.contextClassLoaderSource());
        debugUnreturnedConnectionStackTraces = C3P0Config.initializeBooleanPropertyVar("debugUnreturnedConnectionStackTraces", C3P0Defaults.debugUnreturnedConnectionStackTraces());
        factoryClassLocation = C3P0Config.initializeStringPropertyVar("factoryClassLocation", C3P0Defaults.factoryClassLocation());
        forceIgnoreUnresolvedTransactions = C3P0Config.initializeBooleanPropertyVar("forceIgnoreUnresolvedTransactions", C3P0Defaults.forceIgnoreUnresolvedTransactions());
        forceSynchronousCheckins = C3P0Config.initializeBooleanPropertyVar("forceSynchronousCheckins", C3P0Defaults.forceSynchronousCheckins());
        idleConnectionTestPeriod = C3P0Config.initializeIntPropertyVar("idleConnectionTestPeriod", C3P0Defaults.idleConnectionTestPeriod());
        initialPoolSize = C3P0Config.initializeIntPropertyVar("initialPoolSize", C3P0Defaults.initialPoolSize());
        maxAdministrativeTaskTime = C3P0Config.initializeIntPropertyVar("maxAdministrativeTaskTime", C3P0Defaults.maxAdministrativeTaskTime());
        maxConnectionAge = C3P0Config.initializeIntPropertyVar("maxConnectionAge", C3P0Defaults.maxConnectionAge());
        //初始化最大空闲时间
	maxIdleTime = C3P0Config.initializeIntPropertyVar("maxIdleTime", C3P0Defaults.maxIdleTime());
        maxIdleTimeExcessConnections = C3P0Config.initializeIntPropertyVar("maxIdleTimeExcessConnections", C3P0Defaults.maxIdleTimeExcessConnections());
        //初始化最大连接池数
	maxPoolSize = C3P0Config.initializeIntPropertyVar("maxPoolSize", C3P0Defaults.maxPoolSize());
        //最大statements
	maxStatements = C3P0Config.initializeIntPropertyVar("maxStatements", C3P0Defaults.maxStatements());
        maxStatementsPerConnection = C3P0Config.initializeIntPropertyVar("maxStatementsPerConnection", C3P0Defaults.maxStatementsPerConnection());
        minPoolSize = C3P0Config.initializeIntPropertyVar("minPoolSize", C3P0Defaults.minPoolSize());
        overrideDefaultPassword = C3P0Config.initializeStringPropertyVar("overrideDefaultPassword", C3P0Defaults.overrideDefaultPassword());
        overrideDefaultUser = C3P0Config.initializeStringPropertyVar("overrideDefaultUser", C3P0Defaults.overrideDefaultUser());
        preferredTestQuery = C3P0Config.initializeStringPropertyVar("preferredTestQuery", C3P0Defaults.preferredTestQuery());
        privilegeSpawnedThreads = C3P0Config.initializeBooleanPropertyVar("privilegeSpawnedThreads", C3P0Defaults.privilegeSpawnedThreads());
        propertyCycle = C3P0Config.initializeIntPropertyVar("propertyCycle", C3P0Defaults.propertyCycle());
        statementCacheNumDeferredCloseThreads = C3P0Config.initializeIntPropertyVar("statementCacheNumDeferredCloseThreads", C3P0Defaults.statementCacheNumDeferredCloseThreads());
        testConnectionOnCheckin = C3P0Config.initializeBooleanPropertyVar("testConnectionOnCheckin", C3P0Defaults.testConnectionOnCheckin());
        testConnectionOnCheckout = C3P0Config.initializeBooleanPropertyVar("testConnectionOnCheckout", C3P0Defaults.testConnectionOnCheckout());
        unreturnedConnectionTimeout = C3P0Config.initializeIntPropertyVar("unreturnedConnectionTimeout", C3P0Defaults.unreturnedConnectionTimeout());
        userOverridesAsString = C3P0Config.initializeUserOverridesAsString();
        usesTraditionalReflectiveProxies = C3P0Config.initializeBooleanPropertyVar("usesTraditionalReflectiveProxies", C3P0Defaults.usesTraditionalReflectiveProxies());
        if(autoregister)
        {
	    //获取唯一token
            identityToken = C3P0ImplUtils.allocateIdentityToken(this);
	    //注册到C3P0Registry的token Map中。
            C3P0Registry.reregister(this);
        }
    }
    //添加bean属性改变监听器
    public void addVetoableChangeListener(VetoableChangeListener vcl)
    {
        vcs.addVetoableChangeListener(vcl);
    }
        public synchronized DataSource getNestedDataSource()
    {
        return nestedDataSource;
    }
    //设置数据源,这个在AbstractComboPooledDataSource构造函数中
    //新建驱动数据源管理器
    //dmds = new DriverManagerDataSource();
    //新建数据库连接池
    //wcpds = new WrapperConnectionPoolDataSource();
    //设置数据连接池的数据源驱动管理器
    //wcpds.setNestedDataSource(dmds);
    public synchronized void setNestedDataSource(DataSource nestedDataSource)
    {
        DataSource oldVal = this.nestedDataSource;
        this.nestedDataSource = nestedDataSource;
        if(!eqOrBothNull(oldVal, nestedDataSource))
            pcs.firePropertyChange("nestedDataSource", oldVal, nestedDataSource);
    }
}

从上面可以看出AbstractComboPooledDataSource初始化,主要是初始化数据库连接池相关的属性,如最大,最小数据库连接数,空闲时间,连接失败尝试次数,事务是否自动提交,
statement相关属性。

//VetoableChangeListener
package java.beans;

/**
 * A VetoableChange event gets fired whenever a bean changes a "constrained"
 * property.  You can register a VetoableChangeListener with a source bean
 * so as to be notified of any constrained property updates.
 */
public interface VetoableChangeListener extends java.util.EventListener {
    /**
     * This method gets called when a constrained property is changed.
     *
     * @param     evt a <code>PropertyChangeEvent</code> object describing the
     *                event source and the property that has changed.
     * @exception PropertyVetoException if the recipient wishes the property
     *              change to be rolled back.
     */
    void vetoableChange(PropertyChangeEvent evt)
                                throws PropertyVetoException;
}


//VetoableChangeSupport
/**
 * This is a utility class that can be used by beans that support constrained
 * properties.  It manages a list of listeners and dispatches
 * {@link PropertyChangeEvent}s to them.  You can use an instance of this class
 * as a member field of your bean and delegate these types of work to it.
 * The {@link VetoableChangeListener} can be registered for all properties
 * or for a property specified by name.
 * <p>
 * Here is an example of {@code VetoableChangeSupport} usage that follows
 * the rules and recommendations laid out in the JavaBeans&trade; specification:
 * <pre>
 * public class MyBean {
 *     private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
 *
 *     public void addVetoableChangeListener(VetoableChangeListener listener) {
 *         this.vcs.addVetoableChangeListener(listener);
 *     }
 *
 *     public void removeVetoableChangeListener(VetoableChangeListener listener) {
 *         this.vcs.removeVetoableChangeListener(listener);
 *     }
 *
 *     private String value;
 *
 *     public String getValue() {
 *         return this.value;
 *     }
 *
 *     public void setValue(String newValue) throws PropertyVetoException {
 *         String oldValue = this.value;
 *         this.vcs.fireVetoableChange("value", oldValue, newValue);
 *         this.value = newValue;
 *     }
 *
 *     [...]
 * }
 * </pre>
 * <p>
 * A {@code VetoableChangeSupport} instance is thread-safe.
 * <p>
 * This class is serializable.  When it is serialized it will save
 * (and restore) any listeners that are themselves serializable.  Any
 * non-serializable listeners will be skipped during serialization.
 *
 * @see PropertyChangeSupport
 */
public class VetoableChangeSupport implements Serializable {
    private VetoableChangeListenerMap map = new VetoableChangeListenerMap();

    /**
     * Constructs a <code>VetoableChangeSupport</code> object.
     *
     * @param sourceBean  The bean to be given as the source for any events.
     */
    public VetoableChangeSupport(Object sourceBean) {
        if (sourceBean == null) {
            throw new NullPointerException();
        }
        source = sourceBean;
    }

    /**
     * Add a VetoableChangeListener to the listener list.
     * The listener is registered for all properties.
     * The same listener object may be added more than once, and will be called
     * as many times as it is added.
     * If <code>listener</code> is null, no exception is thrown and no action
     * is taken.
     *
     * @param listener  The VetoableChangeListener to be added
     */
    public void addVetoableChangeListener(VetoableChangeListener listener) {
        if (listener == null) {
            return;
        }
        if (listener instanceof VetoableChangeListenerProxy) {
            VetoableChangeListenerProxy proxy =
                    (VetoableChangeListenerProxy)listener;
            // Call two argument add method.
            addVetoableChangeListener(proxy.getPropertyName(),
                                      proxy.getListener());
        } else {
            this.map.add(null, listener);
        }
    }
}
1
0
分享到:
评论

相关推荐

    SIN初始化_混沌初始化_matlab_混沌映射_种群初始化_sin映射初始化粒子群_

    标题中的“SIN初始化_混沌初始化”指的是使用正弦混沌映射对粒子群进行初始位置的设置。混沌系统具有高度的敏感性,使得初始条件的微小差异可能导致显著不同的结果,这为种群的多样性和探索性提供了可能。SIN映射是...

    tft初始化程序.rar_4.5"TFT初始化_9481_ILI9338、_TFT初始化指令_tft初始化

    本篇将详细讲解与"4.5"TFT初始化相关的知识,特别是针对9481、ILI9338型号的TFT屏幕,以及TFT初始化指令。 首先,"4.5"指的是屏幕的对角线尺寸,这通常用于描述手机或平板电脑等设备的显示屏大小。4.5英寸的TFT屏幕...

    C++全局变量初始化的一点总结

    静态初始化发生在程序加载时,主要针对那些可以用常量表达的初始化,例如零初始化(zero initialization)和常量初始化(const initialization)。零初始化的变量通常存放在BSS段,而常量初始化的变量则位于数据段,...

    C#中结构(struct)的部分初始化和完全初始化实例分析

    本文将深入探讨结构的两种初始化方式:部分初始化和完全初始化,并通过实例分析其特点和注意事项。 首先,我们来看部分初始化。部分初始化是指在创建结构实例时只给一部分字段赋值,而其余字段保持默认状态。以下是...

    PCI设备BAR空间的初始化

    ### PCI设备BAR空间的初始化详解 #### 一、引言 在现代计算机系统中,PCI(Peripheral Component Interconnect,外围部件互连)总线是一种重要的高速扩展总线标准,广泛应用于连接各种硬件设备,如显卡、声卡、...

    C++构造函数初始化列表

    ### C++构造函数初始化列表详解 在C++编程语言中,构造函数是对象生命周期开始时自动调用的特殊成员函数,用于初始化对象的状态。构造函数初始化列表是C++中一个非常重要的特性,它允许程序员在对象创建时直接对类...

    LS-DYNA3D中的应力初始化_lsdyna_应力初始化_

    标题中的“应力初始化”是指在进行LS-DYNA3D模拟时,如何设定初始条件中的应力状态。在进行复杂的工程问题模拟时,正确设置初始应力对于获取准确的计算结果至关重要。 应力初始化通常涉及到以下几个关键知识点: 1...

    FANUC机器人初始化系统的基本方法和步骤.docx

    ### FANUC机器人初始化系统的基本方法和步骤 #### 一、引言 FANUC机器人的广泛应用使得其系统的维护与管理变得尤为重要。其中,初始化作为系统恢复的重要手段之一,不仅能够帮助用户解决软件故障问题,还能确保...

    柯尼卡美能达7828载体初始化方法

    ### 柯尼卡美能达7828载体初始化方法详解 #### 一、概述 在使用柯尼卡美能达7828打印机的过程中,可能会遇到需要对载体进行初始化的情况。载体初始化是为了确保打印机能够正常工作并维持打印质量的重要步骤之一。...

    SpringBoot项目启动时实现调用一次初始化方法.docx

    在Spring Boot应用中,我们经常需要在项目启动时执行一次初始化操作,比如加载配置、预设数据等。这里我们将详细探讨如何实现这个需求,主要涉及`@PostConstruct`注解、`CommandLineRunner`接口以及在启动类中直接...

    MFC中通用控件的初始化

    在MFC(Microsoft Foundation Classes)框架中,通用控件的初始化是使用Windows API中的特定函数来实现的。这些通用控件提供了丰富的用户界面元素,包括工具栏、状态栏、树视图、列表视图、动画、热键、图像列表、...

    CSS样式初始化commonInitialize.css

    CSS样式初始化是开发过程中一个重要的步骤,它旨在消除浏览器之间的默认样式差异,确保网页在不同浏览器上的一致性表现。"commonInitialize.css"就是这样一个专门用于全局CSS样式初始化的文件。 首先,我们来理解...

    解决数码视讯Q5使用USB_Burning_Tool刷机时 提示 初始化DDR/读取初始化结果/USB错误

    解决数码视讯Q5使用USB_Burning_Tool刷机时 提示 初始化DDR/读取初始化结果/USB错误

    组态王设备初始化失败安装可用

    在工业控制系统中,"设备初始化失败"是一个常见的问题,这可能由多种原因引起,例如驱动程序不兼容、系统设置错误、硬件故障或是缺少必要的组件。在本案例中,提到的“组态王设备初始化失败安装可用”指的是,当遇到...

    PMON 设备初始化代码分析,非常详细的资料说明

    PMON 设备初始化代码分析 PMON 设备初始化代码是 PMON 设备的核心组件之一,它负责初始化 PMON 设备的各个组件,包括 PCI 设备、内存、时钟频率、异常处理等。下面我们将对 PMON 设备初始化代码进行详细的分析。 1...

    第二篇金蝶k3供应链系统初始化.pptx

    金蝶K3供应链系统初始化 在金蝶K3供应链系统中,初始化是非常重要的一步,它决定了整个系统的基础参数和基础资料的设置。在本课程中,我们将学习如何对新帐套进行初始化设置,掌握供应链系统初始化流程及操作、...

    typedef struct 与 struct 的区别及初始化

    初始化结构体时,通常有两种方式:构造函数初始化(如果结构体是类)和成员初始化列表。由于 `struct` 在C++中等同于类,但不支持构造函数,所以我们必须使用成员初始化列表。例如,对于 `PhotoInfo` 结构体,其初始...

    液晶显示器单片机初始化程序

    液晶显示器单片机初始化程序是实现微控制器与液晶显示器(LCD)之间通信的关键步骤,确保LCD能够正确地显示数据。本文将深入解析标题、描述、标签以及部分内容中提及的知识点,帮助读者理解单片机控制的液晶显示器...

    解决C++全局变量只能初始化不能赋值的问题

    C++中,全局变量只能声明、初始化,而不能赋值 也就是说,下面这样是不被允许的: #include using namespace std; int a; a = 2; int main() { return 0; } 错误提示是: C++ requires a type specifier for all...

    DDR 初始化 流程

    ### DDR初始化流程详解 DDR(Double Data Rate)内存技术在现代计算系统中扮演着至关重要的角色,其高速数据传输能力和高带宽特性使得DDR成为服务器、个人计算机以及各种电子设备中的首选内存类型。DDR初始化流程是...

Global site tag (gtag.js) - Google Analytics