52

JavaでのJDBCJDBIの違いについて知りたいです。特に、一般的にどちらが優れているのか、そしてその理由は何ですか?

4

7 に答える 7

119

(私は jDBI の主な作成者です)

jDBIは、 JDBCの上に構築された便利なライブラリです。JDBC は非常にうまく機能しますが、一般的に、ユーザーよりもデータベース ベンダー (ドライバー ライター) 向けに最適化されているようです。jDBI は同じ機能を公開しようとしますが、ユーザー向けに最適化された API を使用します。

HibernateJPAなどよりもはるかに低いレベルです。最も近い同様のライブラリは、おそらくMyBatis ( iBATISのフォークされた後継) です。

jDBI は 2 つのスタイル API をサポートしています。これは古い流暢なスタイルで、次のようになります。

List<Something> r = h.createQuery("select * from something where name = :name and id = :id")
                .bind(0, "eric")
                .bind("id", 1)
                .map(Something.class)
                .list();

新しい SQL オブジェクト API は、より多くのリフレクション型の処理を行い、実際に一連の JDBC 処理を抽象化し始めています。

interface TheBasics
{
    @SqlUpdate("insert into something (id, name) values (:id, :name)")
    int insert(@BindBean Something something);

    @SqlQuery("select id, name from something where id = :id")
    Something findById(@Bind("id") long id);
}

@Test
public void useTheBasics() throws Exception
{
    TheBasics dao = dbi.onDemand(TheBasics.class);

    dao.insert(new Something(7, "Martin"));

    Something martin = dao.findById(7);
}

このライブラリには、優れたリファレンス ドキュメント (javadoc) と、適切なチュートリアル スタイルのドキュメントがhttp://jdbi.org/にあります。これは 2004 年から存在しており、比較的少数の人々 (私が個人的に知っている数十人、おそらく十数社の企業) によって使用されていますが、非常にうまく機能しています。それに取り組んでいる人々のほとんどは A+ の人々であり、主に彼らにとってうまく機能するツールを構築することに関心があります。それがオープンソースであることは、主に副作用です。

于 2011-06-06T22:36:00.463 に答える
9

https://jdbi.org のことですか?

jDBI は、Java(tm) で便利な表形式のデータ アクセスを提供するように設計されています。クエリ結果に Java コレクション フレームワークを使用し、SQL ステートメントを外部化する便利な手段を提供し、使用されているデータベースに対して名前付きパラメーターのサポートを提供します。

JDBI は JDBC を使用します。JDBI が必要かどうかわからない場合は、使用しないことをお勧めします。

于 2011-04-28T13:37:30.273 に答える
8

JDBC は、Java で SQL データベースにアクセスするために使用される、長い間確立された標準です。DB ベンダーは JDBC ドライバーを実装して、すべての DB に均一な方法でアクセスできるようにします。Java でデータベースを操作する場合、実際にはすべて JDBC を使用します。

JDBI は、JDBC の上にあるある種の抽象化レイヤーのように見えますが、文書化が不十分なため、見分けるのは困難です。確かにあまり使われていませんし、初めて聞きました。

于 2011-04-28T13:39:47.797 に答える
5

jDBI は JDBC の上に構築されています。すべての Java アプリケーションは JDBC を使用してリレーショナル データベースにアクセスするため、どちらか一方しか選択できません。無料です。JDBC なしで jDBI を使用することはできません。

そうは言っても、jDBI は、Java 開発者を JDBC に必要なボイラープレートから解放しようとする別の人物の試みです。Hibernate、TopLink、または iBatis を選択するようなものです。

于 2011-04-28T14:27:54.120 に答える
4

実際、JDBI は JDBC の上に構築されています。実際、ほとんどの場合、JDBC を使用して DB にアクセスします。JDBI は、JDBC を包含 (またはラップ) して、DB に対して PreparedStatements を実行するものになります。

内部的には、JDBC ドライバーはトランザクションを実行するドライバーであり、JDBI は単に仲介者として機能します。

ORM (Hibernate や Spring など) よりも軽量ですが、コーディングをより簡単かつクリーンにするための多くのユーティリティがあるため、開発をスピードアップし、すべてを「素晴らしくクリーン」にするのに本当に役立ちます。次に例を示します。

テーブルを挿入/読み取る単純なオブジェクトを定義するには、次のようにします。

import com.sql.poc.data.jDBI.map.AgentMapper;
import com.sql.poc.domain.Agent;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;

public interface SqlObjectDataAccess extends Transactional<SqlObjectDataAccess> {

