欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文弄懂Mybatis中介者模式

 更新時(shí)間:2023年06月11日 11:33:25   作者:Cosolar  
本文主要介紹了一文弄懂Mybatis中介者模式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、前言

中介者模式的核心思想是將對(duì)象間的交互行為集中在一個(gè)中介者對(duì)象中,從而降低對(duì)象之間的耦合度。在mybatis中,中介者模式被廣泛應(yīng)用于Session對(duì)象的創(chuàng)建和管理中。

具體來(lái)說(shuō),mybatis中的SqlSessionFactory就扮演了中介者的角色,它負(fù)責(zé)創(chuàng)建和管理SqlSession對(duì)象。SqlSession是mybatis中用于與數(shù)據(jù)庫(kù)交互的核心對(duì)象,而SqlSessionFactory則是創(chuàng)建SqlSession對(duì)象的工廠類。

當(dāng)應(yīng)用程序需要執(zhí)行一個(gè)操作(如查詢、添加或更新記錄)時(shí),它將向SqlSessionFactory請(qǐng)求一個(gè)SqlSession對(duì)象。SqlSessionFactory根據(jù)需要的配置信息(如數(shù)據(jù)庫(kù)連接信息、事務(wù)管理器等)創(chuàng)建一個(gè)新的SqlSession對(duì)象,并將其返回給應(yīng)用程序。

一旦應(yīng)用程序獲得了SqlSession對(duì)象,它就可以使用SqlSession對(duì)象來(lái)執(zhí)行數(shù)據(jù)庫(kù)操作。當(dāng)執(zhí)行完操作后,應(yīng)用程序需要調(diào)用SqlSession的close()方法關(guān)閉資源,SqlSession將會(huì)被歸還給SqlSessionFactory進(jìn)行資源回收。

通過(guò)將SqlSession對(duì)象的創(chuàng)建和管理職責(zé)交由SqlSessionFactory統(tǒng)一管理,不僅可以保證SqlSession對(duì)象的有效性和一致性,同時(shí)也可以避免重復(fù)創(chuàng)建和銷毀SqlSession對(duì)象的開銷,提高系統(tǒng)性能和穩(wěn)定性。

Mybatis是一個(gè)我項(xiàng)目開發(fā)中常用的非常優(yōu)秀的ORM框架,它可以幫我們快速、簡(jiǎn)便地操作數(shù)據(jù)庫(kù)。本文將會(huì)按照Mybatis的原理手寫一個(gè)ORM框架,并通過(guò)利用中介者模式來(lái)實(shí)現(xiàn)JDBC方式操作數(shù)據(jù)庫(kù)的增強(qiáng)。

二、Mybatis工作原理

在開始實(shí)現(xiàn)ORM框架之前,我們需要先了解一下Mybatis的工作原理:

SqlSessionFactory:SqlSessionFactory是Mybatis的核心接口,它是一個(gè)工廠類,用于創(chuàng)建SqlSession對(duì)象。SqlSession是Mybatis的另一個(gè)核心接口,它提供了操作數(shù)據(jù)庫(kù)的方法和事務(wù)管理的功能。

Configuration:Configuration是Mybatis的配置類,它包含了Mybatis的所有配置,如數(shù)據(jù)源、映射關(guān)系等,用于生成SqlSessionFactory。

SqlSession:SqlSession是Mybatis的會(huì)話類,它與數(shù)據(jù)庫(kù)的連接是一一對(duì)應(yīng)的,負(fù)責(zé)與數(shù)據(jù)庫(kù)進(jìn)行交互。SqlSession中包含了一系列的操作數(shù)據(jù)庫(kù)的方法,如插入、更新、刪除、查詢等。

Mapper:Mapper是Mybatis的映射器,它定義了Java對(duì)象與SQL語(yǔ)句之間的映射關(guān)系,即將Java對(duì)象轉(zhuǎn)化為SQL語(yǔ)句,或?qū)QL語(yǔ)句轉(zhuǎn)化為Java對(duì)象。

