【发布时间】:2017-12-08 03:11:19
【问题描述】:
开始了一份新工作,需要学习 Java(作为 .NET 开发人员已有十多年了)。上级要求所有新的东西都必须在 Java / Oracle 中完成。
所以我正在进行 PluralSight 培训,现在我正在尝试学习 JDBC 的复杂性。
我在 Oracle 数据库中有下表(对我来说也是一项新技术)。
CREATE TABLE "TEST"."ACCOUNT"
(
"ACCOUNT_ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY VALUE,
"ACCOUNT_NAME" VARCHAR2(20)
"ACCOUNT_NUMBER" VARCHAR2(20)
"ACCOUNT_TYPE" VARCHAR2(20)
)
我使用存储库模式设置了一些代码。但这很简单:
public static void main(String[] args) throws IOException {
IAccountMapper accountMapper = new AccountMapper();
IConfiguration configuration = new OracleConfiguration();
try (
IDataAccess<ResultSet> dataAccess = new OracleDataAccess(configuration);
IAccountRepository accountRepo = new AccountRepository(accountMapper, dataAccess);
){
//nothing here
List<Account> accounts = accountRepo.query(new AllAccountsSpecification());
} catch (Exception e){
System.err.println(e.getMessage());
}
}
IDataAccess 接口:
public interface IDataAccess<T> {
T get(String query) throws SQLException;
}
我的所有实现都在基类中,并且引用了子类 - 即:
public interface IOracleDataAccess extends IDataAccess<ResultSet>{
}
public class OracleDataAccess extends DataAccessBase<ResultSet> implements IOracleDataAccess {
public OracleDataAccess(IConfiguration configuration) throws SQLException {
super(configuration);
}
IDataAccess 的实现(一个基类,其中 T 是 repo 使用的实体):
public abstract class DataAccessBase<T> implements AutoCloseable {
protected final IConfiguration configuration;
protected Connection connection;
protected PreparedStatement statement;
protected ResultSet resultSet;
public DataAccessBase(IConfiguration configuration) {
this.configuration = configuration;
this.connection = DriverManager.getConnection(configuration.getConnectionString(),
configuration.getUsername(), configuration.getPassword());
}
public T get(String query) throws SQLException {
statement = connection.prepareStatement(query);
return (T)statement.executeQuery();
}
}
这个 DataAccess 类被注入到我的 Repository 类中,用于返回结果:
public abstract class ReadOnlyRepositoryBase<T> implements IReadOnlyRepository<T> {
protected final IMapper<ResultSet, T> mapper;
protected final IDataAccess<ResultSet> database;
public ReadOnlyRepositoryBase(IMapper<ResultSet, T> mapper, IDataAccess<ResultSet> database) {
this.mapper = mapper;
this.database = database;
}
public List<T> query(ISpecification specification){
List<T> entities = new ArrayList<>;
try {
System.out.println(specification.toSqlQuery());
//This is what is output:
//SELECT * FROM ACCOUNT
//this returns 1 record when: "select tablespace_name, table_name from user_tables"
//returns no records when "select * from account"
ResultSet rs = database.get(specification.toSqlQuery());
//loop is never entered for "select * from account"
//runs once for "select tablespace_name, table_name from user_tables"
while(rs.next()){
entities.add(mapper.map(rs));
}
} catch (SQLException sqlEx){
sqlEx.printStackTrace();
}
return entities;
}
}
问题是什么都没有回来(ResultSet next() 方法返回 false)这条 SQL:
SELECT * FROM ACCOUNT
从 Oracle SQL Developer IDE 返回 2 条记录 - 但代码中没有任何记录。
如果我从代码中运行此查询:
"SELECT TABLESPACE_NAME, TABLE_NAME FROM USER_TABLES"
我得到了 1 条记录(测试,帐户)
我是否需要进一步限定 SQL 中的表才能取回记录?
我使用与我连接的相同凭据登录到数据库 - 所以我认为这不是权限问题。
【问题讨论】:
-
您分享的代码不足以找出问题所在。请分享更多关于流程、入口数据等的代码。
-
请在
try {之后和ResultSet rs = dat ....之前插入System.println( specification.toSqlQuery() );语句(或将其打印到日志的其他代码),然后运行代码并检查控制台(或日志) - 请复制打印在控制台或日志中的语句,并将其粘贴到问题中。 -
如果您刚刚在 SQL Developer 中创建了表并插入了两行,那么在从 Java 查询之前,您是否在该会话中
commit? -
@AlexPoole - 昨天没有通过 IDE 插入这些记录。
-
@krokodilko - 添加了代码和结果。