编写自己的JDBC框架

Jun 07, 2016 pm 04:06 PM
jdbc フレーム

一、数据库连接池: 

  在一般用JDBC 进行连接数据库进行CRUD操作时,每一次都会:

    通过:java.sql.Connection conn = DriverManager.getConnection(url,user,password); 重新获取一个数据库的链接再进行操作,这样用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。

18182134-7f7837eb36d64384944ff8c18c7a87ac.png


所以为了减少服务器的压力,便可用连接池的方法:在启动Web应用时,数据就创建好一定数量的Connection链接
  存放到一个容器中,然后当用户请求时,服务器则向容器中获取Connection链接来处理用户的请求,当用户的请求完成后,
  又将该Connection 链接放回到该容器中。这样的一个容器称为连接池。

    18182325-70f65b66b08249f5a588316d537ca99c.png  
  编写一个基本的连接池实现连接复用
       步骤:
       1、建立一个数据库连接池容器。(因为方便存取,则使用LinkedList集合)
       2、初始化一定数量的连接,放入到容器中。
       3、等待用户获取连接对象。(该部分要加锁)
          |---记得删除容器中对应的对象,放置别人同时获取到同一个对象。
       4、提供一个方法,回收用户用完的连接对象。
       5、要遵循先入先出的原则。

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;


/**
 * 一个基本的数据连接池:  
 * 1、初始化时就建立一个容器,来存储一定数量的Connection 对象
 * 2、用户通过调用MyDataSource 的getConnection 来获取Connection 对象。
 * 3、再通过release 方法来回收Connection 对象,而不是直接关闭连接。
 * 4、遵守先进先出的原则。
 *  
 *     
 * @author 贺佐安
 *
 */
public class MyDataSource {
    private static String url = null;
    private static String password = null;
    private static String user = null ;
    private static String DriverClass = null;
    private static LinkedList<Connection> pool = new LinkedList<Connection>() ;
//    注册数据库驱动
    static {
        try {
            InputStream in = MyDataSource.class.getClassLoader()
                    .getResourceAsStream("db.properties");
            Properties prop = new Properties(); 
            prop.load(in);
            user = prop.getProperty("user"); 
            url = prop.getProperty("url") ;
            password = prop.getProperty("password") ; 
            DriverClass = prop.getProperty("DriverClass") ;  
            Class.forName(DriverClass) ;  
            
        } catch (Exception e) {
            throw new RuntimeException(e) ;
        }  
    }
    //初始化建立数据连接池
    public MyDataSource ()  {
        for(int i = 0 ; i < 10 ; i ++) {
            try {
                Connection conn = DriverManager.getConnection(url, user, password) ;
                pool.add(conn) ;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //、从连接池获取连接
    public Connection getConnection() throws SQLException {
        return pool.remove() ;
    } 
    // 回收连接对象。
    public void release(Connection conn) {
        System.out.println(conn+"被回收");
        pool.addLast(conn) ;
    } 
    public int getLength() {
        return pool.size() ;
    }
}
ログイン後にコピー

这样当我们要使用Connection 连接数据库时,则可以直接使用连接池中Connection 的对象。测试如下:

import java.sql.Connection;
import java.sql.SQLException;

import org.junit.Test;


public class MyDataSourceTest {
    
    
    /**
     * 获取数据库连接池中的所有连接。
     */
    @Test
    public void Test() {
        MyDataSource mds = new MyDataSource() ; 
        Connection conn = null ;
        try {
            
            for (int i = 0 ; i < 20 ; i ++) {
                conn = mds.getConnection() ;
                System.out.println(conn+"被获取;连接池还有:"+mds.getLength()); 
                mds.release(conn) ;
            } 
        } catch (SQLException e) {
            e.printStackTrace();
        } 
    }
}
ログイン後にコピー

再运行的时候,可以发现,循环10次后,又再一次获取到了第一次循环的得到的Connection对象。所以,这样可以大大的减轻数据库的压力。上面只是一个简单的数据库连接池,不完美的便是,回收需要调用数据池的release() 方法来进行回收,那么可以不可以直接调用Connection 实例的close 便完成Connection 对象的回收呢?


二、数据源: 

    > 编写连接池需实现javax.sql.DataSource接口。
   > 实现DataSource接口,并实现连接池功能的步骤:
    1、在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。

      2、实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。

    利用动态代理和包装设计模式来标准的数据源。

    1、包装设计模式实现标准数据源:

      这里的用包装设计模式,便是将Connection 接口进行包装。简单总结一下包装设计模式的步骤:

          a)定义一个类,实现与被包装类()相同的接口。
             |----可以先自己写一个适配器,然后后面继承这个适配器,改写需要改写的方法,提高编程效率。
         b)定义一个实例变量,记住被包装类的对象的引用。
         c)定义构造方法,转入被包装类的对象。

          e)对需要改写的方法,改写。
    f)对不需要改写的方法,调用原来被包装类的对应方法。

      所以先编写一个类似适配器的类,将Connection 接口的方法都进行实现:

View Code

      然后再对Connection 接口进行包装,将close 方法修改掉:

import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;
/**
 * 对MyConnectionAdapter 进行包装处理 
 * @author 贺佐安
 *
 */
public class MyConnectionWrap extends MyConnectionAdapter {

    private LinkedList<Connection> pool = new LinkedList<Connection>() ;
    public MyConnectionWrap(Connection conn ,LinkedList<Connection> pool ) {
        super(conn); 
        this.pool = pool ; 
    }
    
    //改写要实现的方法
    public void close() throws SQLException {
        pool.addLast(conn) ;
    }
}
ログイン後にコピー

编写标准数据源:

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.ResourceBundle;

import javax.sql.DataSource;


/** 
 * 编写标准的数据源:
 * 1、实现DataSource 接口
 * 2、获取在实现类的构造方法中批量获取Connection 对象,并将这些Connection 存储
 * 在LinkedList 容器中。
 * 3、实现getConnection() 方法,调用时返回LinkedList容器的Connection对象给用户。
 * @author 贺佐安
 *
 */
public class MyDataSource implements DataSource{
    private static String url = null;
    private static String password = null;
    private static String user = null ;
    private static String DriverClass = null;
    private static LinkedList<Connection> pool = new LinkedList<Connection>() ;

    //    注册数据库驱动
    static {
        try {  
            ResourceBundle rb = ResourceBundle.getBundle("db") ;
            url = rb.getString("url") ; 
            password = rb.getString("password") ; 
            user = rb.getString("user") ; 
            DriverClass = rb.getString("DriverClass") ;
            Class.forName(DriverClass) ;  
            
            //初始化建立数据连接池
            for(int i = 0 ; i < 10 ; i ++) {
                Connection conn = DriverManager.getConnection(url, user, password) ;
                pool.add(conn) ;
            }
        } catch (Exception e) {
            throw new RuntimeException(e) ;
        } 
        
    }
    public MyDataSource ()  {  
    }
    
    //、从连接池获取连接:通过包装模式
    public synchronized Connection getConnection() throws SQLException {
        if (pool.size() > 0) {
            MyConnectionWrap mcw = new MyConnectionWrap(pool.remove(), pool) ;
            return mcw ;
        }else {
            throw new RuntimeException("服务器繁忙!"); 
        }
    }
    
    // 回收连接对象。
    public void release(Connection conn) {
        System.out.println(conn+"被回收");
        pool.addLast(conn) ;
    }
    
    public int getLength() {
        return pool.size() ;
    }
    
    
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        
    }
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        
    }
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
    @Override
    public Connection getConnection(String username, String password)
            throws SQLException {
        return null;
    }
    
}
ログイン後にコピー

 2、动态代理实现标准数据源:

    相对于用包装设计来完成标准数据源,用动态代理则方便许多:

import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.ResourceBundle;

import javax.sql.DataSource;


/** 
 * 编写标准的数据源:
 * 1、实现DataSource 接口
 * 2、获取在实现类的构造方法中批量获取Connection 对象,并将这些Connection 存储
 * 在LinkedList 容器中。
 * 3、实现getConnection() 方法,调用时返回LinkedList容器的Connection对象给用户。
 * @author 贺佐安
 *
 */