Executor:Executor是Mybatis的執(zhí)行器,它負(fù)責(zé)執(zhí)行SQL語(yǔ)句,管理事務(wù)。Mybatis中有兩種類型的執(zhí)行器:SimpleExecutor和ReuseExecutor,SimpleExecutor會(huì)為每個(gè)SQL語(yǔ)句創(chuàng)建一個(gè)Statement對(duì)象,而ReuseExecutor則會(huì)復(fù)用Statement對(duì)象。

TypeHandler:TypeHandler是Mybatis的類型處理器,它用于將Java對(duì)象與數(shù)據(jù)庫(kù)中的數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換。Mybatis中內(nèi)置了許多常用的類型處理器,如StringTypeHandler、IntegerTypeHandler等,可以根據(jù)需要進(jìn)行擴(kuò)展。

三、手寫ORM框架

我們將按照Mybatis的工作原理來(lái)手寫一個(gè)ORM框架,該框架支持基本的增刪改查操作。

1. 創(chuàng)建Configuration類

首先,我們需要?jiǎng)?chuàng)建一個(gè)Configuration類,該類負(fù)責(zé)讀取配置文件并生成SqlSessionFactory對(duì)象。

public class Configuration {
    private final Properties properties = new Properties(); // 存儲(chǔ)配置信息
    public Configuration(String configLocation) {
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream(configLocation);
            properties.load(is);
        } catch (IOException e) {
            throw new RuntimeException("Config file not found!");
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public SqlSessionFactory buildSqlSessionFactory() {
        return new DefaultSqlSessionFactory(this);
    }
    // getter 方法省略...
}

2. 創(chuàng)建SqlSessionFactory和SqlSession類

接下來(lái),我們需要?jiǎng)?chuàng)建SqlSessionFactory和SqlSession類。

public interface SqlSessionFactory {
    SqlSession openSession();
}
public interface SqlSession {
    int insert(String statementId, Object parameter);
    int update(String statementId, Object parameter);
    int delete(String statementId, Object parameter);
    <T> T selectOne(String statementId, Object parameter);
    <T> List<T> selectList(String statementId, Object parameter);
    void close();
}

3. 創(chuàng)建Executor類

然后,我們需要?jiǎng)?chuàng)建Executor類,該類負(fù)責(zé)執(zhí)行SQL語(yǔ)句,并返回結(jié)果。

public interface Executor {
    int insert(MappedStatement mappedStatement, Object parameter);
    int update(MappedStatement mappedStatement, Object parameter);
    int delete(MappedStatement mappedStatement, Object parameter);
    <T> T selectOne(MappedStatement mappedStatement, Object parameter);
    <E> List<E> selectList(MappedStatement mappedStatement, Object parameter);
}

4. 創(chuàng)建MappedStatement類

我們還需要?jiǎng)?chuàng)建MappedStatement類,該類保存了SQL語(yǔ)句和參數(shù)映射關(guān)系的信息。

public class MappedStatement {
    private String statementId; // SQL語(yǔ)句的ID
    private String sql; // SQL語(yǔ)句
    private Class<?> parameterType; // 參數(shù)類型
    private Class<?> resultType; // 返回值類型
    // getter、setter方法省略...
}

5. 創(chuàng)建MapperRegistry和MapperProxy類

最后,我們需要?jiǎng)?chuàng)建MapperRegistry和MapperProxy類,用于將Java對(duì)象與SQL語(yǔ)句之間進(jìn)行映射。

