Java JDBC和JDBI之间的区别是什么?

Java JDBC和JDBI之间的区别是什么?,java,jdbc,jdbi,Java,Jdbc,Jdbi,我想知道java和之间的区别。特别是,哪一个通常更好?为什么?你的意思是 jDBI旨在以Java(tm)提供方便的表格数据访问。它为查询结果使用Java集合框架,提供了一种外部化sql语句的方便方法,并为正在使用的任何数据库提供命名参数支持 JDBC使用JDBC,如果您不知道是否需要JDBC,我建议您不要使用它。JDBC是Java中用于访问SQL数据库的一个长期确立的标准。数据库供应商实现了一个JDBC驱动程序,以便可以以统一的方式访问所有数据库。实际上,Java中数据库的所有操作都使用JDBC

我想知道java和之间的区别。特别是,哪一个通常更好?为什么?

你的意思是

jDBI旨在以Java(tm)提供方便的表格数据访问。它为查询结果使用Java集合框架,提供了一种外部化sql语句的方便方法,并为正在使用的任何数据库提供命名参数支持


JDBC使用JDBC,如果您不知道是否需要JDBC,我建议您不要使用它。

JDBC是Java中用于访问SQL数据库的一个长期确立的标准。数据库供应商实现了一个JDBC驱动程序,以便可以以统一的方式访问所有数据库。实际上,Java中数据库的所有操作都使用JDBC


JDBI似乎是JDBC之上的某种抽象层,但很难说清楚,因为它的文档记录很差。它肯定没有被广泛使用,这是我第一次听说它。

jDBI是在JDBC之上构建的。所有Java应用程序都使用JDBC访问关系数据库,因此它不是非此即彼的选择。它们是免费的。没有JDBC,就不能使用jDBI

话虽如此,jDBI是另一个人试图将Java开发人员从JDBC所需的样板文件中解放出来的尝试。这就像选择Hibernate、TopLink或iBatis一样。

(我是jDBI的主要作者)

是一个方便的图书馆建在上面。JDBC工作得很好,但通常似乎是针对数据库供应商(驱动程序编写者)而不是用户进行优化。jDBI试图公开相同的功能,但使用的是为用户优化的API

它的级别远低于或。最接近的类似库可能是(分叉的后续库)

jDBI支持两种风格的API,一种较旧的fluent风格,如下所示:

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

这个库有很好的参考文档(javadoc)和一些合理的教程风格的文档。它从2004年就开始出现了,被相对较少的人使用(我个人认识几十个人,可能还有十几家公司),但对他们来说效果非常好。大多数从事it工作的人都是A+型的,他们主要关心的是构建一个适合他们的工具——它是开源的,这在很大程度上是一个副作用。

我在搜索命名SQL参数时发现了jDBI。我使用已知的竞争对手SpringJDBC NamedTemplate,但对8-10MB有奇怪的依赖关系。我已经依赖ANTLR了

我看了几个小时后,jDBI似乎鼓舞人心。
两者(jDBI/Spring JDBC)在某种程度上都可以与iBatis/MyBatis等轻型ORM进行比较。

事实上,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();    
}
然后,如果我们再深入一点,检查如何连接到数据库,您会注意到,对于这个概念验证示例,使用了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;
    }
}
import com.google.inject.inject;
导入com.sql.poc.IConnectionHelper;
导入org.apache.commons.dbcp.ConnectionFactory;
导入org.apache.commons.dbcp.driverManager连接工厂;
导入org.apache.commons.dbcp.PoolableConnectionFactory;
导入org.apache.commons.dbcp.pooligdatasource;
导入org.apache.commons.pool.impl.GenericObject池;
导入javax.sql.DataSource;
导入java.sql.Connection;
导入java.sql.SQLException;
公共类TandemMPConnectionHelper实现IConnectionHelper{
私有最终数据源_数据源;
@注入
TandemMPConnectionHelper(){
试一试{
Class.forName(“com.tandem.t4jdbc.SQLMXDriver”);
}catch(classnotfounde异常){
System.out.println(例如toString());
}
_dataSource=setupDataSource(“jdbc:t4sqlmx://::”、“user1”、“password1”);
}
@凌驾
公共数据源setupDataSource(字符串连接URI、字符串用户名、字符串密码){
GenericObjectPool connectionPool=新的GenericObjectPool();
connectionPool.setMaxActive(20);
ConnectionFactory ConnectionFactory=新驱动器管理器ConnectionFactory(
connectURI,
用户名,
密码);
新的PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,false);
返回新的PoolgDataSource(connectionPool);
}
@凌驾
公共数据源getDataSource(){
返回_数据源;
}
@凌驾
公共连接getConnection(){
连接;
试一试{
connection=_dataSource.getConnection();
connection.setAutoCommit(false);
}捕获(SQLE异常){
System.out.println(e.getMessage());
返回null;
}
回路连接;
}
}
在本例中,我正在访问一个串联的不间断数据库,但同样适用于SQL Server、ORACLE或任何您正在访问的数据库,您只需要正确的JDBC驱动程序(您可以很容易地找到,只需谷歌一下!)


希望它能让您更清楚地了解JDBI和JDBC在代码中的概念位置。

像大多数已经回答过的人一样,
JDBI
是一个方便的库,位于
JDBC
之上,它对大多数应用程序来说不是特别友好,而且级别太低

根据我个人的经验,
JDBI
在成熟的ORMs和自己动手的JDBC之间处于一个甜蜜的停顿。也就是说,我相信它涵盖了普通开发者可能需要的strik的95%
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"));
    }
}
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;
    }
}
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;
    }
}
   @Override
    public Widget fetchWidget(String widgetGuid) {
        Widget widget = jdbi.withHandle(
            handle ->  {
                return handle.createQuery(
                    "SELECT guid, x AS p_x, y AS p_y, width, height, zindex FROM widget WHERE guid = :widgetGuid"
                ).bind("widgetGuid", widgetGuid)
                .registerRowMapper(ConstructorMapper.factory(Widget.class))
                .mapTo(Widget.class)
                .one();
            }
        );
        return widget;
    }