    @SqlUpdate("INSERT INTO pocAgent (LocationId, Name, Country) VALUES (:id, :name, :country)")
    void insertAgent(@Bind("id") String locationId,
                     @Bind("name") String name,
                     @Bind("country") String country);

    @SqlQuery("SELECT LOCATIONID, NAME, COUNTRY, CREATEDON FROM pocAgent WHERE LOCATIONID = :LocationId")
    @Mapper(AgentMapper.class)
    Agent getAgentByLocation(@Bind("LocationId") String locationId);

    void close();    
}

JDBI は、次のようなすべてのマッピング ロジックを同じ場所に配置する機能を提供します。

import com.sql.poc.domain.Agent;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
import java.sql.ResultSet;
import java.sql.SQLException;

public class AgentMapper implements ResultSetMapper<Agent> {
    @Override
    public Agent map(int index, ResultSet r, StatementContext ctx) throws SQLException {
        return new Agent(r.getString("LocationId"),
                r.getString("Name"),
                r.getString("Country"),
                r.getDate("CreatedOn"));
    }
}

そして、DAO (データ アクセス オブジェクト) を使用する必要があります。

import com.google.inject.Inject;
import com.sql.poc.IConnectionHelper;
import com.sql.poc.domain.Agent;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.logging.Log4JLog;

public class SqlObjectRepository {
    IConnectionHelper _connectionHelper;
    DBI _dbiInstance;
    SqlObjectDataAccess _daoHandler;

    @Inject
    SqlObjectRepository() {
        _dbiInstance = new DBI(_connectionHelper.getDataSource());
        _dbiInstance.setSQLLog(new Log4JLog());
    }

    public void openConnection() {
        if (_daoHandler == null)
            _daoHandler = _dbiInstance.open(SqlObjectDataAccess.class);
    }

    @org.skife.jdbi.v2.sqlobject.Transaction
    public Agent insertAgent(String locationId, String name, String country) {
        openConnection();
        Agent agent = _daoHandler.getAgentByLocation(locationId);
        if (agent == null) {
            _daoHandler.insertAgent(locationId, name, country);
        }
        agent = _daoHandler.getAgentByLocation(locationId);
        _daoHandler.commit();
        return agent;
    }
}

次に、もう少し深く掘り下げて、DB への接続がどのように行われるかを確認すると、この概念実証のサンプルでは JDBC が使用されていることがわかります。

import com.google.inject.Inject;
import com.sql.poc.IConnectionHelper;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class TandemMPConnectionHelper implements IConnectionHelper {
    private final DataSource _dataSource;

    @Inject
    TandemMPConnectionHelper() {
        try {
            Class.forName("com.tandem.t4jdbc.SQLMXDriver");
        } catch (ClassNotFoundException e) {
            System.out.println(e.toString());
        }
        _dataSource = setupDataSource("jdbc:t4sqlmx://<server>:<port>/:<username>:<password>:", "user1", "password1");
    }

    @Override
    public DataSource setupDataSource(String connectURI, String userName, String password) {
        GenericObjectPool connectionPool = new GenericObjectPool();
        connectionPool.setMaxActive(20);
        ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                connectURI,
                userName,
                password);
        new PoolableConnectionFactory(connectionFactory, connectionPool, null, null, false, false);
        return new PoolingDataSource(connectionPool);
    }

    @Override
    public DataSource getDataSource() {
        return _dataSource;
    }

    @Override
    public Connection getConnection() {
        Connection connection;
        try {
            connection = _dataSource.getConnection();
            connection.setAutoCommit(false);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
            return null;
        }
        return connection;
    }
}

この場合、Tandem Non/Stop データベースに到達していますが、SQL Server、ORACLE、または到達しているデータベースでも同じように機能します。正しい JDBC ドライバーが必要なだけです (簡単に見つけることができます。Google で検索してください!)。

概念的に、コード内で JDBI と JDBC を配置する場所がより明確になることを願っています。

于 2015-04-23T15:09:13.447 に答える
0

名前付き SQL パラメータを検索すると、jDBI が見つかりました。私は既知の競合他社の Spring JDBC NamedTemplate を使用していますが、8 ~ 10 MB の奇妙な依存関係があります。私はすでにANTLRに依存しています。

数時間前から見ていますが、jDBI は刺激的なようです。両方 (jDBI/Spring JDBC) は、iBatis/MyBatis などの軽い ORM とある程度比較できます。

于 2012-05-18T08:13:11.133 に答える