Java servlet与数据库设计
我有一个关于使用Servlet和JDBC的一般性问题 例如,我有一个名为MyDatabaseManager的类,它提供函数 public boolean updateUser(User user) {...} public boolean deleteUser(User user) {...} public boolean inserUser(User user){...} 公共布尔更新用户(用户){…} 公共布尔deleteUser(用户用户){…} 公共布尔插入器(用户){…} ,这些函数将访问和操作数据库 我的问题是关于Servlet实现的。目前我正在使用三个Servlet(UpdateUserServlet、InsertUserServlet和DeleteUserServlet),每个Servlet调用MyDatabaseManager实例(这里只有一个实例,使用单例模式)函数。(例如,UpdateUserServlet调用MyDatabaseManager.updateUser…)Java servlet与数据库设计,java,servlets,jdbc,Java,Servlets,Jdbc,我有一个关于使用Servlet和JDBC的一般性问题 例如,我有一个名为MyDatabaseManager的类,它提供函数 public boolean updateUser(User user) {...} public boolean deleteUser(User user) {...} public boolean inserUser(User user){...} 公共布尔更新用户(用户){…} 公共布尔deleteUser(用户用户){…} 公共布尔插入器(用户){…} ,这些函数将
我认为这是使用Servlet和数据库最直接的方法。但我不确定这样做是否正确。例如,这在业界是如何实现的。数据库类上的Singleton听起来不错,尤其是它似乎包含更新/删除/插入代码
如果您使用的是连接池,请确保将DataSourceFactory单独设置。很难回答,因为存在数百种设计模式!我知道一个关于数据库管理的好方法叫做DAO(数据访问对象)。我经常用这个。我建议你去看看 别误会我的意思,一个单身汉来挽留你的经理是个好主意。我通常也是这么做的。然而,通常我有一个DAOFactorySingleton,它几乎有责任在我的应用程序中生成所有类DAO,这个工厂很好,因为我可以有一些数据源规则,这个工厂只是从某处轮询并注入我的DAO!所以,几乎每个DAO都不必关心JDBC连接之类的事情 通过2个链接来解释更多关于DAO的信息!
第二个是与hibernate一起使用!您可以阅读它,并且仅与hibernate一起使用不是必需的。我真的很喜欢第二个,虽然更复杂。现在人们并不真正直接使用servlet,他们使用的框架可以简化您的工作,但是如果您真的想使用servlet,您可以使用其他方法doPut、dodelite,甚至创建您自己的方法,在一个框架中完成所有操作。以下是您将如何执行此操作的示例:
public abstract class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String method = request.getParameter("_method");
if ("form".equals(method)) {
this.doForm(request, response);
} else {
if ("delete".equals(method)) {
this.doDelete(request, response);
} else {
super.service(request, response);
}
}
}
protected void doForm(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
throw new UnsupportedOperationException();
}
}
如您所见,这个Servlet在表单上使用一个特殊字段\u method来决定调用什么特殊方法,如果\u method不可用,它将使用常用的服务方法,并将调用doGet或doPost
下面是这个servlet的实现的样子:
public class UsersServlet extends BaseServlet {
private UsersRepository cadastro = new UsersRepository();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setAttribute("usuarios", cadastro.list());
req.getRequestDispatcher("/usuarios/listar.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
User usuario = this.getUser(req);
usuario.setNome(req.getParameter("nome"));
usuario.setEmail(req.getParameter("email"));
usuario.setSenha(req.getParameter("senha"));
this.cadastro.persist(usuario);
resp.sendRedirect(req.getContextPath() + "/usuarios");
}
protected User getUser(HttpServletRequest req) {
User usuario;
if (req.getParameter("id") == null) {
usuario = new Usuario();
} else {
Long id = new Long(req.getParameter("id"));
usuario = this.cadastro.search(id);
}
return usuario;
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
User usuario = this.getUser(req);
this.cadastro.remover(usuario);
resp.sendRedirect(req.getContextPath() + "/usuarios");
}
@Override
protected void doForm(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
User usuario = this.getUser(request);
request.setAttribute("usuario", usuario);
request.getRequestDispatcher("/usuarios/form.jsp").forward(request,
response);
}
}
通过这种方式,您可以在一个servlet中实现所有功能。许多业内人士使用ORM+依赖注入框架+事务管理器+数据库池库,例如Hibernate(ORM)+Spring DI(依赖注入)+Spring事务管理器(事务管理器)+Apache DBCP(DB连接池) 有时,当ORM的使用不合理时(例如,非常简单的DB模式,ORM性能开销因应用程序的性质而无法承受),开发人员可能会使用原始JDBC。许多人仍然使用依赖注入和DB连接池 使用依赖项注入或DB连接池是非常罕见的。也就是说,除非它是一个非常罕见的特殊应用程序,否则业界的开发人员确实使用依赖注入框架和DB连接池 在这种情况下,需要管理的状态由DB连接池框架管理,因此您不必担心状态管理或线程安全(只要您自己不在不同线程之间共享任何内容,并且遵循DB连接池框架的API)。也就是说,你不需要单身。如果您实现自己的DB连接池,那么使用单例将是有意义的
如果开发人员不想使用任何框架(例如,创建一个非常简单的工具),那么很多人每次都会打开一个连接(针对每个线程)。在这种情况下,您也不需要管理任何状态,因此不需要单例。这当然是一个设计选择问题,您可以采用Spring、Struts等框架。。这使得这更容易。或者,如果您想使用经典的servlet请求/响应模式,我建议您创建一个父servlet,它拦截请求并将其传递给正确的方法来执行请求
此外,您还可以选择各种ORM解决方案,如Hibernate、JPA等。。您可以使用它来处理数据库访问操作。但是,如果您选择坚持使用经典的JDBC调用,您可以使用来决定要针对哪些调用提供wrap数据库连接和操作。在业界,我们都是为了简单。例如,对于从浏览器到服务器再到持久性存储(数据库)的用户交互,我们遵循以下方法 首先是一种模式。这将允许我们完全而不是为从浏览器到服务器的每个用户交互编写Servlet。这使我们能够做到以下几点:
- 允许控制器处理用户请求并将其链接到我们的用户操作(我们的模型)。这个模型允许我们编写业务逻辑来响应用户数据
public class ActionServlet extends HttpServlet {
//Action registration
public void init() {
ActionMapping mapping = .....; //some instatiation
mapping.setAction("/userRegistration", UserRegistrationAction.class);
//Save it in Application Scope
getServletContext().setAttribute("actionConfig", mapping);
}
private void doAction(HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = request.getPathInfo();
Action action = ((ActionMapping)getServletContext().getAttribute("actionConfig")).getAction(path);
if (action == null) {
throw new Exception("No action of '" + path + "' found.");
}
action.execute(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
doAction(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
doAction(request, response);
}
}
public abstract class Action {
public abstract void execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
protected void dispatch(HttpServletRequest request, String path) {
RequestDispatcher dispatcher = request.getRequestDispatcher(path);
dispatcher.forward(request, response);
}
}
public class UserRegistrationAction extends Action {
public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//Business Logic goes here...
//Call DAO,
UserRegistrationDAO dao = ; //Some DAO instantation
User user = createUserFromForm(request);
dao.save(user);
dispatch(request, "success");
}
}