public class MyDataSource implements DataSource{
    private static String url = null;
    private static String password = null;
    private static String user = null ;
    private static String DriverClass = null;
    private static LinkedList<Connection> pool = new LinkedList<Connection>() ;

    //    注册数据库驱动
    static {
        try {  
            ResourceBundle rb = ResourceBundle.getBundle("db") ;
            url = rb.getString("url") ; 
            password = rb.getString("password") ; 
            user = rb.getString("user") ; 
            DriverClass = rb.getString("DriverClass") ;
            Class.forName(DriverClass) ;  
            
            //初始化建立数据连接池
            for(int i = 0 ; i < 10 ; i ++) {
                Connection conn = DriverManager.getConnection(url, user, password) ;
                pool.add(conn) ;
            }
        } catch (Exception e) {
            throw new RuntimeException(e) ;
        }  
    }
    public MyDataSource ()  { 
        
    }
    
    //、从连接池获取连接:通过动态代理
    public Connection getConnection() throws SQLException {
        if (pool.size() > 0) {
            final Connection conn  = pool.remove() ; 
            Connection proxyCon = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), 
                    new InvocationHandler() {
                        //策略设计模式:
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
                            if("close".equals(method.getName())){
                                //谁调用,
                                return pool.add(conn);//当调用close方法时,拦截了,把链接放回池中了
                            }else{
                                return method.invoke(conn, args);
                            } 
                        }
                    });
          return proxyCon ;
        }else {
            throw new RuntimeException("服务器繁忙!"); 
        }
    } 
    
    public int getLength() {
        return pool.size() ;
    }
    
    
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        
    }
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        
    }
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
    @Override
    public Connection getConnection(String username, String password)
            throws SQLException {
        return null;
    } 
}
ログイン後にコピー


当然觉得麻烦的则可以直接使用一些开源的数据源如:DBCP、C3P0等。DBCP的原理是用包装设计模式开发的数据源,而C3P0则是动态代理的。

    1、DBCP的使用:

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

/**
 * 创建DBCP 工具类
 * @author 贺佐安
 *
 */
public class DbcpUtil {
    private static DataSource ds = null ;
    static {
        try {
            //读取配置文件
            InputStream in = DbcpUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties") ;
            Properties prop = new Properties() ; 
            prop.load(in) ;
            
            //通过BasicDataSourceFactory 的creatDataSurce 方法创建 BasicDataSource 对象。
            ds = BasicDataSourceFactory.createDataSource(prop) ;
            
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    public static DataSource getDs() {
        return ds ; 
    }
    public static Connection getConnection () {
        try { 
            return ds.getConnection() ;
        } catch (SQLException e) {
            throw new RuntimeException() ;
        } 
    }
}
ログイン後にコピー


2、C3P0 的使用:

import java.sql.Connection;
import java.sql.SQLException;

import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
 * C3P0 开源数据源的使用
 * @author 贺佐安
 *
 */
public class C3p0Util {
    private static ComboPooledDataSource cpds  = null ;
    static {
        
        cpds = new ComboPooledDataSource() ; 
    }
    public static Connection getConnection() {
        try {
            return cpds.getConnection() ;
        } catch (SQLException e) {
            throw new RuntimeException() ;
        }
    }
}
ログイン後にコピー

使用这两个数据源时,直接调用获取到的Connection 连接的close 方法,也是将连接放到pool中去。

    

三、元数据(DatabaseMetaData)信息的获取

  > 元数据:数据库、表、列的定义信息。

  > 元数据信息的获取:为了编写JDBC框架使用。

      1、数据库本身信息的获取:java.sql.DataBaseMateData java.sql.Connection.getMetaData() ;

      DataBaseMateData 实现类的常用方法:

        getURL():返回一个String类对象,代表数据库的URL。

        getUserName():返回连接当前数据库管理系统的用户名。

        getDatabaseProductName():返回数据库的产品名称。

        getDatabaseProductVersion():返回数据库的版本号。

        getDriverName():返回驱动驱动程序的名称。

        getDriverVersion():返回驱动程序的版本号。

        isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。

      2、ParameterMetaData: 代表PerparedStatment 中的SQL 参数元数据信息: java.sql.ParameterMetaData java.sql.PerparedStatement.getParameterMetaData() ;       

      ParameterMetaData 实现类常用方法:

        getParameterCount() :获得指定参数的个数

        getParameterType(int param) :获得指定参数的sql类型(驱动可能不支持)

      3、ResultSetMetaData : 代表结果集的源数据信息:相当于SQL 中的 :DESC java.sql.ResultSetMetaData java.sql.ResultSet.getMetaData() ;         

      java.sql.ResultSetMetaData 接口中常用的方法:

        a) getColumnCount() : 获取查询方法有几列。

