<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Servlet FreeMarker `JdbcTemplate`教程 - CRUD 操作 > 原文: [http://zetcode.com/articles/servletfreemarker/](http://zetcode.com/articles/servletfreemarker/) 在本教程中,我們將創建一個具有基本 CRUD 操作的簡單 Java Web 應用。 我們使用 FreeMarker 模板引擎,Servlet 技術和`JdbcTemplate`庫。 MySQL 用于存儲數據。 該應用最終部署在 Tomcat 服務器上。 該教程的資源可從作者的 Github [存儲庫](https://github.com/janbodnar/ServletFreemarkerJdbcTemplate)中獲得。 CRUD(創建,讀取,更新和刪除)是持久性存儲的四個基本功能。 對于關系數據庫,它們等效于`INSERT`,`SELECT`,`UPDATE`和`DELETE`語句。 FreeMarker 是 Java 編程語言的流行模板引擎。 模板以 FreeMarker 模板語言(FTL)編寫。 模板引擎將靜態數據與動態數據結合起來以生成內容。 模板是內容的中間表示。 它指定如何產生輸出。 `JDBCTemplate`是用于簡化 JDBC 編程的 Spring 庫。 它處理乏味且容易出錯的底層細節,例如處理事務,清理資源以及正確處理異常。 它包含在 Spring 的 spring-jdbc 模塊中。 ## 管理用戶 我們的應用將管理用戶。 它允許添加新用戶,對其進行修改,刪除它并列出所有可用用戶。 ```java mysql> CREATE TABLE Users(Id INTEGER PRIMARY KEY AUTO_INCREMENT, Firstname TEXT, Lastname TEXT, Email TEXT); ``` 我們在 MySQL `testdb`數據庫中創建`Users`表。 `Excerpt from pom.xml` ```java <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.2</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.25-incubating</version> </dependency> </dependencies> ``` 在 Maven `pom.xml`文件中,我們提供四個依賴項:`javaee-web-api`是用于開發 Java Web 應用的一組庫,`spring-jdbc`模塊包含 JDBCTemplate 庫,`mysql-connector-java`是 MySQL Java 驅動程序,而`freemarker`是 FreeMarker 庫。 `context.xml` ```java <?xml version="1.0" encoding="UTF-8"?> <Context path="/ServletFreemarkerEx"> <Resource name="jdbc/testdb" auth="Container" type="javax.sql.DataSource" username="user7" password="s$cret" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/testdb" maxActive="10" maxIdle="4"/> </Context> ``` 在`context.xml`文件中,我們定義了應用上下文路徑(其名稱)和一個 MySQL 數據源。 `web.xml` ```java <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <init-param> <param-name>TemplatePath</param-name> <param-value>/WEB-INF/template/</param-value> </init-param> <init-param> <param-name>NoCache</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>ResponseCharacterEncoding</param-name> <param-value>fromTemplate</param-value> </init-param> <init-param> <param-name>ExceptionOnMissingTemplate</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>incompatible_improvements</param-name> <param-value>2.3.25-incubating</param-value> </init-param> <init-param> <param-name>template_exception_handler</param-name> <param-value>html_debug</param-value> </init-param> <init-param> <param-name>template_update_delay</param-name> <param-value>0 s</param-value> </init-param> <init-param> <param-name>default_encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>output_encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>locale</param-name> <param-value>en_US</param-value> </init-param> <init-param> <param-name>number_format</param-name> <param-value>0.##########</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>FreeMarker MVC Views</web-resource-name> <url-pattern>*.ftl</url-pattern> </web-resource-collection> <auth-constraint> </auth-constraint> </security-constraint> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app> ``` 在`web.xml`文件中,我們設置了`FreemarkerServlet`,該文件用于處理 FreeMarker `.ftl`文件。 `User.java` ```java package com.zetcode.bean; public class User { private Long id; private String firstName; private String lastName; private String email; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } ``` 我們有一個`User` bean,其中包含四個屬性:`id`,`firstName`,`lastName`和`email`。 `ServiceLocator.java` ```java package com.zetcode.util; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; public class ServiceLocator { public static DataSource getDataSource(String jndiName) { Context ctx = null; DataSource ds = null; try { ctx = new InitialContext(); ds = (DataSource) ctx.lookup(jndiName); } catch (NamingException ex) { Logger.getLogger(ServiceLocator.class.getName()).log( Level.SEVERE, null, ex); } return ds; } } ``` `ServiceLocator`包含用于查找數據源的代碼。 它使用 JNDI API 來完成這項工作。 `DatabaseService.java` ```java package com.zetcode.service; import com.zetcode.bean.User; import com.zetcode.util.ServiceLocator; import java.util.List; import javax.sql.DataSource; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; public class DatabaseService { public static User getUserById(Long id) { String sql = "SELECT * FROM Users WHERE Id = ?"; JdbcTemplate jtm = getJDBCTempate(); User user = (User) jtm.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper(User.class)); return user; } public static void addUser(User user) { String sql = "INSERT INTO Users(Firstname, Lastname, Email) VALUES(?, ?, ?)"; JdbcTemplate jtm = getJDBCTempate(); jtm.update(sql, new Object[] {user.getFirstName(), user.getLastName(), user.getEmail()}); } public static void deleteUser(Long id) { String sql = "DELETE From Users WHERE Id = ?"; JdbcTemplate jtm = getJDBCTempate(); jtm.update(sql, new Object[] {id}); } public static void updateUser(User user) { String sql = "UPDATE Users SET Firstname=?, Lastname=?, Email=? WHERE Id=?"; JdbcTemplate jtm = getJDBCTempate(); jtm.update(sql, new Object[] {user.getFirstName(), user.getLastName(), user.getEmail(), user.getId()}); } public static List<User> getAllUsers() { String sql = "SELECT * FROM Users"; JdbcTemplate jtm = getJDBCTempate(); List<User> users = (List<User>) jtm.query(sql, new BeanPropertyRowMapper(User.class)); return users; } private static JdbcTemplate getJDBCTempate() { DataSource ds = ServiceLocator.getDataSource("java:comp/env/jdbc/testdb"); JdbcTemplate jtm = new JdbcTemplate(ds); return jtm; } } ``` 在`DatabaseService`中,我們有利用`JDBCTemplate`庫執行數據庫操作的方法。 ```java public static User getUserById(Long id) { String sql = "SELECT * FROM Users WHERE Id = ?"; JdbcTemplate jtm = getJDBCTempate(); User user = (User) jtm.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper(User.class)); return user; } ``` `getUserById()`方法返回由其 ID 標識的用戶。 `queryForObject()`運行指定的 SQL 語句并返回一個對象。 `BeanPropertyRowMapper`將返回的行轉換為目標類(用戶)。 ```java public static List<User> getAllUsers() { String sql = "SELECT * FROM Users"; JdbcTemplate jtm = getJDBCTempate(); List<User> users = (List<User>) jtm.query(sql, new BeanPropertyRowMapper(User.class)); return users; } ``` `getAllUsers()`方法返回表中的所有用戶。 `query()`方法返回類型列表。 `MyController.java` ```java package com.zetcode.web; import com.zetcode.bean.User; import com.zetcode.service.DatabaseService; import java.io.IOException; import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "MyController", urlPatterns = {"/MyController"}) public class MyController extends HttpServlet { private static final String ADD_USER_VIEW = "addUser.ftl"; private static final String UPDATE_USER_VIEW = "updateUser.ftl"; private static final String LIST_USERS_VIEW = "listUsers.ftl"; private static final String USER_ADDED_VIEW = "userAdded.html"; private static final String USER_DELETED_VIEW = "userDeleted.html"; private static final String USER_MODIFIED_VIEW = "userUpdated.html"; private static final String DELETE_ACTION = "deleteUser"; private static final String ADD_ACTION = "addUser"; private static final String UPDATE_ACTION = "updateUser"; private static final String LIST_ACTION = "listUsers"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String path = ""; String action = request.getParameter("action"); if (DELETE_ACTION.equals(action)) { Long userId = Long.parseLong(request.getParameter("userId")); DatabaseService.deleteUser(userId); path = USER_DELETED_VIEW; } else if (ADD_ACTION.equals(action)) { path = ADD_USER_VIEW; } else if (UPDATE_ACTION.equals(action)) { Long userId = Long.parseLong(request.getParameter("userId")); User user = DatabaseService.getUserById(userId); request.setAttribute("user", user); path = UPDATE_USER_VIEW; } else if (LIST_ACTION.equals(action)) { List<User> users = DatabaseService.getAllUsers(); request.setAttribute("users", users); path = LIST_USERS_VIEW; } RequestDispatcher dispatcher = request.getRequestDispatcher(path); dispatcher.forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = ""; response.setContentType("text/html;charset=UTF-8"); String action = request.getParameter("action"); if (ADD_ACTION.equals(action)) { User user = new User(); user.setFirstName(request.getParameter("firstName")); user.setLastName(request.getParameter("lastName")); user.setEmail(request.getParameter("email")); DatabaseService.addUser(user); path = USER_ADDED_VIEW; } else if (UPDATE_ACTION.equals(action)) { User user = new User(); user.setId(Long.parseLong(request.getParameter("id"))); user.setFirstName(request.getParameter("firstName")); user.setLastName(request.getParameter("lastName")); user.setEmail(request.getParameter("email")); DatabaseService.updateUser(user); path = USER_MODIFIED_VIEW; } response.sendRedirect(path); } } ``` `MyController`是一個控制器類,用于管理傳入的請求并委托給特定的服務方法。 我們有兩種方法:`doGet()`處理 HTTP GET 請求,`doPost()`處理 HTTP POST 請求。 ```java private static final String ADD_USER_VIEW = "addUser.ftl"; private static final String UPDATE_USER_VIEW = "updateUser.ftl"; private static final String LIST_USERS_VIEW = "listUsers.ftl"; ``` 這是三個 FreeMarker 模板視圖。 ```java private static final String USER_ADDED_VIEW = "userAdded.html"; private static final String USER_DELETED_VIEW = "userDeleted.html"; private static final String USER_MODIFIED_VIEW = "userUpdated.html"; ``` 在這里,我們有三個 HTML 視圖。 它們用于確認我們的任務。 ```java private static final String DELETE_ACTION = "deleteUser"; private static final String ADD_ACTION = "addUser"; private static final String UPDATE_ACTION = "updateUser"; private static final String LIST_ACTION = "listUsers"; ``` 我們有四個不同的操作:刪除用戶,添加新用戶,更新用戶以及列出所有用戶。 ```java if (DELETE_ACTION.equals(action)) { Long userId = Long.parseLong(request.getParameter("userId")); DatabaseService.deleteUser(userId); path = USER_DELETED_VIEW; } ``` 收到刪除操作后,我們從請求中找到 ID,然后調用`DatabaseService`的`deleteUser()`方法。 然后選擇一個視圖。 ```java } else if (UPDATE_ACTION.equals(action)) { Long userId = Long.parseLong(request.getParameter("userId")); User user = DatabaseService.getUserById(userId); request.setAttribute("user", user); path = UPDATE_USER_VIEW; } ``` 當我們單擊更新鏈接時,將執行此代碼。 從數據庫中檢索用戶,并將`User`對象添加到請求對象。 `UPDATE_USER_VIEW`將應用轉發到模板文件,該文件具有用于更新用戶的形式。 提交表單后,將 POST 請求發送到控制器,并執行其`doPost()`方法。 ```java } else if (LIST_ACTION.equals(action)) { List<User> users = DatabaseService.getAllUsers(); request.setAttribute("users", users); path = LIST_USERS_VIEW; } ``` 在這里,我們檢索所有用戶并將用戶列表設置為請求對象。 我們選擇`LIST_USERS_VIEW`視圖。 ```java response.sendRedirect(path); ``` 遵循發布/重定向/獲取模式,我們將重定向到`doPost()`方法中的視圖。 這樣可以防止提交多個表單。 (例如,我們可能不小心多次添加了一個用戶)。 `addUser.ftl` ```java <!DOCTYPE html> <html> <head> <title>Add new user</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <form action="MyController?action=addUser" method="post"> <label for="fname">First name:</label> <input id="fname" type="text" name="firstName"> <br> <label for="lname">Last name:</label> <input id="lname" type="text" name="lastName"> <br> <label for="email">Email:</label> <input id="email" type="text" name="email"> <br> <button type="submit">Submit</button> </form> </body> </html> ``` `addUser.ftl`是一個模板文件,其中包含用于添加新用戶的表單。 ```java <form action="MyController?action=addUser" method="post"> ``` 該表單調用`MyController` servlet,并將`action`參數設置為`addUser`。 `updateUser.ftl` ```java <!DOCTYPE html> <html> <head> <title>Update user</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> input[readonly] { background-color:lightGray; } </style> </head> <body> <form action="MyController?action=updateUser" method="post"> <label for="id">Id:</label> <input id="id" type="text" name="id" readonly value="${user.id}"> <br> <label for="fname">First name:</label> <input id="fname" type="text" name="firstName" value="${user.firstName}"> <br> <label for="lname">Last name:</label> <input id="lname" type="text" name="lastName" value="${user.lastName}"> <br> <label for="email">Email:</label> <input id="email" type="text" name="email" value="${user.email}"> <br> <button type="submit">Submit</button> </form> </body> </html> ``` `addUser.ftl`模板文件包含用于更新特定用戶的表單。 ```java <style> input[readonly] { background-color:lightGray; } </style> ``` 這種 CSS 樣式將淺色的只讀輸入標簽的背景繪制為灰色。 ```java <label for="id">Id:</label> <input id="id" type="text" name="id" readonly value="${user.id}"> <br> ``` ID 是一個只讀參數。 `${user.id}`是一個 FreeMarker 插值,可解析為用戶 ID。 在到達`updateUser.ftl`文件之前,該請求獲得一個將要修改的用戶對象。 `listUsers.ftl` ```java <!DOCTYPE html> <html> <head> <title>List users</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <table> <thead> <tr> <th>User Id</th> <th>First Name</th> <th>Last Name</th> <th>Email</th> <th colspan="2">Action</th> </tr> </thead> <tbody> <#list users as user> <tr> <td>${user.id}</td> <td>${user.firstName}</td> <td>${user.lastName}</td> <td>${user.email}</td> <td><a href="MyController?action=updateUser&userId=${user.id}">Update</a></td> <td><a href="MyController?action=deleteUser&userId=${user.id}">Delete</a></td> </tr> </#list> </tbody> </table> <p> <a href="MyController?action=addUser">Add new user</a> </p> </body> </html> ``` `listUsers.ftl`模板文件列出了`Users`數據庫表中的所有用戶。 ```java <#list users as user> ``` FreeMarker `#list`指令遍歷`users`集合的所有元素。 ```java <td>${user.id}</td> <td>${user.firstName}</td> <td>${user.lastName}</td> <td>${user.email}</td> ``` 這些 FreeMarker 插值顯示用戶數據。 ```java <td><a href="MyController?action=updateUser&userId=${user.id}">Update</a></td> ``` 該鏈接將更新操作發送到應用控制器; 它還發送要修改的用戶的 ID。 ```java <td><a href="MyController?action=deleteUser&userId=${user.id}">Delete</a></td> ``` 該鏈接將刪除操作發送到應用控制器。 它還發送要刪除的用戶的 ID。 ```java <a href="MyController?action=addUser">Add new user</a> ``` 該鏈接將添加用戶操作發送到控制器。 `index.html` ```java <!DOCTYPE html> <html> <head> <title>Main page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <a href="MyController?action=listUsers">List all users</a> </body> </html> ``` 這是一個帶有鏈接的主頁,該鏈接將列表用戶的操作發送到控制器。 `userAdded.html` ```java <!DOCTYPE html> <html> <head> <title>User added</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <p> New user has been added successfully. <a href="MyController?action=listUsers">List all users</a> </p> </body> </html> ``` 該視圖通知用戶已成功添加到數據庫表中。 `userDeleted.html` ```java <!DOCTYPE html> <html> <head> <title>User deleted</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <p> User has been successfully deleted. <a href="MyController?action=listUsers">List all users</a> </p> </body> </html> ``` 此視圖通知用戶刪除。 `userUpdated.html` ```java <!DOCTYPE html> <html> <head> <title>User modified</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <p> User has been modified successfully. <a href="MyController?action=listUsers">List all users</a> </p> </body> </html> ``` 該視圖通知用戶的修改。 ![Users web application](https://img.kancloud.cn/0a/f0/0af0980c1e371596883992e47e1f8710_654x368.jpg) 圖:用戶 Web 應用 在上面的屏幕截圖中,我們可以看到用戶列表。 該應用部署在 NetBeans 內置的 Tomcat 服務器上,該服務器正在監聽端口 8084。 在本教程中,我們創建了一個執行 CRUD 操作的 Java Web 應用。 它使用了 FreeMarker,Servlet 和`JDBCTemplate`。 您可能也對相關教程感興趣: [`JdbcTemplate`教程](/db/jdbctemplate/), [FreeMarker 教程](/java/freemarker/), [Java 教程](/lang/java/),[游戲入門](/java/play/), [Spark 簡介](/java/spark/)或 [Strips 簡介](/java/stripes/)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看