bri*_*anm 95
(我是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();
Run Code Online (Sandbox Code Playgroud)
一个较新的SQL Object 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);
}
Run Code Online (Sandbox Code Playgroud)
该库具有良好的参考文档(javadoc)和http://jdbi.org/上的一些合理的教程样式文档.它自2004年以来一直存在,并且被相对较少的人使用(我个人认识的几十个人,可能有十几家公司),但它对他们非常有效.大多数从事这项工作的人都是A +人,他们主要关注的是构建一个适合他们的工具 - 它是开源的主要是副作用.
你的意思是http://jdbi.codehaus.org/?
jDBI旨在提供Java(tm)中方便的表格数据访问.它使用Java集合框架进行查询结果,提供了一种外部化sql语句的便捷方法,并为正在使用的任何数据库提供命名参数支持.
JDBI使用JDBC,如果你不知道你是否需要JDBI,我建议你不要使用它.
JDBC是Java中用于访问SQL数据库的长期标准.数据库供应商实现JDBC驱动程序,以便可以以统一的方式访问所有数据库.实际上,Java中的数据库所做的一切都使用了JDBC.
JDBI似乎是JDBC之上的某种抽象层,但由于文档记录很少,因此很难说.它肯定没有被广泛使用,这是我第一次听说过它.
jDBI构建于JDBC之上.所有Java应用程序都使用JDBC来访问关系数据库,因此它不是一种选择.他们是免费的.没有JDBC就不能使用jDBI.
话虽如此,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();
}
Run Code Online (Sandbox Code Playgroud)
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"));
}
}
Run Code Online (Sandbox Code Playgroud)
然后你只需要使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,如果我们更深入一点,检查如何与数据库建立连接,您会注意到,对于这个概念验证示例,使用了 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;
}
}
Run Code Online (Sandbox Code Playgroud)
在本例中,我正在访问 Tandem Non/Stop 数据库,但同样适用于 SQL Server、ORACLE 或您要访问的任何数据库,您只需要正确的 JDBC 驱动程序(您可以轻松找到该驱动程序,只需 Google 即可!)。
希望它能让您从概念上更清楚地了解代码中 JDBI 和 JDBC 的位置。