В чем разница между JDBC и JDBI?

Я хочу знать о различиях между JDBC и JDBI в java. В частности, какой из них вообще лучше и почему?

6 ответов


(Я основной автор jDBI)

jDBI это удобная библиотека, построенная поверх JDBC. JDBC работает очень хорошо, но, как правило, оптимизируется для поставщиков баз данных (авторов драйверов) над пользователями. jDBI пытается предоставить ту же функциональность, но в API, оптимизированном для пользователей.

это гораздо более низкий уровень, чем такие вещи, как спящий режим или JPA. Ближайшая подобная библиотека, вероятно, MyBatis (раздвоенный преемником iBATIS).

jDBI поддерживает два 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();

новый API объектов SQL делает гораздо более отражающий тип материала и действительно начинает абстрагировать кучу материала 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+ и в первую очередь озабочены созданием инструмента, который хорошо работает для них-что это открытый исходный код, в основном побочный эффект.


вы имеете в виду http://jdbi.codehaus.org/ ?

jDBI предназначен для обеспечения удобного доступа к табличным данным в Java (tm). Он использует Java collections framework для результатов запросов, предоставляет удобные средства экстернализации операторов sql и обеспечивает поддержку именованных параметров для любой используемой базы данных.

JDBI использует JDBC, если вы не знаете, нужен ли вам JDBI, я бы предложил вам не использовать его.


JDBC-это давно используется в Java для доступа к базам данных SQL. Поставщики БД реализуют драйвер JDBC, чтобы доступ ко всем БД был единообразным. Практически все, что делается с базами данных в Java, использует JDBC.

JDBI кажется своего рода слоем абстракции поверх JDBC, но трудно сказать, так как он плохо документирован. Это, конечно, не широко используется, и это первый раз, когда я слышал о нем.


jDBI построен поверх JDBC. Все приложения Java используют JDBC для доступа к реляционным базам данных, поэтому это не выбор "или / или". Они бесплатные. Вы не можете использовать jDBI без JDBC.

с учетом сказанного, jDBI-это попытка другого человека освободить разработчиков Java от шаблона, требуемого JDBC. Это как выбрать Hibernate или TopLink или iBatis.


действительно, JDBI построен поверх JDBC, на самом деле, скорее всего, вы будете использовать JDBC для достижения БД, и JDBI будет тем, который охватывает(или завернутый) JDBC, чтобы получить 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;
    }
}

затем, если мы пойдем немного глубже и проверим, как соединение выполняется с БД, вы заметите, что для это доказательство концепции образца 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;
    }
}

в этом случае я достигаю тандемной базы данных без остановки, но то же самое работает для SQL Server, ORACLE или любой БД, которую вы достигаете, вам просто нужен правильный драйвер JDBC (что вы можете найти легко, просто Google это!).

надеюсь, это даст вам более четкое представление о том, где концептуально найти JDBI и JDBC в вашем коде.


Я нашел jDBI при поиске именованных параметров SQL. Я использую известный конкурент Spring JDBC NamedTemplate, но имеет странные зависимости для 8-10MB. У меня уже есть зависимость от ANTLR.

Я смотрю с нескольких часов, jDBI кажется вдохновляющим. Оба (Jdbi / Spring JDBC) можно сравнить до некоторой степени со светлым ORM как iBatis/MyBatis etc.