[JSP 頁面] → [Servlet/Controller] → [Service] → [DAO] → [連接池] → [MySQL]
// HikariCP (推薦) 或 Druid
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/dbname?useSSL=false&serverTimezone=UTC");
config.setUsername("user");
config.setPassword("pass");
config.setMaximumPoolSize(20);
DataSource ds = new HikariDataSource(config);
public abstract class BaseDAO {
protected DataSource dataSource;
protected Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
// 通用查詢模板
protected List query(String sql, RowMapper mapper, Object... params) {
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
setParams(ps, params);
try (ResultSet rs = ps.executeQuery()) {
List list = new ArrayList<>();
while (rs.next()) list.add(mapper.mapRow(rs));
return list;
}
}
}
}
public class UserDAO extends BaseDAO {
public List findAll() {
return query("SELECT * FROM users", rs -> new User(
rs.getLong("id"),
rs.getString("username"),
rs.getString("email")
));
}
}
@Service
public class UserService {
@Autowired UserDAO userDAO;
public List getUsers() {
return userDAO.findAll(); // 可加事務、緩存、業務邏輯
}
}
@Controller
public class UserController {
@Autowired UserService userService;
@GetMapping("/users")
public String list(Model model) {
model.addAttribute("users", userService.getUsers());
return "user/list"; // 對應 /WEB-INF/jsp/user/list.jsp
}
}
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<table>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.email}</td>
</tr>
</c:forEach>
</table>
public void generateStaticPage() throws Exception {
// 1. 獲取數據
List users = userService.getUsers();
// 2. 渲染模板 (可用 Velocity, Freemarker, Thymeleaf, 或簡單 StringBuilder)
String html = renderTemplate("user_list.ftl", Map.of("users", users));
// 3. 寫入文件
Files.write(Paths.get("/var/www/html/users.html"), html.getBytes(StandardCharsets.UTF_8));
}
private String renderTemplate(String template, Map model) {
// Freemarker 示例
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setClassForTemplateLoading(this.getClass(), "/templates");
Template temp = cfg.getTemplate(template);
StringWriter out = new StringWriter();
temp.process(model, out);
return out.toString();
}
| 層面 | 建議 |
|---|---|
| 連接管理 | 必須用連接池,禁用 DriverManager 直連 |
| SQL 注入 | 全程 PreparedStatement + 參數綁定 |
| 資源關閉 | try-with-resources 自動關閉 Conn/Stmt/RS |
| 異常處理 | DAO 拋 SQLException,Service 包裝為業務異常 |
| 事務控制 | @Transactional 在 Service 層 |
Java 訪問 MySQL 標準路徑:連接池 → DAO → Service → Controller → JSP(EL)。生成靜態文件用模板引擎渲染後 IO 寫入。切記分層解耦,避免在 JSP 中直寫 JDBC 代碼。