public class MapperRegistry {
    private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new ConcurrentHashMap<>();
    public <T> void addMapper(Class<T> type) {
        knownMappers.put(type, new MapperProxyFactory<>(type));
    }
    public <T> T getMapper(SqlSession sqlSession, Class<T> type) {
        MapperProxyFactory<?> mapperProxyFactory = knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new RuntimeException("Mapper not found: " + type);
        }
        return (T) mapperProxyFactory.newInstance(sqlSession);
    }
}
public class MapperProxy<T> implements InvocationHandler {
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;
    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface) {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 獲取MappedStatement對(duì)象
        String statementId = mapperInterface.getName() + "." + method.getName();
        MappedStatement mappedStatement = sqlSession.getConfiguration().getMappedStatement(statementId);
        // 調(diào)用Executor執(zhí)行SQL
        Object result = null;
        switch (mappedStatement.getSqlCommandType()) {
            case INSERT:
                result = sqlSession.insert(statementId, args[0]);
                break;
            case UPDATE:
                result = sqlSession.update(statementId, args[0]);
                break;
            case DELETE:
                result = sqlSession.delete(statementId, args[0]);
                break;
            case SELECT:
                if (method.getReturnType() == List.class) {
                    result = sqlSession.selectList(statementId, args[0]);
                } else {
                    result = sqlSession.selectOne(statementId, args[0]);
                }
                break;
            default:
                throw new RuntimeException("Unknown SqlCommandType: " + mappedStatement.getSqlCommandType());
        }
        return result;
    }
}

6. 在SqlSession中調(diào)用Executor

最后,在SqlSession的方法中,我們需要調(diào)用Executor來(lái)執(zhí)行SQL語(yǔ)句。

public class DefaultSqlSession implements SqlSession {
    private final Executor executor;
    private final Configuration configuration;
    public DefaultSqlSession(Configuration configuration) {
        this.executor = new SimpleExecutor(configuration);
        this.configuration = configuration;
    }
    @Override
    public int insert(String statementId, Object parameter) {
        MappedStatement mappedStatement = configuration.getMappedStatement(statementId);
        return executor.insert(mappedStatement, parameter);
    }
    @Override
    public int update(String statementId, Object parameter) {
        MappedStatement mappedStatement = configuration.getMappedStatement(statementId);
        return executor.update(mappedStatement, parameter);
    }
    @Override
    public int delete(String statementId, Object parameter) {
        MappedStatement mappedStatement = configuration.getMappedStatement(statementId);
        return executor.delete(mappedStatement, parameter);
    }
    @Override
    public <T> T selectOne(String statementId, Object parameter) {
        MappedStatement mappedStatement = configuration.getMappedStatement(statementId);
        return executor.selectOne(mappedStatement, parameter);
    }
    @Override
    public <T> List<T> selectList(String statementId, Object parameter) {
        MappedStatement mappedStatement = configuration.getMappedStatement(statementId);
        return executor.selectList(mappedStatement, parameter);
    }
    @Override
    public void close() {
        // 關(guān)閉Executor等資源
    }
}

7. 創(chuàng)建MapperProxyFactory類

在創(chuàng)建MapperRegistry時(shí),我們還需要?jiǎng)?chuàng)建一個(gè)MapperProxyFactory類,用于創(chuàng)建MapperProxy對(duì)象。

public class MapperProxyFactory<T> {
    private final Class<T> mapperInterface;
    public MapperProxyFactory(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }
    public T newInstance(SqlSession sqlSession) {
        return (T) Proxy.newProxyInstance(
                mapperInterface.getClassLoader(),
                new Class[]{mapperInterface},
                new MapperProxy<>(sqlSession, mapperInterface));
    }
}

到此為止,我們已經(jīng)手寫了一個(gè)簡(jiǎn)單的ORM框架,并且可以進(jìn)行基本的增刪改查操作。

四、利用中介者模式增強(qiáng)JDBC方式操作數(shù)據(jù)庫(kù)

接下來(lái),我們將利用中介者模式來(lái)增強(qiáng)JDBC方式操作數(shù)據(jù)庫(kù)的功能。

1. 創(chuàng)建DataSource類

首先,我們需要?jiǎng)?chuàng)建一個(gè)DataSource類,該類負(fù)責(zé)管理數(shù)據(jù)庫(kù)連接和釋放資源。

