NullPointerException が出る典型的なケース
DAO 層で Connection を取得した直後に Statement を生成しようとした際、conn.createStatement() の呼び出しで NPE が発生することがあります。
Connection conn = DataSourceFactory.getConnection(); // ここで null が返ると…
PreparedStatement ps = conn.prepareStatement(sql); // ここで例外
原因は DataSourceFactory#getConnection() が null を返したことです。コネクション取得メソッドが必ず非 null を返すようにするか、事前にチェックしてください。
頻出 SQL パターン
INSERT
String insert = "INSERT INTO user_account(username, password_hash, role) VALUES (?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(insert);
ps.setString(1, form.getUsername());
ps.setString(2, PasswordUtil.hash(form.getPassword()));
ps.setInt(3, form.getRole());
ps.executeUpdate();
SELECT(部分一致検索)
String fuzzy = "SELECT * FROM student WHERE class_name LIKE ?";
PreparedStatement ps = conn.prepareStatement(fuzzy);
ps.setString(1, "%" + keyword + "%");
SELECT(全件取得)
String all = "SELECT id, name, age FROM tb_qingnian";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(all);
UPDATE
String update = "UPDATE tb_qingnian SET sex=?, appearance=?, service_type=? WHERE name=?";
PreparedStatement ps = conn.prepareStatement(update);
ps.setString(1, entity.getSex());
ps.setString(2, entity.getAppearance());
ps.setString(3, entity.getServiceType());
ps.setString(4, entity.getName());
ps.executeUpdate();
DELETE
String delete = "DELETE FROM tb_qingnian WHERE name=?";
PreparedStatement ps = conn.prepareStatement(delete);
ps.setString(1, targetName);
ps.executeUpdate();
動的 WHERE 句の組み立て例
JSP でプルダウンで選択された項目を基に検索する場合の実装例です。
JSP
<select name="searchField">
<option value="category">カテゴリ</option>
<option value="amount">金額</option>
<option value="location">場所</option>
<option value="date">日付</option>
</select>
<input type="text" name="searchValue" />
Servlet
String field = req.getParameter("searchField");
String value = req.getParameter("searchValue");
List<Expense> list = ExpenseDao.findBy(field, value);
DAO
public static List<Expense> findBy(String column, String value) throws SQLException {
String sql = "SELECT * FROM expense WHERE " + column + " = ?";
try (Connection conn = DataSourceFactory.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, value);
ResultSet rs = ps.executeQuery();
List<Expense> result = new ArrayList<>();
while (rs.next()) {
result.add(new Expense(
rs.getString("category"),
rs.getBigDecimal("amount"),
rs.getString("location"),
rs.getDate("date")
));
}
return result;
}
}
Navicat Premium での「仮想」チェックボックスの注意点
テーブル設計画面で「仮想(Virtual)」にチェックを入れると、MySQL 8 の Generated Column が作成されます。この列は実際にはデータを格納せず、他の列から計算される値のみを保持するため、外部キーやインデックスを設定できないなどの制限が生じます。意図しない仮想列を作らないよう注意してください。