在面向对象编程领域,JavaOOP(Java Object-Oriented Programming)与JDBC(Java Database Connectivity)的结合堪称经典组合拳。这种技术组合不仅体现了"万物皆对象"的编程思想,更通过标准化的数据库访问接口,实现了业务逻辑与数据存储的完美解耦。我曾在多个电商和ERP系统中采用这种架构模式,其优势在于既能保持代码的面向对象特性,又能确保数据库操作的稳定高效。
在纯JDBC操作中,我们通常需要手动处理ResultSet到对象的转换。通过OOP封装,可以构建基础映射工具类:
java复制public class EntityMapper<T> {
public List<T> mapResultSet(ResultSet rs, RowMapper<T> mapper) throws SQLException {
List<T> entities = new ArrayList<>();
while (rs.next()) {
entities.add(mapper.mapRow(rs));
}
return entities;
}
}
@FunctionalInterface
public interface RowMapper<T> {
T mapRow(ResultSet rs) throws SQLException;
}
这种实现方式相比传统JDBC直接操作的优势在于:
数据库连接管理是JDBC性能优化的关键点。通过面向对象设计,我们可以创建智能连接池:
java复制public class SmartConnectionPool {
private static final int MAX_POOL_SIZE = 20;
private final BlockingQueue<Connection> pool = new ArrayBlockingQueue<>(MAX_POOL_SIZE);
public SmartConnectionPool(String url, String user, String password) {
IntStream.range(0, MAX_POOL_SIZE/2).forEach(i ->
pool.add(createConnection(url, user, password))
);
}
public Connection getConnection() throws InterruptedException {
Connection conn = pool.poll(3, TimeUnit.SECONDS);
if (conn == null && pool.size() < MAX_POOL_SIZE) {
return createConnection(url, user, password);
}
return conn;
}
private Connection createConnection(String url, String user, String password) {
// 实际的连接创建逻辑
}
}
借鉴Spring框架的设计思想,我们可以实现简化版的事务模板:
java复制public class TransactionTemplate {
private final DataSource dataSource;
public <T> T execute(TransactionCallback<T> action) throws SQLException {
Connection conn = dataSource.getConnection();
try {
conn.setAutoCommit(false);
T result = action.doInTransaction(conn);
conn.commit();
return result;
} catch (SQLException e) {
conn.rollback();
throw e;
} finally {
conn.close();
}
}
}
@FunctionalInterface
public interface TransactionCallback<T> {
T doInTransaction(Connection conn) throws SQLException;
}
使用示例:
java复制new TransactionTemplate(dataSource).execute(conn -> {
// 执行多个SQL操作
return queryResult;
});
通过枚举和策略模式实现事务传播控制:
java复制public enum Propagation {
REQUIRED,
REQUIRES_NEW,
NESTED
}
public class TransactionContext {
private static final ThreadLocal<Connection> currentConnection = new ThreadLocal<>();
public static Connection getCurrentConnection() {
return currentConnection.get();
}
// 其他上下文管理方法...
}
java复制public class BatchExecutor {
private final Connection conn;
public BatchExecutor(Connection conn) {
this.conn = conn;
}
public int[] executeBatch(String sql, List<Object[]> paramsList) throws SQLException {
try (PreparedStatement ps = conn.prepareStatement(sql)) {
for (Object[] params : paramsList) {
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
ps.addBatch();
}
return ps.executeBatch();
}
}
}
使用装饰器模式增强ResultSet功能:
java复制public class CachedResultSet implements ResultSet {
private final ResultSet delegate;
private final List<Map<String, Object>> cachedRows = new ArrayList<>();
private int currentIndex = -1;
public CachedResultSet(ResultSet rs) throws SQLException {
this.delegate = rs;
cacheResults();
}
private void cacheResults() throws SQLException {
ResultSetMetaData meta = delegate.getMetaData();
int columnCount = meta.getColumnCount();
while (delegate.next()) {
Map<String, Object> row = new HashMap<>();
for (int i = 1; i <= columnCount; i++) {
row.put(meta.getColumnLabel(i), delegate.getObject(i));
}
cachedRows.add(row);
}
}
// 实现ResultSet接口方法...
}
java复制public interface DaoFactory {
<T> T createDao(Class<T> daoInterface);
}
public class JdbcDaoFactory implements DaoFactory {
private final Connection conn;
public JdbcDaoFactory(Connection conn) {
this.conn = conn;
}
@Override
public <T> T createDao(Class<T> daoInterface) {
return (T) Proxy.newProxyInstance(
daoInterface.getClassLoader(),
new Class<?>[] { daoInterface },
new DaoInvocationHandler(conn, daoInterface)
);
}
private static class DaoInvocationHandler implements InvocationHandler {
// 实现代理逻辑...
}
}
java复制public interface SqlExecutionListener {
void beforeExecute(String sql, Object[] params);
void afterExecute(String sql, Object[] params, long elapsedMillis);
}
public class ObservableConnection implements Connection {
private final Connection delegate;
private final List<SqlExecutionListener> listeners = new ArrayList<>();
// 实现Connection接口并添加监听通知...
}
java复制public class DataAccessException extends RuntimeException {
public DataAccessException(String message, Throwable cause) {
super(message, cause);
}
}
public class OptimisticLockException extends DataAccessException {
public OptimisticLockException(String message) {
super(message, null);
}
}
public class JdbcTemplate {
public <T> T execute(ConnectionCallback<T> action) {
try {
return action.doInConnection(conn);
} catch (SQLException e) {
throw new DataAccessException("Database error", e);
}
}
}
java复制public class SqlStateTranslator {
private static final Map<String, Function<String, RuntimeException>> translators = Map.of(
"23000", msg -> new ConstraintViolationException(msg),
"40001", msg -> new DeadlockException(msg)
);
public static RuntimeException translate(SQLException e) {
Function<String, RuntimeException> translator = translators.get(e.getSQLState());
if (translator != null) {
return translator.apply(e.getMessage());
}
return new DataAccessException(e.getMessage(), e);
}
}
java复制public class TypedParameterBinder {
public static void bindParameters(PreparedStatement ps, Object... params) throws SQLException {
for (int i = 0; i < params.length; i++) {
Object param = params[i];
if (param instanceof LocalDate) {
ps.setDate(i + 1, Date.valueOf((LocalDate) param));
} else if (param instanceof Enum) {
ps.setString(i + 1, ((Enum<?>) param).name());
} else {
ps.setObject(i + 1, param);
}
}
}
}
java复制public class ResultSetConverter {
public static <T> T convert(ResultSet rs, Class<T> targetType) throws SQLException {
if (targetType == String.class) {
return (T) rs.getString(1);
}
if (targetType == Long.class) {
return (T) Long.valueOf(rs.getLong(1));
}
// 其他类型处理...
}
}
java复制public class DatabaseInspector {
private final Connection conn;
public List<String> getTableNames() throws SQLException {
DatabaseMetaData meta = conn.getMetaData();
try (ResultSet rs = meta.getTables(null, null, "%", new String[]{"TABLE"})) {
List<String> tables = new ArrayList<>();
while (rs.next()) {
tables.add(rs.getString("TABLE_NAME"));
}
return tables;
}
}
}
java复制public class EntityClassGenerator {
public String generateClass(String tableName, DatabaseMetaData meta) throws SQLException {
StringBuilder sb = new StringBuilder();
sb.append("public class ").append(toCamelCase(tableName, true)).append(" {\n");
try (ResultSet columns = meta.getColumns(null, null, tableName, null)) {
while (columns.next()) {
String colName = columns.getString("COLUMN_NAME");
String colType = columns.getString("TYPE_NAME");
sb.append(" private ").append(mapToJavaType(colType))
.append(" ").append(toCamelCase(colName, false)).append(";\n");
}
}
sb.append("}");
return sb.toString();
}
}
java复制public class InMemoryDatabaseTest {
private Connection conn;
@BeforeEach
void setup() throws SQLException {
conn = DriverManager.getConnection("jdbc:h2:mem:test");
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE users(id INT PRIMARY KEY, name VARCHAR(100))");
}
}
@Test
void testUserInsert() throws SQLException {
UserDao dao = new UserDao(conn);
User user = new User(1, "Test");
dao.save(user);
assertNotNull(dao.findById(1));
}
}
java复制public class MockResultSet implements ResultSet {
private final List<Map<String, Object>> data;
private int rowIndex = -1;
public MockResultSet(List<Map<String, Object>> data) {
this.data = data;
}
@Override
public boolean next() {
return ++rowIndex < data.size();
}
@Override
public Object getObject(String columnLabel) {
return data.get(rowIndex).get(columnLabel);
}
// 其他方法实现...
}
java复制public class ResultSetStream {
public static Stream<Map<String, Object>> toStream(ResultSet rs) throws SQLException {
Spliterator<Map<String, Object>> spliterator = new Spliterators.AbstractSpliterator<Map<String, Object>>(
Long.MAX_VALUE, Spliterator.ORDERED) {
@Override
public boolean tryAdvance(Consumer<? super Map<String, Object>> action) {
try {
if (!rs.next()) return false;
ResultSetMetaData meta = rs.getMetaData();
Map<String, Object> row = new HashMap<>();
for (int i = 1; i <= meta.getColumnCount(); i++) {
row.put(meta.getColumnLabel(i), rs.getObject(i));
}
action.accept(row);
return true;
} catch (SQLException e) {
throw new UncheckedSQLException(e);
}
}
};
return StreamSupport.stream(spliterator, false);
}
}
java复制public record UserRecord(Long id, String username, LocalDateTime createTime) {}
public List<UserRecord> fetchUsers(Connection conn) throws SQLException {
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
return ResultSetStream.toStream(rs)
.map(row -> new UserRecord(
(Long) row.get("id"),
(String) row.get("username"),
((Timestamp) row.get("create_time")).toLocalDateTime()))
.collect(Collectors.toList());
}
}