        b) getColumnName(int index) : 获取列名:index从1开始。

        c) getColumnType(int index) : 获取列的数据类型。返回的是TYPES 中的常量值。

四、编写自己的JDBC框架:

    JDBC框架的基本组成:  

    1、核心类:

      a、定义一个指定javax.sql.DataSource 实例的引用变量,通过构造函数获取指定的实例并给定义的变量。
      b、编写SQL运行框架。

         DML 语句的编写:
          1、通过获取的javax.sql.DataSource 实例,获取Connection 对象。
           2、通过ParamenterMeteData 获取数据库元数据。

        DQL 语句的编写:
          1、通过获取的DataSource 实例,获取Connection 对象。
          2、通过ParamenterMeteData、ResultSetMetaData 等获取数据库元数据。
          3、用抽象策略设计模式:设计一个ResultSetHandler 接口,作用:将查找出的数据封装到指定的JavaBean中。
                |————这里的JavaBean,由用户来指定。
                抽象策略模式,用户可以更具具体的功能来扩展成具体策略设计模式。如:查找的一条信息、查找的所有信息。

import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

/**
 * 实现JDBC 框架的核心类。
 * 在该类中定义了SQL语句完成的方法;
 * @author 贺佐安
 *
 */
public class  MyJdbcFrame {
    /**
     * javax.sql.DataSource 实例的引用变量
     */
    private DataSource ds = null ;
    /**
     * 将用户指定的DataSource 指定给系统定义的DataSource 实例的引用变量
     * @param ds
     */
    public MyJdbcFrame(DataSource ds ) {
        this.ds = ds ; 
    }
    /**
     * 执行UPDATE、DELETE、INSERT 语句。
     * @param sql 
     * @param obj
     */
    public void update(String sql , Object[] obj) {
        Connection conn = null ; 
        PreparedStatement stmt = null ; 
        try {
            //获取Connection 对象
            conn = ds.getConnection() ;
            stmt = conn.prepareStatement(sql) ; 
            
            // 获取ParameterMetaData 元数据对象。
            ParameterMetaData pmd = stmt.getParameterMetaData() ;
            
            //获取SQL语句中需要设置的参数的个数
            int parameterCount = pmd.getParameterCount() ;
            if (parameterCount > 0) { 
                if (obj == null || obj.length != parameterCount) {
                    throw new MyJdbcFrameException( "parameterCount is error!") ;
                } 
                //设置参数:
                for ( int i = 0 ; i < obj.length ; i++) {
                    stmt.setObject(i+1, obj[i]) ;
                }
            } 
            //执行语句:
            stmt.executeUpdate() ; 
            
        } catch(Exception e ) {
            throw new MyJdbcFrameException(e.getMessage()) ;
        } finally {
            release(stmt, null, conn) ;
        }
    }
    
