Java servlet与数据库设计

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和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…)


我认为这是使用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不可用,它将使用常用的服务方法,并将调用doGetdoPost

下面是这个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。这使我们能够做到以下几点:

  • 允许控制器处理用户请求并将其链接到我们的用户操作(我们的模型)。这个模型允许我们编写业务逻辑来响应用户数据
在当今的Java世界中,存在着满足MVC需求的框架。出现在Java框中的是(JavaServerFaces)

对于后端,我们肯定使用数据库,但我们也很聪明,使用(对象关系映射)将现实世界的问题建模为对象模型,以及如何最好地持久化(存储)这些对象模型。有些使用(实体关系建模)来设计语义数据模型

在中间的业务逻辑中,我们添加了一个服务(作为业务逻辑层),它不想关心在哪里读/写数据,只要
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");
    }
}