public class DataSource {
    private String url;
    private String username;
    private String password;
    private static final ThreadLocal<Connection> connectionHolder = new ThreadLocal<>();
    public DataSource(String url, String username, String password) {
        this.url = url;
        this.username = username;
        this.password = password;
    }
    public Connection getConnection() throws SQLException {
        Connection connection = connectionHolder.get();
        if (connection == null) {
            connection = DriverManager.getConnection(url, username, password);
            connectionHolder.set(connection);
        }
        return connection;
    }
    public void releaseConnection(Connection connection) throws SQLException {
        if (connection != null && !connection.isClosed()) {
            connection.close();
        }
        connectionHolder.remove();
    }
}

2. 創(chuàng)建JdbcExecutor類

然后,我們需要?jiǎng)?chuàng)建JdbcExecutor類,該類繼承自Executor類,用于執(zhí)行JDBC操作。

public class JdbcExecutor extends Executor {
    private final DataSource dataSource;
    public JdbcExecutor(Configuration configuration, DataSource dataSource) {
        super(configuration);
        this.dataSource = dataSource;
    }
    @Override
    public int insert(MappedStatement mappedStatement, Object parameter) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = dataSource.getConnection();
            statement = connection.prepareStatement(mappedStatement.getSql());
            statement.setObject(1, parameter);
            return statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
                if (connection != null) {
                    dataSource.releaseConnection(connection);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public int update(MappedStatement mappedStatement, Object parameter) {
        // 類似insert方法,此處省略...
    }
    @Override
    public int delete(MappedStatement mappedStatement, Object parameter) {
        // 類似insert方法,此處省略...
    }
    @Override
    public <T> T selectOne(MappedStatement mappedStatement, Object parameter) {
        // 類似insert方法,此處省略...
    }
    @Override
    public <E> List<E> selectList(MappedStatement mappedStatement, Object parameter) {
        // 類似insert方法,此處省略...
    }
}

3. 創(chuàng)建JdbcSqlSession類

我們還需要?jiǎng)?chuàng)建一個(gè)JdbcSqlSession類,該類繼承自DefaultSqlSession類,用于創(chuàng)建JdbcExecutor對(duì)象。

public class JdbcSqlSession extends DefaultSqlSession {
    private final DataSource dataSource;
    public JdbcSqlSession(Configuration configuration, DataSource dataSource) {
        super(configuration);
        this.executor = new JdbcExecutor(configuration, dataSource);
        this.dataSource = dataSource;
    }
    @Override
    public void close() {
        // 關(guān)閉DataSource等資源
    }
}

4. 創(chuàng)建JdbcMapperRegistry類

接下來(lái),我們需要?jiǎng)?chuàng)建JdbcMapperRegistry類,該類繼承自MapperRegistry類,用于創(chuàng)建JdbcMapperProxyFactory對(duì)象。

public class JdbcMapperRegistry extends MapperRegistry {
    private final DataSource dataSource;
    public JdbcMapperRegistry(Configuration configuration, DataSource dataSource) {
        super();
        this.dataSource = dataSource;
    }
    @Override
    public <T> void addMapper(Class<T> type) {
        super.addMapper(type);
        JdbcMapperProxyFactory<?> mapperProxyFactory = new JdbcMapperProxyFactory<>(dataSource, type);
        knownMappers.put(type, mapperProxyFactory);
    }
}

5. 創(chuàng)建JdbcMapperProxyFactory類

最后,我們需要?jiǎng)?chuàng)建JdbcMapperProxyFactory類,該類繼承自MapperProxyFactory類,用于創(chuàng)建JdbcMapperProxy對(duì)象。

public class JdbcMapperProxyFactory<T> extends MapperProxyFactory<T> {
    private final DataSource dataSource;
    public JdbcMapperProxyFactory(DataSource dataSource, Class<T> mapperInterface) {
        super(mapperInterface);
        this.dataSource = dataSource;
    }
    @Override
    public T newInstance(SqlSession sqlSession) {
        return (T) Proxy.newProxyInstance(
                mapperInterface.getClassLoader(),
                new Class[]{mapperInterface},
                new JdbcMapperProxy<>(sqlSession, dataSource, mapperInterface));
    }
}

