Все ДАО получили перезагруженный метод для того что бы вызываться с передачей соединения и без передачи соединия
This commit is contained in:
AidarKC 2025-12-18 15:58:43 +03:00
parent 1b1da19d3d
commit d6d2bfeb73
6 changed files with 250 additions and 127 deletions

View File

@ -9,6 +9,10 @@ import java.util.List;
/** /**
* DAO для таблицы active_sessions. * DAO для таблицы active_sessions.
*
* Правило:
* - методы с Connection НЕ закрывают соединение
* - методы без Connection сами открывают и закрывают соединение
*/ */
public final class ActiveSessionsDAO { public final class ActiveSessionsDAO {
@ -26,7 +30,10 @@ public final class ActiveSessionsDAO {
return instance; return instance;
} }
public void insert(ActiveSessionEntry session) throws SQLException { // -------------------- INSERT --------------------
/** Вставка с внешним соединением. Соединение НЕ закрывает. */
public void insert(Connection c, ActiveSessionEntry session) throws SQLException {
String sql = """ String sql = """
INSERT INTO active_sessions ( INSERT INTO active_sessions (
sessionId, sessionId,
@ -45,9 +52,7 @@ public final class ActiveSessionsDAO {
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, session.getSessionId()); ps.setString(1, session.getSessionId());
ps.setLong(2, session.getLoginId()); ps.setLong(2, session.getLoginId());
ps.setString(3, session.getSessionPwd()); ps.setString(3, session.getSessionPwd());
@ -61,12 +66,21 @@ public final class ActiveSessionsDAO {
ps.setString(11, session.getClientInfoFromClient()); ps.setString(11, session.getClientInfoFromClient());
ps.setString(12, session.getClientInfoFromRequest()); ps.setString(12, session.getClientInfoFromRequest());
ps.setString(13, session.getUserLanguage()); ps.setString(13, session.getUserLanguage());
ps.executeUpdate(); ps.executeUpdate();
} }
} }
public ActiveSessionEntry getBySessionId(String sessionId) throws SQLException { /** Вставка без внешнего соединения. Сам открывает/закрывает. */
public void insert(ActiveSessionEntry session) throws SQLException {
try (Connection c = db.getConnection()) {
insert(c, session);
}
}
// -------------------- SELECT --------------------
/** Получить по sessionId с внешним соединением. Соединение НЕ закрывает. */
public ActiveSessionEntry getBySessionId(Connection c, String sessionId) throws SQLException {
String sql = """ String sql = """
SELECT SELECT
sessionId, sessionId,
@ -86,11 +100,8 @@ public final class ActiveSessionsDAO {
WHERE sessionId = ? WHERE sessionId = ?
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, sessionId); ps.setString(1, sessionId);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return null; if (!rs.next()) return null;
return mapRow(rs); return mapRow(rs);
@ -98,7 +109,15 @@ public final class ActiveSessionsDAO {
} }
} }
public List<ActiveSessionEntry> getByLoginId(long loginId) throws SQLException { /** Получить по sessionId без внешнего соединения. Сам открывает/закрывает. */
public ActiveSessionEntry getBySessionId(String sessionId) throws SQLException {
try (Connection c = db.getConnection()) {
return getBySessionId(c, sessionId);
}
}
/** Получить список по loginId с внешним соединением. Соединение НЕ закрывает. */
public List<ActiveSessionEntry> getByLoginId(Connection c, long loginId) throws SQLException {
String sql = """ String sql = """
SELECT SELECT
sessionId, sessionId,
@ -120,11 +139,8 @@ public final class ActiveSessionsDAO {
List<ActiveSessionEntry> result = new ArrayList<>(); List<ActiveSessionEntry> result = new ArrayList<>();
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, loginId); ps.setLong(1, loginId);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) result.add(mapRow(rs)); while (rs.next()) result.add(mapRow(rs));
} }
@ -133,23 +149,40 @@ public final class ActiveSessionsDAO {
return result; return result;
} }
public void updateLastAuthirificatedAtMs(String sessionId, long lastAuthMs) throws SQLException { /** Получить список по loginId без внешнего соединения. Сам открывает/закрывает. */
public List<ActiveSessionEntry> getByLoginId(long loginId) throws SQLException {
try (Connection c = db.getConnection()) {
return getByLoginId(c, loginId);
}
}
// -------------------- UPDATE --------------------
/** Обновить lastAuthirificatedAtMs с внешним соединением. Соединение НЕ закрывает. */
public void updateLastAuthirificatedAtMs(Connection c, String sessionId, long lastAuthMs) throws SQLException {
String sql = """ String sql = """
UPDATE active_sessions UPDATE active_sessions
SET lastAuthirificatedAtMs = ? SET lastAuthirificatedAtMs = ?
WHERE sessionId = ? WHERE sessionId = ?
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, lastAuthMs); ps.setLong(1, lastAuthMs);
ps.setString(2, sessionId); ps.setString(2, sessionId);
ps.executeUpdate(); ps.executeUpdate();
} }
} }
/** Обновить lastAuthirificatedAtMs без внешнего соединения. Сам открывает/закрывает. */
public void updateLastAuthirificatedAtMs(String sessionId, long lastAuthMs) throws SQLException {
try (Connection c = db.getConnection()) {
updateLastAuthirificatedAtMs(c, sessionId, lastAuthMs);
}
}
/** Обновить данные refresh с внешним соединением. Соединение НЕ закрывает. */
public void updateOnRefresh( public void updateOnRefresh(
Connection c,
String sessionId, String sessionId,
long lastAuthMs, long lastAuthMs,
String clientIp, String clientIp,
@ -169,9 +202,7 @@ public final class ActiveSessionsDAO {
WHERE sessionId = ? WHERE sessionId = ?
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, lastAuthMs); ps.setLong(1, lastAuthMs);
ps.setString(2, clientIp); ps.setString(2, clientIp);
ps.setString(3, clientInfoFromClient); ps.setString(3, clientInfoFromClient);
@ -182,17 +213,41 @@ public final class ActiveSessionsDAO {
} }
} }
public void deleteBySessionId(String sessionId) throws SQLException { /** Обновить данные refresh без внешнего соединения. Сам открывает/закрывает. */
public void updateOnRefresh(
String sessionId,
long lastAuthMs,
String clientIp,
String clientInfoFromClient,
String clientInfoFromRequest,
String userLanguage
) throws SQLException {
try (Connection c = db.getConnection()) {
updateOnRefresh(c, sessionId, lastAuthMs, clientIp, clientInfoFromClient, clientInfoFromRequest, userLanguage);
}
}
// -------------------- DELETE --------------------
/** Удалить по sessionId с внешним соединением. Соединение НЕ закрывает. */
public void deleteBySessionId(Connection c, String sessionId) throws SQLException {
String sql = "DELETE FROM active_sessions WHERE sessionId = ?"; String sql = "DELETE FROM active_sessions WHERE sessionId = ?";
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, sessionId); ps.setString(1, sessionId);
ps.executeUpdate(); ps.executeUpdate();
} }
} }
/** Удалить по sessionId без внешнего соединения. Сам открывает/закрывает. */
public void deleteBySessionId(String sessionId) throws SQLException {
try (Connection c = db.getConnection()) {
deleteBySessionId(c, sessionId);
}
}
// -------------------- MAPPER --------------------
private ActiveSessionEntry mapRow(ResultSet rs) throws SQLException { private ActiveSessionEntry mapRow(ResultSet rs) throws SQLException {
String sessionId = rs.getString("sessionId"); String sessionId = rs.getString("sessionId");
long loginId = rs.getLong("loginId"); long loginId = rs.getLong("loginId");

View File

@ -21,12 +21,14 @@ public final class BlockchainStateDAO {
return instance; return instance;
} }
/** Получить по blockchainId без внешнего соединения. Сам открывает/закрывает. */
public BlockchainStateEntry getByBlockchainId(long blockchainId) throws SQLException { public BlockchainStateEntry getByBlockchainId(long blockchainId) throws SQLException {
try (Connection c = db.getConnection()) { try (Connection c = db.getConnection()) {
return getByBlockchainId(c, blockchainId); return getByBlockchainId(c, blockchainId);
} }
} }
/** Получить по blockchainId с внешним соединением. Соединение НЕ закрывает. */
public BlockchainStateEntry getByBlockchainId(Connection c, long blockchainId) throws SQLException { public BlockchainStateEntry getByBlockchainId(Connection c, long blockchainId) throws SQLException {
String sql = """ String sql = """
SELECT SELECT
@ -60,12 +62,14 @@ public final class BlockchainStateDAO {
} }
} }
/** UPSERT без внешнего соединения. Сам открывает/закрывает. */
public void upsert(BlockchainStateEntry e) throws SQLException { public void upsert(BlockchainStateEntry e) throws SQLException {
try (Connection c = db.getConnection()) { try (Connection c = db.getConnection()) {
upsert(c, e); upsert(c, e);
} }
} }
/** UPSERT с внешним соединением. Соединение НЕ закрывает. */
public void upsert(Connection c, BlockchainStateEntry e) throws SQLException { public void upsert(Connection c, BlockchainStateEntry e) throws SQLException {
String sql = """ String sql = """
INSERT INTO blockchain_state ( INSERT INTO blockchain_state (
@ -87,7 +91,7 @@ public final class BlockchainStateDAO {
line7_last_number, line7_last_hash, line7_last_number, line7_last_hash,
updated_at_ms updated_at_ms
) VALUES ( ) VALUES (
?,?,?,?,?,?,?,?, -- было 7, стало 8 ?,?,?,?,?,?,?,?,
?,?, ?,?,
?,?, ?,?,
?,?, ?,?,

View File

@ -8,36 +8,35 @@ import java.sql.*;
/** /**
* DAO для таблицы ip_geo_cache. * DAO для таблицы ip_geo_cache.
* *
* Таблица: * * Таблица:
* - ip TEXT PRIMARY KEY * * - ip TEXT PRIMARY KEY
* - geo TEXT * * - geo TEXT
* - updated_at_ms INTEGER NOT NULL * * - updated_at_ms INTEGER NOT NULL
*
* Правило:
* - методы с Connection НЕ закрывают соединение
* - методы без Connection сами открывают и закрывают соединение
*/ */
public final class IpGeoCacheDAO { public final class IpGeoCacheDAO {
private static volatile IpGeoCacheDAO instance; private static volatile IpGeoCacheDAO instance;
private final SqliteDbController db = SqliteDbController.getInstance(); private final SqliteDbController db = SqliteDbController.getInstance();
private IpGeoCacheDAO() { private IpGeoCacheDAO() { }
}
public static IpGeoCacheDAO getInstance() { public static IpGeoCacheDAO getInstance() {
if (instance == null) { if (instance == null) {
synchronized (IpGeoCacheDAO.class) { synchronized (IpGeoCacheDAO.class) {
if (instance == null) { if (instance == null) instance = new IpGeoCacheDAO();
instance = new IpGeoCacheDAO();
}
} }
} }
return instance; return instance;
} }
/** // -------------------- UPSERT --------------------
* UPSERT по ip.
* Если записи нет вставляем. /** UPSERT с внешним соединением. Соединение НЕ закрывает. */
* Если есть обновляем geo и updated_at_ms. public void upsert(Connection c, IpGeoCacheEntry entry) throws SQLException {
*/
public void upsert(IpGeoCacheEntry entry) throws SQLException {
String sql = """ String sql = """
INSERT INTO ip_geo_cache (ip, geo, updated_at_ms) INSERT INTO ip_geo_cache (ip, geo, updated_at_ms)
VALUES (?, ?, ?) VALUES (?, ?, ?)
@ -47,9 +46,7 @@ public final class IpGeoCacheDAO {
updated_at_ms = excluded.updated_at_ms updated_at_ms = excluded.updated_at_ms
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, entry.getIp()); ps.setString(1, entry.getIp());
ps.setString(2, entry.getGeo()); ps.setString(2, entry.getGeo());
ps.setLong(3, entry.getUpdatedAtMs()); ps.setLong(3, entry.getUpdatedAtMs());
@ -57,45 +54,60 @@ public final class IpGeoCacheDAO {
} }
} }
/** /** UPSERT без внешнего соединения. Сам открывает/закрывает. */
* Получить запись по IP. public void upsert(IpGeoCacheEntry entry) throws SQLException {
* Если нет возвращает null. try (Connection c = db.getConnection()) {
*/ upsert(c, entry);
public IpGeoCacheEntry getByIp(String ip) throws SQLException { }
}
// -------------------- SELECT --------------------
/** Получить по IP с внешним соединением. Соединение НЕ закрывает. */
public IpGeoCacheEntry getByIp(Connection c, String ip) throws SQLException {
String sql = """ String sql = """
SELECT ip, geo, updated_at_ms SELECT ip, geo, updated_at_ms
FROM ip_geo_cache FROM ip_geo_cache
WHERE ip = ? WHERE ip = ?
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, ip); ps.setString(1, ip);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) { if (!rs.next()) return null;
return null;
}
return mapRow(rs); return mapRow(rs);
} }
} }
} }
/** /** Получить по IP без внешнего соединения. Сам открывает/закрывает. */
* Опционально очистка старых записей. public IpGeoCacheEntry getByIp(String ip) throws SQLException {
* Можно вызывать по расписанию, если нужно. try (Connection c = db.getConnection()) {
*/ return getByIp(c, ip);
public int deleteOlderThan(long thresholdMs) throws SQLException { }
}
// -------------------- DELETE --------------------
/** Удалить старые записи с внешним соединением. Соединение НЕ закрывает. */
public int deleteOlderThan(Connection c, long thresholdMs) throws SQLException {
String sql = "DELETE FROM ip_geo_cache WHERE updated_at_ms < ?"; String sql = "DELETE FROM ip_geo_cache WHERE updated_at_ms < ?";
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, thresholdMs); ps.setLong(1, thresholdMs);
return ps.executeUpdate(); return ps.executeUpdate();
} }
} }
/** Удалить старые записи без внешнего соединения. Сам открывает/закрывает. */
public int deleteOlderThan(long thresholdMs) throws SQLException {
try (Connection c = db.getConnection()) {
return deleteOlderThan(c, thresholdMs);
}
}
// -------------------- MAPPER --------------------
private IpGeoCacheEntry mapRow(ResultSet rs) throws SQLException { private IpGeoCacheEntry mapRow(ResultSet rs) throws SQLException {
String ip = rs.getString("ip"); String ip = rs.getString("ip");
String geo = rs.getString("geo"); String geo = rs.getString("geo");

View File

@ -17,6 +17,10 @@ import java.util.List;
* - loginKey TEXT * - loginKey TEXT
* - deviceKey TEXT * - deviceKey TEXT
* - bchLimit INTEGER (может быть NULL) * - bchLimit INTEGER (может быть NULL)
*
* * Правило:
* * - методы с Connection НЕ закрывают соединение
* * - методы без Connection сами открывают и закрывают соединение
*/ */
public final class SolanaUsersDAO { public final class SolanaUsersDAO {
@ -28,23 +32,22 @@ public final class SolanaUsersDAO {
public static SolanaUsersDAO getInstance() { public static SolanaUsersDAO getInstance() {
if (instance == null) { if (instance == null) {
synchronized (SolanaUsersDAO.class) { synchronized (SolanaUsersDAO.class) {
if (instance == null) { if (instance == null) instance = new SolanaUsersDAO();
instance = new SolanaUsersDAO();
}
} }
} }
return instance; return instance;
} }
public void insert(SolanaUserEntry user) throws SQLException { // -------------------- INSERT --------------------
/** Вставка с внешним соединением. Соединение НЕ закрывает. */
public void insert(Connection c, SolanaUserEntry user) throws SQLException {
String sql = """ String sql = """
INSERT INTO solana_users (login, loginId, bchId, loginKey, deviceKey, bchLimit) INSERT INTO solana_users (login, loginId, bchId, loginKey, deviceKey, bchLimit)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, user.getLogin()); ps.setString(1, user.getLogin());
ps.setLong(2, user.getLoginId()); ps.setLong(2, user.getLoginId());
ps.setLong(3, user.getBchId()); ps.setLong(3, user.getBchId());
@ -61,16 +64,24 @@ public final class SolanaUsersDAO {
} }
} }
public SolanaUserEntry getByLoginId(long loginId) throws SQLException { /** Вставка без внешнего соединения. Сам открывает/закрывает. */
public void insert(SolanaUserEntry user) throws SQLException {
try (Connection c = db.getConnection()) {
insert(c, user);
}
}
// -------------------- SELECT --------------------
/** Получить по loginId с внешним соединением. Соединение НЕ закрывает. */
public SolanaUserEntry getByLoginId(Connection c, long loginId) throws SQLException {
String sql = """ String sql = """
SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit
FROM solana_users FROM solana_users
WHERE loginId = ? WHERE loginId = ?
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, loginId); ps.setLong(1, loginId);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return null; if (!rs.next()) return null;
@ -79,7 +90,14 @@ public final class SolanaUsersDAO {
} }
} }
// добавь рядом со старым методом /** Получить по loginId без внешнего соединения. Сам открывает/закрывает. */
public SolanaUserEntry getByLoginId(long loginId) throws SQLException {
try (Connection c = db.getConnection()) {
return getByLoginId(c, loginId);
}
}
/** Получить по login (case-insensitive) с внешним соединением. Соединение НЕ закрывает. */
public SolanaUserEntry getByLogin(Connection c, String login) throws SQLException { public SolanaUserEntry getByLogin(Connection c, String login) throws SQLException {
String sql = """ String sql = """
SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit
@ -96,25 +114,15 @@ public final class SolanaUsersDAO {
} }
} }
/** Получить по login (case-insensitive) без внешнего соединения. Сам открывает/закрывает. */
public SolanaUserEntry getByLogin(String login) throws SQLException { public SolanaUserEntry getByLogin(String login) throws SQLException {
String sql = """ try (Connection c = db.getConnection()) {
SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit return getByLogin(c, login);
FROM solana_users
WHERE LOWER(login) = LOWER(?)
""";
try (Connection c = db.getConnection();
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, login);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return null;
return mapRow(rs);
}
} }
} }
public List<SolanaUserEntry> searchByLoginPrefix(String prefix) throws SQLException { /** Поиск по префиксу с внешним соединением. Соединение НЕ закрывает. */
public List<SolanaUserEntry> searchByLoginPrefix(Connection c, String prefix) throws SQLException {
String sql = """ String sql = """
SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit SELECT login, loginId, bchId, loginKey, deviceKey, bchLimit
FROM solana_users FROM solana_users
@ -125,9 +133,7 @@ public final class SolanaUsersDAO {
List<SolanaUserEntry> result = new ArrayList<>(); List<SolanaUserEntry> result = new ArrayList<>();
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, prefix.toLowerCase() + "%"); ps.setString(1, prefix.toLowerCase() + "%");
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) result.add(mapRow(rs)); while (rs.next()) result.add(mapRow(rs));
@ -137,6 +143,15 @@ public final class SolanaUsersDAO {
return result; return result;
} }
/** Поиск по префиксу без внешнего соединения. Сам открывает/закрывает. */
public List<SolanaUserEntry> searchByLoginPrefix(String prefix) throws SQLException {
try (Connection c = db.getConnection()) {
return searchByLoginPrefix(c, prefix);
}
}
// -------------------- MAPPER --------------------
private SolanaUserEntry mapRow(ResultSet rs) throws SQLException { private SolanaUserEntry mapRow(ResultSet rs) throws SQLException {
return new SolanaUserEntry( return new SolanaUserEntry(
rs.getLong("loginId"), rs.getLong("loginId"),

View File

@ -7,32 +7,27 @@ import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** Здесь зраним сохранённые параметры пользователей (в основном до каково сообщения просмотрены ленты) */ /** Здесь храним сохранённые параметры пользователей (в основном до какого сообщения просмотрены ленты) */
public final class UserParamsDAO { public final class UserParamsDAO {
private static volatile UserParamsDAO instance; private static volatile UserParamsDAO instance;
private final SqliteDbController db = SqliteDbController.getInstance(); private final SqliteDbController db = SqliteDbController.getInstance();
private UserParamsDAO() { private UserParamsDAO() { }
}
public static UserParamsDAO getInstance() { public static UserParamsDAO getInstance() {
if (instance == null) { if (instance == null) {
synchronized (UserParamsDAO.class) { synchronized (UserParamsDAO.class) {
if (instance == null) { if (instance == null) instance = new UserParamsDAO();
instance = new UserParamsDAO();
}
} }
} }
return instance; return instance;
} }
/** // -------------------- UPSERT --------------------
* UPSERT методом ON CONFLICT одним SQL-запросом.
* Если запись существует -> обновляем поля. /** UPSERT с внешним соединением. Соединение НЕ закрывает. */
* Если нет -> вставляем новую запись. public void upsert(Connection c, UserParamEntry param) throws SQLException {
*/
public void upsert(UserParamEntry param) throws SQLException {
String sql = """ String sql = """
INSERT INTO users_params ( INSERT INTO users_params (
loginId, loginId,
@ -52,9 +47,7 @@ public final class UserParamsDAO {
signature = excluded.signature signature = excluded.signature
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, param.getLoginId()); ps.setLong(1, param.getLoginId());
ps.setString(2, param.getParam()); ps.setString(2, param.getParam());
ps.setLong(3, param.getBchChannelId()); ps.setLong(3, param.getBchChannelId());
@ -66,10 +59,17 @@ public final class UserParamsDAO {
} }
} }
/** /** UPSERT без внешнего соединения. Сам открывает/закрывает. */
* Получить параметр по loginId + param. public void upsert(UserParamEntry param) throws SQLException {
*/ try (Connection c = db.getConnection()) {
public UserParamEntry getByUserIdAndParam(long loginId, String paramName) throws SQLException { upsert(c, param);
}
}
// -------------------- SELECT --------------------
/** Получить параметр с внешним соединением. Соединение НЕ закрывает. */
public UserParamEntry getByUserIdAndParam(Connection c, long loginId, String paramName) throws SQLException {
String sql = """ String sql = """
SELECT SELECT
loginId, loginId,
@ -83,9 +83,7 @@ public final class UserParamsDAO {
WHERE loginId = ? AND param = ? WHERE loginId = ? AND param = ?
"""; """;
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, loginId); ps.setLong(1, loginId);
ps.setString(2, paramName); ps.setString(2, paramName);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
@ -95,10 +93,15 @@ public final class UserParamsDAO {
} }
} }
/** /** Получить параметр без внешнего соединения. Сам открывает/закрывает. */
* Получить все параметры пользователя. public UserParamEntry getByUserIdAndParam(long loginId, String paramName) throws SQLException {
*/ try (Connection c = db.getConnection()) {
public List<UserParamEntry> getByUserId(long loginId) throws SQLException { return getByUserIdAndParam(c, loginId, paramName);
}
}
/** Получить все параметры пользователя с внешним соединением. Соединение НЕ закрывает. */
public List<UserParamEntry> getByUserId(Connection c, long loginId) throws SQLException {
String sql = """ String sql = """
SELECT SELECT
loginId, loginId,
@ -115,9 +118,7 @@ public final class UserParamsDAO {
List<UserParamEntry> result = new ArrayList<>(); List<UserParamEntry> result = new ArrayList<>();
try (Connection c = db.getConnection(); try (PreparedStatement ps = c.prepareStatement(sql)) {
PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, loginId); ps.setLong(1, loginId);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) result.add(mapRow(rs)); while (rs.next()) result.add(mapRow(rs));
@ -127,6 +128,15 @@ public final class UserParamsDAO {
return result; return result;
} }
/** Получить все параметры пользователя без внешнего соединения. Сам открывает/закрывает. */
public List<UserParamEntry> getByUserId(long loginId) throws SQLException {
try (Connection c = db.getConnection()) {
return getByUserId(c, loginId);
}
}
// -------------------- MAPPER --------------------
private UserParamEntry mapRow(ResultSet rs) throws SQLException { private UserParamEntry mapRow(ResultSet rs) throws SQLException {
return new UserParamEntry( return new UserParamEntry(
rs.getLong("loginId"), rs.getLong("loginId"),

View File

@ -0,0 +1,27 @@
DAO: правило перегруженных методов (короткая справка)
1) Всегда два метода:
insert(Connection c, …) // не закрывает соединение, не коммитит
insert(…) // открывает своё соединение и сам закрывает
2) Внутри одного бизнес-метода:
открываем одно соединение conn = db.getConnection();
делаем несколько DAO-вызовов через версии с Connection
в конце вручную conn.commit();
conn закрываем только один раз в finally
3) DAO-методы с Connection:
не создают соединение
не закрывают соединение
не делают commit/rollback
4) DAO-методы без Connection:
маленькие удобные обёртки
открывают соединение в try-with-resources
внутри вызывают версию с Connection
5) Итог:
одиночные операции → вызываем короткий метод без Connection
пакетные/атомарные операции → берём одно соединение и используем только методы с Connection