В приложении, которое я писал, один из методов на уровне DAO должен запрашивать базу данных (в этом случае MySQL), возвращая список записей, соответствующих критериям. Таблица, на которую он ссылается, является WordInstance и имеет 3 внешних ключа для 3 других таблиц (слова, части речи и категории). Поле Category в таблице wordInstances может быть нулевой, но остальные поля не могут - потому что слово может не иметь категорию.
У меня есть два отдельных метода createObjectFromResults и createObjectListFromResults. Внутри createObjectListFromResults есть строка/цикл while (objResults.next()) и внутри, которая вызывает другую функцию create, чтобы выполнить работу для отдельной строки. По какой-то причине он пропускает этот цикл, как если бы не было записей для обработки - за исключением случаев, когда я принимаю один и тот же оператор и подключаю его к workbench MySQL, я получаю 1 строку (преобразование раздела "Category =?" В "Category is null "для MySQL Workbench" - это после запуска его один раз и не отбрасывая схему или таблицу между исполнением. Может быть, я что-то не так сделал с моим sQL-запросом в отношении JDBC, чтобы не возвращать записи? Код ниже:
public List<WordInstance> listByWordPartOfSpeechAndCategory(final Word objWord, final PartOfSpeech objPartOfSpeech, final Category objCategory) throws SQLException
{
if(!isTableExists())
createTable();
try
{
PreparedStatement objStatement = getConnection().prepareStatement("select " + getQueriedColumnsForSelect() + " from " + TableName + " where Word = ? and PartOfSpeech = ? and Category = ?;");
objStatement.setInt(1, objWord.getId());
objStatement.setInt(2, objPartOfSpeech.getId());
if(objCategory != null)
objStatement.setInt(3, objCategory.getId());
else
objStatement.setNull(3, Types.INTEGER);
return(createObjectListFromResults(objStatement.executeQuery()));
}
catch(SQLException objException)
{
msObjLogger.error("There was a problem retrieving the word instances that had the same word, part of speech, and category...", objException);
return(null);
}
finally
{
closeConnection();
}
}
TableName для этого объекта DAO - "WordInstances", а getQueriedColumnsForSelect:
protected String getQueriedColumnsForSelect()
{
return("Id, Word, PartOfSpeech, Category, Definition, Slang");
}
createObjectListFromResults здесь:
protected List<WordInstance> createObjectListFromResults(final ResultSet objResults) throws SQLException
{
List<WordInstance> lstWordInstances = new ArrayList<WordInstance>();
while(objResults.next())
lstWordInstances.add(createObjectFromResults(objResults));
return(lstWordInstances);
}
Я могу включить любой другой код в соответствии с запросом, чтобы помочь решить эту проблему. Как я уже сказал, в самой MySQL он возвращает строку (или больше, поскольку я заметил проблему, потому что там было несколько записей). Фактически несколько записей смешивают меня, потому что у меня есть уникальный ключ для Word, PartOfSpeech и Category, если только тот факт, что Категория имеет значение null, что делает ее не уникальной.
Какие-нибудь мысли?
Решение, которое я нашел на другом сайте и адаптированное к моему коду, состояло в том, чтобы составить строку SQL на основе того, была ли категория передана в null, тогда используйте "и Category is null" else "и Category =?" и при настройке параметров, просто установите категорию, если она не равна нулю, если она равна нулю, то инструкция sQL берется за жесткое кодирование "равно нулю" - мне хотелось бы, чтобы JDBC разрешал использовать null вместо a? как параметр, но это только действительно опция с полями операторов обновлений, а не в предложении where.
null
с использованием =
приводит к неизвестности (что интерпретируется как false). Если у вас разные результаты в вашем инструменте запросов при буквальном использовании category = null
, тогда ваш инструмент запросов использует другой параметр обработки нуля для своего сеанса.
createObjectFromResults()
. В любом случае, я не рекомендую методы цепочки и передачиResultSet
как это.