    public Object query(String sql , Object[] obj , ResultSetHandler rsh) {
        Connection conn = null ; 
        PreparedStatement stmt = null ; 
        ResultSet rs = null ;
        try {
            //获取Connection 对象
            conn = ds.getConnection() ;
            stmt = conn.prepareStatement(sql) ; 
            
            // 获取ParameterMetaData 元数据对象。
            ParameterMetaData pmd = stmt.getParameterMetaData() ;
            
            //获取SQL语句中需要设置的参数的个数
            int parameterCount = pmd.getParameterCount() ;
            
            if (obj.length != parameterCount) {
                throw new MyJdbcFrameException( "&#39;" +sql +"&#39; : parameterCount is error!") ;
            } 
            //设置参数:
            for ( int i = 0 ; i < obj.length ; i++) {
                stmt.setObject(i+1, obj[i]) ;
            }
            //执行语句:
            rs = stmt.executeQuery(); 
            
            return rsh.handler(rs);
        } catch(Exception e ) {
            throw new MyJdbcFrameException(e.getMessage()) ;
        } finally {
            release(stmt, null, conn) ;
        } 
    } 
    /**
     * 释放资源
     * @param stmt
     * @param rs
     * @param conn
     */
    public static void release(Statement stmt 
                             , ResultSet rs 
                             , Connection conn) {
        if(rs != null) {
            try {
                rs.close() ;
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null ;
        }
        if (stmt != null) { 
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } 
            stmt = null ;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null ;
        }
    } 
    
}
ログイン後にコピー

2、接口:策略模式的接口:ResultSetHandler 。

 import java.sql.ResultSet;
//抽象策略模式
public interface ResultSetHandler {
     public Object handler(ResultSet rs) ;
     }
ログイン後にコピー

这里对ResultSetHandler 接口实现一个BeanHandler 实例 :

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

/**
 * 该类获取ResultSet 结果集中的第一个值,封装到JavaBean中
 * @author 贺佐安
 *
 */
public class BeanHandler implements ResultSetHandler { 
    //获取要封装的JavaBean的字节码
    private Class clazz ;
    public BeanHandler (Class clazz) {
        this.clazz = clazz ;
    }

    public Object handler(ResultSet rs) {
        try {
            if (rs.next()) {
                //1、获取结果集的元数据。
                ResultSetMetaData rsm = rs.getMetaData() ;
                //2、创建JavaBean的实例:
                Object obj = clazz.newInstance() ;
                //3、将数据封装到JavaBean中。  
                for (int i = 0 ; i < rsm.getColumnCount() ; i ++) {
                    //获取属性名
                    String columnName = rsm.getColumnName(i+1) ; 
                    //获取属性值
                    Object value = rs.getObject(i+1) ; 
                    
                    Field objField = obj.getClass().getDeclaredField(columnName) ;
                    objField.setAccessible(true) ;
                    objField.set(obj, value) ;
                }
                return obj ;
            } else {
                return null ;
            }
        } catch (Exception e) {
            throw new RuntimeException(e) ;
        }   
    } 
}
ログイン後にコピー

3、自定义异常类:继承RuntimeException。如:

public class MyJdbcFrameException extends RuntimeException {
    public MyJdbcFrameException() {
        super() ; 
    }
    public MyJdbcFrameException(String e) {
        super(e) ;
    }
}
ログイン後にコピー

然后就可以将其打包发布,在以后写数据库操作时就可以用自己的JDBC框架了,如果要完成查询多条语句什么的,则要实现ResultSetHandler 接口。来完成更多的功能。

  当然,使用DBUtils 则更简单:Apache 组织提供的一个开源JDBC 工具类库。



このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java フレームワークの商用サポートの費用対効果を評価する方法 Java フレームワークの商用サポートの費用対効果を評価する方法 Jun 05, 2024 pm 05:25 PM

Java フレームワークの商用サポートのコスト/パフォーマンスを評価するには、次の手順が必要です。 必要な保証レベルとサービス レベル アグリーメント (SLA) 保証を決定します。研究サポートチームの経験と専門知識。アップグレード、トラブルシューティング、パフォーマンスの最適化などの追加サービスを検討してください。ビジネス サポートのコストと、リスクの軽減と効率の向上を比較検討します。

PHP フレームワークの学習曲線は他の言語フレームワークと比較してどうですか? PHP フレームワークの学習曲線は他の言語フレームワークと比較してどうですか? Jun 06, 2024 pm 12:41 PM

PHP フレームワークの学習曲線は、言語熟練度、フレームワークの複雑さ、ドキュメントの品質、コミュニティのサポートによって異なります。 PHP フレームワークの学習曲線は、Python フレームワークと比較すると高く、Ruby フレームワークと比較すると低くなります。 Java フレームワークと比較すると、PHP フレームワークの学習曲線は中程度ですが、開始までの時間は短くなります。

