有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (6) 个答案

  1. # 1 楼答案

    实际上,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驱动程序(,您可以轻松找到,只需谷歌一下!

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

  2. # 2 楼答案

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

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

  3. # 3 楼答案

    (我是jDBI的主要作者)

    jDBI是建立在JDBC之上的一个方便的库。JDBC工作得很好,但总体而言,它似乎更适合数据库供应商(驱动程序编写者)而不是用户。jDBI试图公开相同的功能,但使用的是为用户优化的API

    它的级别比HibernateJPA低得多。最接近的类似库可能是MyBatis(分叉继承iBATIS

    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();
    

    一个更新的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);
    }
    

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

  4. # 4 楼答案

    你是说https://jdbi.org

    jDBI is designed to provide convenient tabular data access in Java(tm). It uses the Java collections framework for query results, provides a convenient means of externalizing sql statements, and provides named parameter support for any database being used.

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

  5. # 5 楼答案

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

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

  6. # 6 楼答案

    像大多数已经回答的人一样,JDBIJDBC之上的一个方便的库,它不是特别友好的用户界面,对于大多数应用程序来说,它的级别太低

    根据我个人的经验,JDBI在成熟的orm和自己动手的JDBC之间处于一个甜蜜的停顿。也就是说,我相信,通过在控制(您可以轻松调整SQL)和便利性(与JDBC相比,您的生产率显著提高)之间取得平衡,它涵盖了普通开发人员可能需要的95%的内容

    当然,一幅画抵得上千言万语。这是一种DAO方法,通过JDBI获取一行并将其转换为对象层次结构:

       @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;
        }
    

    想象一下,用JDBC做同样的事情是可行的,但非常乏味。。。而且JDBI可以做更多的事情——例如,检查它的SqlObjectAPI