6. 創(chuàng)建JdbcMapperProxy類

最后,我們還需要?jiǎng)?chuàng)建JdbcMapperProxy類,該類繼承自MapperProxy類,用于調(diào)用JdbcSqlSession的方法。

public class JdbcMapperProxy<T> extends MapperProxy<T> {
    private final DataSource dataSource;
    public JdbcMapperProxy(SqlSession sqlSession, DataSource dataSource, Class<T> mapperInterface) {
        super(sqlSession, mapperInterface);
        this.dataSource = dataSource;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 如果是Object類的方法,則直接調(diào)用父類的方法
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        }
        // 獲取MappedStatement對(duì)象
        String statementId = mapperInterface.getName() + "." + method.getName();
        MappedStatement mappedStatement = sqlSession.getConfiguration().getMappedStatement(statementId);
        // 根據(jù)配置文件中的useCache屬性來(lái)判斷是否開啟緩存
        if (mappedStatement.isUseCache()) {
            // TODO: 如果開啟了緩存,先從緩存中查找數(shù)據(jù),如果不存在再調(diào)用JdbcSqlSession中的方法
        }
        // 調(diào)用JdbcSqlSession的方法
        Object result;
        JdbcSqlSession jdbcSqlSession = new JdbcSqlSession(sqlSession.getConfiguration(), dataSource);
        try {
            result = method.invoke(jdbcSqlSession.getMapper(mapperInterface), args);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            jdbcSqlSession.close();
        }
        // 如果開啟了緩存,則將查詢結(jié)果添加到緩存中
        if (mappedStatement.isUseCache()) {
            // TODO: 將查詢結(jié)果添加到緩存中
        }
        return result;
    }
}

到此為止,我們利用中介者模式增強(qiáng)了JDBC方式操作數(shù)據(jù)庫(kù)的功能。通過(guò)使用中介者模式,我們可以讓JDBC操作數(shù)據(jù)庫(kù)更加方便快捷、靈活可擴(kuò)展。

五、小結(jié)一下

Mybatis,這個(gè)神奇的ORM框架,讓我們?cè)诓僮鲾?shù)據(jù)庫(kù)的道路上披荊斬棘。沒錯(cuò),你沒有聽錯(cuò),它就是那個(gè)可以幫我們快速、簡(jiǎn)便地操作數(shù)據(jù)庫(kù)的好伙伴。不過(guò)話說(shuō)回來(lái),你有沒有想過(guò),如果這個(gè)世界上沒有Mybatis,那我們程序員豈不是要像遠(yuǎn)古時(shí)期惡劣的條件下編程,跟數(shù)據(jù)庫(kù)打交道會(huì)變得異常的困難。

但是別擔(dān)心,就算Mybatis哪天離我們而去了,我們也可以自己動(dòng)手寫一個(gè)ORM框架,用中介者模式來(lái)增強(qiáng)JDBC方式操作數(shù)據(jù)庫(kù),這樣,我們就可以輕松愉悅地跟數(shù)據(jù)庫(kù)玩耍啦。所以,讓我們手握鍵盤,放聲歌唱,繼承Mybatis的精髓,創(chuàng)造更加屬于我們自己的數(shù)據(jù)庫(kù)操作方式吧!

我在本文中全面講解了如何按照Mybatis的原理手寫一個(gè)ORM框架,并利用中介者模式增強(qiáng)JDBC方式操作數(shù)據(jù)庫(kù)的功能。在實(shí)際開發(fā)中,ORM框架可以幫助我們快速、簡(jiǎn)便地操作數(shù)據(jù)庫(kù),而中介者模式則可以讓我們的程序更加靈活可擴(kuò)展。同時(shí),在使用ORM框架時(shí),我們需要注意管理數(shù)據(jù)庫(kù)連接和釋放資源等問題,以保證軟件系統(tǒng)的穩(wěn)定性和安全性。

