Všimněte si, že voláte .getConnection()
vícekrát. Ačkoli dokumentace by mohla být v tomto ohledu jasnější DataSource.getConnection()
ve skutečnosti otevře nové připojení (na rozdíl od vracení existujícího), takže musíte zavřít každou instanci vrácenou touto metodou.
Jako .getConnection()
vytvoří novou instanci pokaždé, když se nazývá tento řádek je únikem připojení, protože neuzavírá vracené připojení:
pstmt = dataSource.getConnection().prepareStatement(query);
A tato linka marnotratně otevírá nové spojení, aby ho okamžitě uzavřela:
dataSource.getConnection().close();
Zdá se, že se pokoušíte otevřít a zavřít samostatné připojení pro každé vyvolání isValidUser()
(protože na konci volání této metody ukončujete připojení). I když opravíte netěsnost popsanou výše, není to způsob, jakým mají být připojení používána. Místo toho byste měli sdílet jedno připojení (nebo jejich malý počet) napříč vaší aplikací. Takže když se váš program spustí, otevřete takové připojení a jednou celý program již nepotřebuje připojení (často krátce před ukončením), zavřete jej.
Tento druh chování běžně implementuje injekce závislosti , kde vytváříte svá připojení a další zdroje a poté je předáváte jakýmkoli objektům, které je potřebují – to odděluje správu zdrojů od kódu, který tyto zdroje používá. Jako zjednodušený příklad:
public static void main(String[] args) {
DataSource dataSource = createDataSource();
try (Connection connection = dataSource.getConnection()) {
runProgram(connection);
}
}
/**
* this method doesn't need to worry about closing the Connection,
* it trusts that its caller will be responsible for that.
*/
private static void runProgram(Connection connection) {
// ...
}
Obecně platí, že objekty by měly být zodpovědné pouze za uzavření objektů, které vytvořily, a neměly by se zavírat objekty, které jsou předány. Ve vašem aktuálním kódu UserDaoImpl
otevírá připojení, takže by měl být zodpovědný za jeho uzavření, ale navrhuji předat Connection
místo toho.