Java フレームワークのパフォーマンス比較 Java フレームワークのパフォーマンス比較 Jun 04, 2024 pm 03:56 PM

ベンチマークによると、小規模で高性能なアプリケーションの場合、Quarkus (高速起動、低メモリ) または Micronaut (TechEmpower に優れた) が理想的な選択肢です。 SpringBoot は大規模なフルスタック アプリケーションに適していますが、起動時間とメモリ使用量が若干遅くなります。

PHP フレームワークの軽量オプションはアプリケーションのパフォーマンスにどのような影響を与えますか? PHP フレームワークの軽量オプションはアプリケーションのパフォーマンスにどのような影響を与えますか? Jun 06, 2024 am 10:53 AM

軽量の PHP フレームワークは、サイズが小さくリソース消費が少ないため、アプリケーションのパフォーマンスが向上します。その特徴には、小型、高速起動、低メモリ使用量、改善された応答速度とスループット、および削減されたリソース消費が含まれます。 実際のケース: SlimFramework は、わずか 500 KB、高い応答性と高スループットの REST API を作成します。

Golang フレームワークのドキュメントのベスト プラクティス Golang フレームワークのドキュメントのベスト プラクティス Jun 04, 2024 pm 05:00 PM

明確で包括的なドキュメントを作成することは、Golang フレームワークにとって非常に重要です。ベスト プラクティスには、Google の Go コーディング スタイル ガイドなど、確立されたドキュメント スタイルに従うことが含まれます。見出し、小見出し、リストなどの明確な組織構造を使用し、ナビゲーションを提供します。スタート ガイド、API リファレンス、概念など、包括的で正確な情報を提供します。コード例を使用して、概念と使用法を説明します。ドキュメントを常に最新の状態に保ち、変更を追跡し、新機能を文書化します。 GitHub の問題やフォーラムなどのサポートとコミュニティ リソースを提供します。 API ドキュメントなどの実践的なサンプルを作成します。

さまざまなアプリケーションシナリオに最適な Golang フレームワークを選択する方法 さまざまなアプリケーションシナリオに最適な Golang フレームワークを選択する方法 Jun 05, 2024 pm 04:05 PM

アプリケーションのシナリオに基づいて最適な Go フレームワークを選択します。アプリケーションの種類、言語機能、パフォーマンス要件、エコシステムを考慮します。一般的な Go フレームワーク: Jin (Web アプリケーション)、Echo (Web サービス)、Fiber (高スループット)、gorm (ORM)、fasthttp (速度)。実際のケース: REST API (Fiber) の構築とデータベース (gorm) との対話。フレームワークを選択します。主要なパフォーマンスには fasthttp、柔軟な Web アプリケーションには Jin/Echo、データベース インタラクションには gorm を選択してください。

Java フレームワーク学習ロードマップ: さまざまな分野のベスト プラクティス Java フレームワーク学習ロードマップ: さまざまな分野のベスト プラクティス Jun 05, 2024 pm 08:53 PM

さまざまな分野の Java フレームワーク学習ロードマップ: Web 開発: SpringBoot と PlayFramework。永続層: Hibernate と JPA。サーバー側のリアクティブ プログラミング: ReactorCore と SpringWebFlux。リアルタイム コンピューティング: ApacheStorm および ApacheSpark。クラウド コンピューティング: AWS SDK for Java および Google Cloud Java。

Golang フレームワークの学習プロセスでよくある誤解は何ですか? Golang フレームワークの学習プロセスでよくある誤解は何ですか? Jun 05, 2024 pm 09:59 PM

Go フレームワークの学習には、フレームワークへの過度の依存と柔軟性の制限という 5 つの誤解があります。フレームワークの規則に従わない場合、コードの保守が困難になります。古いライブラリを使用すると、セキュリティと互換性の問題が発生する可能性があります。パッケージを過度に使用すると、コード構造が難読化されます。エラー処理を無視すると、予期しない動作やクラッシュが発生します。

See all articles