В чем разница между JDBC и JDBI? - PullRequest
37 голосов
/ 28 апреля 2011

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

Ответы [ 6 ]

90 голосов
/ 07 июня 2011

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

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

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

8 голосов
/ 28 апреля 2011

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

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

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

7 голосов
/ 28 апреля 2011

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

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

5 голосов
/ 28 апреля 2011

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

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

4 голосов
/ 23 апреля 2015

Действительно, 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;
    }
}

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

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

0 голосов
/ 18 мая 2012

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

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

...