✅✅作者主页:🔗孙不坚1208的博客
🔥🔥精选专栏:🔗JavaWeb从入门到精通(持续更新中)
📋📋 本文摘要:本篇文章主要分享JavaWeb的学习重点内容。💞💞觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论💬支持博主🤞
👉 👉你的一键三连是我更新的最大动力❤️❤️
JavaWeb复习重点
javaweb期末题型有2大类:问答题、编程题
一、问答题7个左右,共40分
1.Servlet的定义、配置(使用xml或注解)
Servlet是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。
Servlet的配置有xml和注解两种方式
xml方式:
<servlet><servlet-name>demoservlet-name> <servlet-class>web.servlet.ServletDemoservlet-class>servlet> <servlet-mapping> <servlet-name>demoservlet-name> <url-pattern>/indexurl-pattern>servlet-mapping>
注解方式:在类上使用注解@WebServlet注解配置
@WebServlet("/demo")public class ServletDemo implements Servlet { // 实现Servlet接口}
2.重定向与请求转发的区别,使用API完成重定向和转发
重定向(Redirect)和请求转发(Forward)是两种不同的HTTP请求处理机制。
重定向是在接收到请求后,服务器向客户端返回一个特殊的响应,指示客户端重新向指定的url发送请求,这个过程是完全由客户端完成的,客户端会发送一个新的请求到指定的url,并接收新的响应。重定向经常被用来处理资源的移动,url的更改,或者是需要访问其他网站的情况。
请求转发则是在服务器端将请求转发给另一个资源进行处理,这个过程是在服务器内部完成的。客户端发送请求到服务器,服务器会将请求转发到另一个资源进行处理,然后将处理结果返回给客户端。请求转发经常被用来组合多个资源进行处理,例如在JSP中使用include指令将多个JSP页面组合在一起。
重定向:
response.sendRedirect("http://www.example.com");
转发:
RequestDispatcher dispatcher = request.getRequestDispatcher("/example.jsp");dispatcher.forward(request, response);
在以上示例代码中,response
和request
是javax.servlet.http.HttpServletResponse
和javax.servlet.http.HttpServletRequest
的实例对象。重定向通过调用sendRedirect()
方法并传入要重定向到的URL字符串来实现。请求转发则通过创建一个RequestDispatcher
对象,该对象通过getRequestDispatcher()
方法获取,并传入要转发到的资源的路径,然后调用forward()
方法来实现。在请求转发中,request
和response
对象被传递给了要转发到的资源。
需要注意的是,重定向会向客户端发送一个新的请求,因此客户端的URL会发生改变,而请求转发是在服务器内部完成的,客户端的URL不会改变。
3.重定向与请求转发的优缺点
重定向的优点:
- 简单易用:使用
response.sendRedirect()
方法非常简单,可以很容易地将客户端重定向到其他URL。 - 安全性高:重定向会向客户端发送一个新的请求,因此客户端的URL会发生改变,可以避免某些安全漏洞,比如在表单提交后刷新页面导致的重复提交等。
重定向的缺点:
- 频繁网络请求:重定向会向客户端发送一个新的请求,会导致网络请求的增加,影响性能。
- 无法访问原始请求对象:重定向会生成一个新的请求对象,因此无法访问原始请求对象,如原始的HTTP请求头等。
请求转发的优点:
- 性能高:请求转发是在服务器内部完成的,不会向客户端发送新的请求,因此不会增加网络请求,性能比较高。
- 可以访问原始请求对象:请求转发可以访问原始请求对象,如原始的HTTP请求头等。
请求转发的缺点:
- 不适用于跨域请求:由于请求转发只能转发到同一Web应用程序中的资源,因此不能用于跨域请求。
- 不支持修改URL:请求转发是在服务器内部完成的,客户端无法感知,也无法修改URL。
4.给出了Servlet的代码实现,让大家用JSP来实现该功能
这个参考课本
使用JSP实现重定向和请求转发的示例代码:
重定向:
<% response.sendRedirect("http://www.example.com");%>
请求转发:
jsp转换如下
<%if(session.getAttribute("user")) == null { User user = new new User(); session.getAttribute("user",user); }%>
5.JavaBean的规范,应该详细掌握
JavaBean是一种符合Java语言规范的特殊类,通常用于存储和操作数据。JavaBean类应该遵循以下规范:
- 应该提供一个无参的构造方法:JavaBean的构造方法应该是无参的,这样可以方便地在其他类中创建JavaBean的实例。无参构造方法可以通过手动编写或者使用编译器自动生成的方式实现。
- 所有属性应该私有化:JavaBean的属性应该使用private修饰符进行私有化,通过提供公共的getter和setter方法来访问属性。
- getter和setter方法的命名应该符合JavaBean命名规范:JavaBean的getter和setter方法应该遵循一定的命名规范。getter方法的名称应该以“get”开头,setter方法的名称应该以“set”开头,后面跟着属性名的首字母大写的形式。
- 应该提供默认的toString方法:JavaBean应该提供一个默认的toString方法,以便在调试和日志记录时方便查看JavaBean的属性值。
- 应该提供其他有用的方法:除了getter和setter方法以外,JavaBean还可以提供一些其他的有用方法,例如校验方法、计算方法等。
6.给出了Servlet的代码实现,让大家用JSTL来实现该功能
这个参考课本
JSTL(JavaServer Pages Standard Tag Library)是一个标准的JSP标签库,提供了一些常用的标签,可以方便地实现一些常见的操作,包括重定向和转发。以下是使用JSTL实现重定向和转发的示例代码:
重定向:
以上代码中,
标签用于实现重定向,url
属性指定要重定向到的URL字符串。
请求转发:
以上代码中,
标签用于实现请求转发,page
属性指定要转发到的JSP页面的路径。
7.过滤器的概念,写出一个过滤器类
过滤器(Filter)是Java Web应用程序中的一个重要组件,可以拦截客户端请求和服务器响应,对它们进行预处理和后处理,实现一些通用的功能,例如日志记录、权限控制、字符编码转换等。
一个过滤器类必须实现javax.servlet.Filter
接口,并重写其中的doFilter()
方法。以下是一个简单的过滤器类的示例代码,实现了字符编码转换的功能:
import javax.servlet.*;import java.io.IOException;@WebFilter(filterName = "CharacterEncodingFilter", urlPatterns = "/*")public class CharacterEncodingFilter implements Filter { private String encoding; public void init(FilterConfig config) throws ServletException { // 读取初始化参数,设置字符编码 encoding = config.getInitParameter("encoding"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 设置请求和响应的字符编码 request.setCharacterEncoding(encoding); response.setCharacterEncoding(encoding); // 调用后续的过滤器或Servlet/JSP处理请求 chain.doFilter(request, response); } public void destroy() { // 释放资源 }}
以上代码中,使用@WebFilter
注解配置了过滤器的名称和URL模式。filterName
属性指定过滤器的名称,urlPatterns
属性指定需要过滤的URL模式。在此示例中,过滤器会拦截所有的请求。
以上代码中,CharacterEncodingFilter
类实现了javax.servlet.Filter
接口,并重写了其中的init()
、doFilter()
和destroy()
方法。init()
方法在过滤器初始化时被调用,读取初始化参数并设置字符编码;doFilter()
方法用于实现过滤功能,设置请求和响应的字符编码,并调用后续的过滤器或Servlet/JSP处理请求;destroy()
方法在过滤器销毁时被调用,释放资源。
需要注意的是,过滤器配置除了注解的这种方式也可以在Web应用程序的web.xml
文件中,通过过滤器链(Filter Chain)的方式实现多个过滤器的协同工作。过滤器的顺序可以通过
元素中的
子元素来指定。
8.JPA中实体类、以及实体关系映射,一对一、一对多
在 JPA 中,实体类是指映射到数据库表的 Java 类。实体类通常具有以下特点:
- 实体类使用
@Entity
注解进行标记。 - 实体类的每个实例对应数据库表中的一行数据。
- 实体类的属性对应数据库表中的列。
JPA 中的实体关系映射用于描述实体类之间的关联关系,包括一对一、一对多、多对一和多对多关系。其中,一对一和一对多是较为常见的关系类型。
一对一关系映射示例:
@Entitypublic class Person { @Id private Long id; private String name; @OneToOne(cascade = CascadeType.ALL) private Address address;}@Entitypublic class Address { @Id private Long id; private String street; private String city; private String country; @OneToOne(mappedBy = "address") private Person person;}
上述代码中,Person
和 Address
分别是两个实体类。它们之间的关系是一对一,通过 @OneToOne
注解进行映射。Person
实体类中的 address
属性使用 @OneToOne
注解,表示它与 Address
实体类是一对一关系。Address
实体类中的 person
属性也使用了 @OneToOne
注解,但是它的 mappedBy
属性指向了 Person
实体类的 address
属性,表示这是一个双向关联,并且由 Person
实体类来维护关系。
一对多关系映射示例:
@Entitypublic class Department { @Id private Long id; private String name; @OneToMany(mappedBy = "department", cascade = CascadeType.ALL) private List<Employee> employees;}@Entitypublic class Employee { @Id private Long id; private String name; private String email; @ManyToOne private Department department;}
上述代码中,Department
和 Employee
分别是两个实体类。它们之间的关系是一对多,通过 @OneToMany
和 @ManyToOne
注解进行映射。Department
实体类中的 employees
属性使用了 @OneToMany
注解,表示它与 Employee
实体类是一对多关系。Employee
实体类中的 department
属性使用了 @ManyToOne
注解,表示它与 Department
实体类是多对一关系,并且它的 department
属性指向了 Department
实体类的 employees
属性,表示这是一个双向关联,并且由 Department
实体类来维护关系。
需要注意的是,上述示例中使用了 JPA 中的级联操作(CascadeType.ALL
),表示当父实体被删除时,子实体也将被删除。这种级联操作可能会对数据产生不可逆的影响,因此需要谨慎使用。
9.Spring控制器的类的编写、路径的配置、注入组件、返回Json数据
在 Spring 中,控制器是指负责处理请求和响应的组件,通常由一个 Java 类实现。以下是 Spring 控制器类的编写、路径配置、注入组件和返回 JSON 数据的示例:
@Controller@RequestMapping("/api/users")public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") @ResponseBody public User getUserById(@PathVariable Long id) { return userService.getUserById(id); } @PostMapping("/") @ResponseBody public User createUser(@RequestBody User user) { return userService.createUser(user); } @PutMapping("/{id}") @ResponseBody public User updateUser(@PathVariable Long id, @RequestBody User user) { return userService.updateUser(id, user); } @DeleteMapping("/{id}") @ResponseBody public void deleteUser(@PathVariable Long id) { userService.deleteUser(id); } }
在上述示例中,我们定义了一个名为 UserController
的控制器类,并使用 @Controller
注解标记它。@RequestMapping
注解用于配置控制器类的路径前缀,即 /api/users
。这意味着,当请求的路径以 /api/users
开头时,Spring 将会把请求交给该控制器类来处理。
在控制器类中,我们使用了 @Autowired
注解来自动注入一个名为 userService
的组件。这里假设 UserService
是一个已经定义好的服务组件,可以使用 @Service
注解标记它。
控制器类中的方法使用了不同的 HTTP 方法注解,包括 @GetMapping
、@PostMapping
、@PutMapping
和 @DeleteMapping
,用于定义请求的 HTTP 方法类型。这些注解后面跟随的路径参数用于定义具体的请求路径。例如,@GetMapping("/{id}")
表示可以处理 /api/users/{id}
这样的 GET 请求。
在方法中,我们使用了 @ResponseBody
注解来表示将方法的返回值直接作为响应内容返回给客户端。这里,我们返回的是一个 User 类型的对象,Spring 会将它自动转换为 JSON 格式并返回给客户端。需要注意的是,为了能够让 Spring 自动完成 JSON 转换,我们需要在项目中引入相应的 JSON 库,例如 Jackson。
总的来说,Spring 控制器类提供了方便的方式来处理 HTTP 请求和响应,可以通过注解配置路径和 HTTP 方法,并且支持自动注入组件和返回 JSON 数据等常用功能。
二、编程题4个题,共60分
1.题目给出了数据库、表等信息,要求使用JDBC完成增删改查这些操作,可能需要事务
使用 JDBC 完成增删改查操作通常需要以下步骤:
- 加载数据库驱动。
- 建立数据库连接。
- 创建 Statement 或 PreparedStatement 对象。
- 执行 SQL 语句。
- 处理查询结果。
- 释放资源。
以下是一个使用 JDBC 实现增删改查操作的示例:
public class UserDao { private Connection conn; public UserDao(Connection conn) { this.conn = conn; } public void createUser(User user) throws SQLException { String sql = "INSERT INTO users(name, email, password) VALUES (?, ?, ?)"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, user.getName()); stmt.setString(2, user.getEmail()); stmt.setString(3, user.getPassword()); stmt.executeUpdate(); stmt.close(); } public void updateUser(User user) throws SQLException { String sql = "UPDATE users SET name=?, email=?, password=? WHERE id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, user.getName()); stmt.setString(2, user.getEmail()); stmt.setString(3, user.getPassword()); stmt.setLong(4, user.getId()); stmt.executeUpdate(); stmt.close(); } public void deleteUser(long id) throws SQLException { String sql = "DELETE FROM users WHERE id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setLong(1, id); stmt.executeUpdate(); stmt.close(); } public User getUserById(long id) throws SQLException { String sql = "SELECT id, name, email, password FROM users WHERE id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setLong(1, id); ResultSet rs = stmt.executeQuery(); User user = null; if (rs.next()) { user = new User(); user.setId(rs.getLong("id")); user.setName(rs.getString("name")); user.setEmail(rs.getString("email")); user.setPassword(rs.getString("password")); } rs.close(); stmt.close(); return user; } }
上述代码中,我们定义了一个 UserDao
类,用于操作名为 users
的数据库表。其中的四个方法分别实现了创建用户、更新用户、删除用户和根据用户 ID 查询用户的功能。在这些方法中,我们使用了 PreparedStatement
对象来执行 SQL 语句,并通过设置占位符的方式传递参数。通过这种方式,可以有效避免 SQL 注入等安全问题。
如果需要使用事务,可以将上述方法放到一个事务中执行。以下是一个示例:
public void createUserWithTransaction(User user) throws SQLException { conn.setAutoCommit(false); try { createUser(user); conn.commit(); } catch (SQLException e) { conn.rollback(); throw e; } finally { conn.setAutoCommit(true); }}
在这个方法中,我们通过将 autoCommit
属性设置为 false
,来启用手动事务。在执行完所有操作后,我们可以选择提交或回滚事务。同时,为了保证代码的健壮性,需要在 finally
块中将 autoCommit
属性设置回 true
。
2.编写Servlet接收请求参数,并保存到某个作用域
@WebServlet("/example")public class ExampleServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String email = request.getParameter("email"); String password = request.getParameter("password"); // 将参数保存到 session 作用域 HttpSession session = request.getSession(); session.setAttribute("name", name); session.setAttribute("email", email); session.setAttribute("password", password); // 将参数保存到 request 作用域 request.setAttribute("name", name); request.setAttribute("email", email); request.setAttribute("password", password); // 将参数保存到 application 作用域 ServletContext context = getServletContext(); context.setAttribute("name", name); context.setAttribute("email", email); context.setAttribute("password", password); // 重定向到结果页面 response.sendRedirect(request.getContextPath() + "/result.jsp"); }}
在上述代码中,我们在 doPost
方法中,分别将参数保存到 session、request 或 application 作用域中。在 session
中保存参数的方式与之前的示例类似,使用 request.getSession()
方法获取 HttpSession
对象,并调用其 setAttribute
方法将参数保存到 session 作用域中。
在 request
作用域中保存参数的方式也很类似,只需要使用 request.setAttribute
方法将参数保存到 request 作用域中即可。
在 application
作用域中保存参数也非常简单,只需要使用 getServletContext()
方法获取 ServletContext
对象,并调用其 setAttribute
方法将参数保存到 application 作用域中即可。
需要注意的是,在将参数保存到不同作用域中时,需要使用不同的对象来调用 setAttribute
方法。除此之外,其他代码与之前的示例相同,最终通过 response.sendRedirect
方法重定向到结果页面。
3.JPA的编程题,题目给出数据库和表,让大家使用JPA完成实体类及使用EntityManager完成增删改查操作
假设有一个表名为 user
,包含以下字段:
Field | Type |
---|---|
id | INT |
name | VARCHAR(100) |
age | INT |
VARCHAR(100) | |
password | VARCHAR(100) |
接下来,我们需要使用 JPA 完成实体类及使用 EntityManager
完成增删改查操作。
首先,我们需要定义一个实体类 User
,对应 user
表中的一条记录:
@Entity@Table(name = "user")public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private Integer age; private String email; private String password; // getters and setters}
在上述代码中,我们使用 @Entity
注解表示这是一个实体类,使用 @Table
注解指定了实体对应的表名为 user
。同时,我们在类中定义了实体对应的属性,并使用 @Id
和 @GeneratedValue
注解表示该属性为实体的唯一标识,并指定了该属性的生成策略为自增长。
接下来,我们可以使用 EntityManager
对实体进行增删改查操作。以下是一个示例:
public class UserDao { @PersistenceContext private EntityManager entityManager; // 添加用户 public void addUser(User user) { entityManager.persist(user); } // 根据 id 查询用户 public User getUserById(Integer id) { return entityManager.find(User.class, id); } // 更新用户信息 public void updateUser(User user) { entityManager.merge(user); } // 根据 id 删除用户 public void deleteUserById(Integer id) { User user = entityManager.find(User.class, id); entityManager.remove(user); }}
在上述代码中,我们使用 @PersistenceContext
注解将 EntityManager
注入到 UserDao
类中。接着,我们定义了几个方法,分别用于添加、查询、更新和删除用户。
在 addUser
方法中,我们使用 EntityManager
的 persist
方法将用户对象保存到数据库中。
在 getUserById
方法中,我们使用 EntityManager
的 find
方法根据用户的唯一标识 id
查询用户信息,并将查询结果返回。
在 updateUser
方法中,我们使用 EntityManager
的 merge
方法将修改后的用户对象保存到数据库中。
在 deleteUserById
方法中,我们使用 EntityManager
的 remove
方法将根据用户的唯一标识 id
查询到的用户对象从数据库中删除。
需要注意的是,为了使用 EntityManager
,我们需要将 JPA 的实现框架(如 Hibernate)配置到项目中,并在 persistence.xml
配置文件中配置数据源等信息。
4.JSP+Servet+JavaBean开发模式完成系统功能
JSP + Servlet + JavaBean 开发模式是一种经典的 Web 开发模式,它的核心是将前端页面(JSP)与后端业务逻辑(JavaBean)分离开来,通过 Servlet 充当中间层,完成两者之间的交互和协作。
以下是一个简单的示例:
首先,创建一个JavaBean来表示系统中的一个实体。例如,我们创建一个名为User的JavaBean来表示系统中的用户:
public class User { private String username; private String password; // getter and setter methods}
接下来,创建一个Servlet来处理用户提交的数据。例如,我们创建一个名为LoginServlet的Servlet来处理用户登录请求:
@WebServlet("/login")public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); User user = new User(); user.setUsername(username); user.setPassword(password); // 将User对象保存到Session作用域中 request.getSession().setAttribute("user", user); // 转发到登录成功页面 request.getRequestDispatcher("/success.jsp").forward(request, response); }}
在Servlet中,我们首先获取用户提交的用户名和密码,然后创建一个User对象,并将其保存到Session作用域中。最后,我们使用请求转发将用户重定向到登录成功页面。
在Servlet中,我们首先获取用户提交的用户名和密码,然后创建一个User对象,并将其保存到Session作用域中。最后,我们使用请求转发将用户重定向到登录成功页面。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>登录成功
在JSP页面中,我们使用EL表达式来显示用户登录成功后的信息,例如用户的用户名。
最后,我们可以在Web应用程序中部署和运行这个示例,访问/login路径,提交用户名和密码,然后会被重定向到success.jsp页面,页面中显示登录成功后的信息。
这就是使用JSP+Servlet+JavaBean开发模式完成系统功能的基本流程。开发人员可以根据具体的业务需求进行修改和扩展。
三、附加一些常用配置
1.JDBC-DBConnection
package com.sun.util;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class DBConnection {private static final String driverName = "com.mysql.cj.jdbc.Driver";private static final String url = "jdbc:mysql://localhost:3306/testdb?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true";private static final String user = "root";private static final String password = "sm1208";private DBConnection() {}static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}public static void close(ResultSet rs, Statement st, Connection conn) {try {if (rs != null) {rs.close();}} catch (SQLException e) {e.printStackTrace();} finally {try {if (st != null) {st.close();}} catch (SQLException e) {e.printStackTrace();} finally {if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}}}
2.直接连接方式
try { //1.数据库连接的4个基本要素: String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "sm1208"; String driverName = "com.mysql.cj.jdbc.Driver"; //2.加载驱动 Class.forName(driverName); //3.获取连接 Connection conn = DriverManager.getConnection(url, user, password);} catch (Exception e) { e.printStackTrace();}
3.JDBC-CRUD
创建类StudentCRUD实现对student表的CRUD操作(使用DBConnection类):该类具有main()方法和使用PreparedStatement实现增加记录的方法add()、实现查询全部记录的方法listAll()、实现根据id更新数据的方法update()、实现根据id删除记录的方法delete()。
add()public static boolean add(String name, int age, String hobby)throws SQLException{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;boolean successflag = false;try {conn = DBConnection.getConnection();String sql = "insert into student values(null,?,?,?)";// 预编译SQL语句,得到PrepareStatement对象 ps = conn.prepareStatement(sql); // 填充占位符 ps.setObject(1,name); ps.setObject(2,age); ps.setObject(3,hobby); ps.execute();} finally {// 关闭资源对象DBConnection.close(rs, ps, conn);successflag = true;}return successflag;} listAll()public static List<Student> listAll()throws SQLException{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;List<Student> list = new ArrayList<Student>();try {conn = DBConnection.getConnection();String sql = "select * from student";ps = conn.prepareStatement(sql);// 执行executeQuery(),得到结果集:ResultSetrs = ps.executeQuery();// 通过ResultSet得到列值while (rs.next()) { list.add(new Student(rs.getInt(1),rs.getString(2),rs.getInt(3),rs.getString(4)));}} finally {DBConnection.close(rs, ps, conn);}return list;}update()public static boolean update(Student student)throws SQLException{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;boolean successflag = false; try {conn = DBConnection.getConnection();String sql = "update student set name = ?,age = ?,hobby = ? where studentId = ?";ps = conn.prepareStatement(sql);ps.setObject(1, student.getName());ps.setObject(2, student.getAge());ps.setObject(3, student.getHobby());ps.setObject(4, student.getStudentId());ps.execute();} finally {DBConnection.close(rs, ps, conn);successflag = true;}return successflag;}delete()public static boolean delete(int id)throws SQLException{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;boolean successflag = false; try {conn = DBConnection.getConnection();String sql = "delete from student where studentId = ?";ps = conn.prepareStatement(sql);ps.setObject(1, id);ps.execute();} finally {DBConnection.close(rs, ps, conn);successflag = true;}return successflag;}
在数据库testDB中创建存储过程,名为getSnameAndClassBySno,其可以通过学号查询学生的姓名和班级信息。
create procedure getSnameAndClassBySno(in id VARCHAR(25))BEGINSELECT * FROM student WHERE studentId=id;ENDCALL getSnameAndClassBySno(1);
在类StudentCRUD中定义方法,调用存储过程getSnameAndClassBySno。
// 调用存储过程public static Student getStudentByid(int id)throws SQLException{Connection conn = null;CallableStatement cs = null;ResultSet rs = null;Student stu = null;try {conn = DBConnection.getConnection();String sql = "CALL getSnameAndClassBySno(?);";cs = (CallableStatement) conn.prepareCall(sql);cs.setInt(1, id);// 执行execute()cs.execute();// 存储过程结果集rs = cs.getResultSet();if(rs.next()) {stu = new Student(rs.getInt(1),rs.getString(2),rs.getInt(3),rs.getString(4));}} finally {try {if (rs != null) {rs.close();}} catch (SQLException e) { e.printStackTrace();} finally {try {if (cs != null) {cs.close();}} catch (SQLException e) { e.printStackTrace();} finally {if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}}return stu;}
创建TransactionTest类,使用JDBC事务管理实现用户转账功能。(注意,user表需要有float类型的字段money,并存在用于测试的2条用户记录)
// 使用JDBC事务管理实现用户转账功能public class TransactionTest {public static void main(String args[]) throws SQLException {transferAccounts(1,2,1000);}// 实现id1向id2转账money元public static boolean transferAccounts(int id1,int id2,float money)throws SQLException{Connection conn = null;PreparedStatement ps1 = null;PreparedStatement ps2=null;ResultSet rs = null;boolean successflag = false;try {conn = DBConnection.getConnection();conn.setAutoCommit(false);//开启事务// id1 扣钱String sql1 = "update user set money = money - ? where userId = ?"; ps1 = conn.prepareStatement(sql1); ps1.setObject(1,money); ps1.setObject(2,id1); ps1.executeUpdate(); // 程序出问题了 // int i = 10 / 0 ; // id2 加钱 String sql2 = "update user set money = money + ? where userId = ?"; ps2 = conn.prepareStatement(sql2); ps2.setObject(1,money); ps2.setObject(2,id2); ps2.executeUpdate(); conn.commit();//提交事务} finally {DBConnection.close(rs, ps, conn);successflag = true;}return successflag;} }
4. Session 校验 (用户登录)
// 方式一: <% String username=(String)(session.getAttribute("username")); if(username==null || username.equals("")){ response.sendRedirect("index.jsp"); } %> // 方式二: <%@ include file="/LoginCheck.jsp" %> <% request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); String path=request.getContextPath();//部署的应用程序名"/www" %> <% String username=user.getUsername(); if(username==null || username.equals("")){ response.sendRedirect(path+"/index.jsp"); } %>
5.JPA
User实体类
@Entitypublic class User { @Id private int id; private String name; private String password; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } // get set}
userDao
import entity.User;public interface UserDao {public void add( String name, String password,int age); public void delete(int id); public void update(User user); public User get(int id);}
userDaoImplement
import javax.persistence.EntityManager;public class UserDaoImpl implements UserDao{EntityManagerFactory factory;EntityManager em;public UserDaoImpl() { factory = Persistence.createEntityManagerFactory(persistenceUnitName); em = factory .createEntityManager();}public void add( String name ,String password,int age) {User user = new User();user.setName( name) ;user. setAge( age);user.setPassword(password); em.getTransaction( ).begin(); em.persist(user) ; em.getTransaction().commit(); } public void delete(int id) {em.getTransaction().begin();User user = em.find(User.class, id); if (user != null) {em. remove(user);}em.getTransaction( ).commit();}public User get(int id) {User user = em.find(User.class,id); return user;}public void update(User user) { em.getTransaction( ).begin(); User user2= em.merge(user); em.getTransaction( ).commit(); }}
6.JavaBean
package com.sun.bean;import com.sun.util.DBConnection;import com.sun.util.Date_String;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class UserBean {private int userid;private String username;private String password;private String sex;private int age;private String birthday;public int getUserid() {return userid;}public void setUserid(int userid) {this.userid = userid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getBirthday() {return birthday;}public void setBirthday(String birthday) {this.birthday = birthday;}// 验证用户登录信息public boolean validlogin()throws SQLException{Connection conn = null;Statement st = null;ResultSet rs = null;boolean successflag=false;try {conn = DBConnection.getConnection();String sql = "select * from user where name='"+this.username+"' and password='"+this.password+"'";st = conn.createStatement();rs=st.executeQuery(sql);if(rs.next()==true) {successflag=true;}} finally {DBConnection.close(rs, st, conn);}return successflag;}public List<UserBean> getUsersPage()throws SQLException{List<UserBean> users=new ArrayList<UserBean>();Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = DBConnection.getConnection();String sql = "select * from user limit 0,3";st = conn.createStatement();rs=st.executeQuery(sql);while(rs.next()==true){UserBean tmp=new UserBean();tmp.setUserid(rs.getInt("id"));tmp.setUsername(rs.getString("name"));tmp.setPassword(rs.getString("password"));tmp.setSex(rs.getString("sex"));tmp.setAge(rs.getInt("age"));String birthday= Date_String.getStringDate1(rs.getDate("birthday"));tmp.setBirthday(birthday);users.add(tmp);}} finally {DBConnection.close(rs, st, conn);}return users;}// 条件查询 没用到public List<UserBean> getUsers(String username, String sex)throws SQLException{if(username==null) username="";if(sex==null) sex="";List<UserBean> users=new ArrayList<UserBean>();Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = DBConnection.getConnection();String sql = "select * from user where name like '%"+username+"%' and ifnull(sex,'') like '%"+sex+"%'";st = conn.createStatement();rs=st.executeQuery(sql);while(rs.next()==true){UserBean tmp=new UserBean();tmp.setUserid(rs.getInt("id"));tmp.setUsername(rs.getString("name"));tmp.setPassword(rs.getString("password"));tmp.setSex(rs.getString("sex"));String birthday=Date_String.getStringDate1(rs.getDate("birthday"));tmp.setBirthday(birthday);users.add(tmp);}} finally {DBConnection.close(rs, st, conn);}return users;}// 查询用户信息public static List<UserBean> getUsers()throws SQLException{List<UserBean> users=new ArrayList<UserBean>();Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = DBConnection.getConnection();String sql = "select * from user limit 0,3";st = conn.createStatement();rs=st.executeQuery(sql);while(rs.next()==true){UserBean tmp=new UserBean();tmp.setUserid(rs.getInt("id"));tmp.setUsername(rs.getString("name"));tmp.setPassword(rs.getString("password"));tmp.setSex(rs.getString("sex"));tmp.setAge(rs.getInt("age"));String birthday= Date_String.getStringDate1(rs.getDate("birthday"));tmp.setBirthday(birthday);users.add(tmp);}} finally {DBConnection.close(rs, st, conn);}return users;}// 查询单个用户信息public UserBean getUserById(String userid)throws SQLException{Connection conn = null;Statement st = null;ResultSet rs = null;UserBean user=null;try {conn = DBConnection.getConnection();String sql = "select * from user where id="+userid;st = conn.createStatement();rs=st.executeQuery(sql);if(rs.next()==true){user=new UserBean();user.setUserid(Integer.valueOf(userid));user.setUsername(rs.getString("name"));;user.setPassword(rs.getString("password"));user.setSex(rs.getString("sex"));user.setAge(rs.getInt("age"));this.birthday=Date_String.getStringDate1(rs.getDate("birthday"));user.setBirthday(birthday);}} finally {DBConnection.close(rs, st, conn);}return user;}// 修改用户个人信息public void updateUser()throws Exception{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBConnection.getConnection();String sql = "update user set name=?,sex=?,age=?,birthday=? where id="+this.userid;ps = conn.prepareStatement(sql);ps.setString(1, this.username);ps.setString(2, this.sex);ps.setInt(3, this.age);ps.setTimestamp(4, Date_String.toTimestamp(this.birthday));ps.executeUpdate();} finally {DBConnection.close(rs, ps, conn);}}// 删除用户个人信息public void delUserById(String userid)throws Exception{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBConnection.getConnection();String sql = "delete from user where id="+userid;ps = conn.prepareStatement(sql);ps.executeUpdate();} finally {DBConnection.close(rs, ps, conn);}}// 注册用户信息public boolean registerUser(){Connection conn = null;PreparedStatement ps = null;try {conn = DBConnection.getConnection();String sql = "insert into user(name,password) values( '" + this.username + "' , '" + this.password+ "')";ps = conn.prepareStatement(sql);ps.execute();return true;} catch (Exception e) {}finally {DBConnection.close(null,ps, conn);}return false;}// 增加用户信息public void addUser()throws Exception{Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBConnection.getConnection();String sql = "insert into user(id,name,password,sex,age,birthday) values(?,?,?,?,?,?)";ps = conn.prepareStatement(sql);ps.setInt(1, this.userid);ps.setString(2, this.username);ps.setString(3, this.password);ps.setString(4, this.sex);ps.setInt(5, this.age);ps.setTimestamp(6, Date_String.toTimestamp(this.birthday));ps.executeUpdate();} finally {DBConnection.close(rs, ps, conn);}}// 校验输入的数据是否符合要求 add update 使用public Map<String, String> checkUser()throws Exception{Map<String, String> errors = new HashMap<String, String>();if(username==null||username.equals("")) errors.put("username", "用户名不能为空!");if(password==null||password.equals("")) errors.put("password", "密码不能为空!");return errors;}}
7.JSP展示层代码
error.jsp
<%@ page contentType="text/html; charset=utf-8" language="java" isErrorPage="true"%>错误页面 发生了以下错误:
<%=exception.getMessage()%>
exit.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" errorPage="error.jsp" %><%session.invalidate(); response.sendRedirect("index.jsp");%>
header.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %><%@ page import="java.util.*" %><%String pathHeader=request.getContextPath();%>学生管理系统
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %><% String pathHeader = request.getContextPath(); String error = (String) request.getAttribute("error"); if (error == null) error = "";%> Student Manager Login Student Manager Login
loginCheck.jsp
<%request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");String path=request.getContextPath();%><jsp:useBean id="user" class="com.sun.bean.UserBean" scope="session"/><%String username=user.getUsername();if(username == null){response.sendRedirect(path+"/index.jsp");}else{session.setAttribute("LoginUser",user);}%>
loginValid.jsp
<%@ page import="java.sql.SQLException" %><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%boolean successflag=user.validlogin();if(successflag==true){ session.setAttribute("user", user);response.sendRedirect("/test4/getUserListByPage");}else{ request.setAttribute("error", "用户名或密码不正确,登陆失败!"); request.getRequestDispatcher("index.jsp").forward(request, response); }%>
Main.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %><%@ include file="/loginCheck.jsp" %><!DOCTYPE html><html><head> <title>Student Manager</title> <link rel="stylesheet" type="text/css" href="css/style.css" /></head><body><div id="root"> <div class="header"> <%@include file="header.jsp" %> </div> <div class="menu"> <%@include file="user/leftMenu.jsp" %> </div> <div class="listStudent"> <%@include file="user/listStudent.jsp" %> </div> <div class="footer"> <%@include file="footer.jsp" %> </div></div></body></html>
8.JSTL
- 引入标签库语句:
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
- 导包语句
<%@page import="entity.User"%>
来源地址:https://blog.csdn.net/qq_51808107/article/details/129110888