到此這篇關(guān)于一文弄懂Mybatis中介者模式的文章就介紹到這了,更多相關(guān)Mybatis中介者模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot中Dozer的使用小結(jié)

    SpringBoot中Dozer的使用小結(jié)

    dozer是用來(lái)兩個(gè)對(duì)象之間屬性轉(zhuǎn)換的工具,有了這個(gè)工具之后,我們將一個(gè)對(duì)象的所有屬性值轉(zhuǎn)給另一個(gè)對(duì)象時(shí),就不需要再去寫重復(fù)的set和get方法了,下面介紹下SpringBoot中Dozer的使用,感興趣的朋友一起看看吧
    2022-03-03
  • SpringBoot集成Kaptcha驗(yàn)證碼的詳細(xì)過(guò)程

    SpringBoot集成Kaptcha驗(yàn)證碼的詳細(xì)過(guò)程

    Kaptcha是一個(gè)強(qiáng)大而靈活的Java驗(yàn)證碼生成庫(kù),通過(guò)合理的配置和使用,它可以有效地提高web應(yīng)用的安全性,防止自動(dòng)化程序的濫用,這篇文章主要介紹了SpringBoot集成Kaptcha驗(yàn)證碼,需要的朋友可以參考下
    2024-07-07
  • java中的Reference和引用類型實(shí)例精講

    java中的Reference和引用類型實(shí)例精講

    這篇文章主要為大家介紹了java中的Reference和引用類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 詳解Java類加載機(jī)制中的雙親委派模型

    詳解Java類加載機(jī)制中的雙親委派模型

    Java的雙親委派模型是一種類加載機(jī)制,它用于保證Java類的安全性和穩(wěn)定性,在這個(gè)模型中,當(dāng)一個(gè)類需要被加載時(shí),Java虛擬機(jī)會(huì)先檢查自己是否已經(jīng)加載了該類,本文就給大家講解一下Java類加載機(jī)制中的雙親委派模型,需要的朋友可以參考下
    2023-09-09
  • Java Enum的簡(jiǎn)單使用

    Java Enum的簡(jiǎn)單使用

    這篇文章主要為大家詳細(xì)介紹了Java Enum的簡(jiǎn)單使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情

    SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情

    這篇文章主要介紹了SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • Spring事件監(jiān)聽機(jī)制之@EventListener實(shí)現(xiàn)方式詳解

    Spring事件監(jiān)聽機(jī)制之@EventListener實(shí)現(xiàn)方式詳解

    這篇文章主要介紹了Spring事件監(jiān)聽機(jī)制之@EventListener實(shí)現(xiàn)方式詳解,ApplicationContext的refresh方法還是初始化了SimpleApplicationEventMulticaster,發(fā)送事件式還是先獲取ResolvableType類型,再獲取發(fā)送監(jiān)聽列表,需要的朋友可以參考下
    2023-12-12
  • JAVA中while循環(huán)的使用與注意事項(xiàng)

    JAVA中while循環(huán)的使用與注意事項(xiàng)

    這篇文章主要介紹了while循環(huán)在編程中的應(yīng)用,包括其基本結(jié)構(gòu)、語(yǔ)句示例、適用場(chǎng)景以及注意事項(xiàng),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • java常見報(bào)錯(cuò):Array?Out?of?Bounds兩種解決辦法

    java常見報(bào)錯(cuò):Array?Out?of?Bounds兩種解決辦法

    這篇文章主要給大家介紹了關(guān)于java報(bào)錯(cuò)Array?Out?of?Bounds的兩種解決辦法,Array out of bounds錯(cuò)誤表示你嘗試訪問數(shù)組中不存在的索引,即索引小于零或者大于等于數(shù)組的大小,文中通過(guò)代碼將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • 詳解java連接mysql數(shù)據(jù)庫(kù)的五種方式

    詳解java連接mysql數(shù)據(jù)庫(kù)的五種方式

    這篇文章主要介紹了詳解java連接mysql數(shù)據(jù)庫(kù)的五種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論