zoukankan      html  css  js  c++  java
  • Creating a Book Store using C++ Server Pages

    Tuturials

    This is the first part in a series of tutorials. I'm going to explain how I've written
    a book store, which is included in the sources of this project. You can see how
    the book store look like right now. Here is a PHP version of the store, on which
    the C++ Server Pages version is based.

    The whole store is written with separation of logic and presentation. Servlets, which are doing the logic, retrieve the data from the database, process them and put then into the attributes of the request. C++ Server Pages - doing the presentation - just take the prepared values from request's attributes and display the accordingly.

    First off lets start with the most simple page. That would be the Search page.
    At first sight you might think it's a static page. But you would be wrong. You see, categories are defined in the database. So the first check box is generated dynamically.

    Let's start with the logic. You can view the whole source of the Search.sxx servlet here. Let me explain the file part by part.

    Just after the includes there's the declaration of the Search servlet class:

    class Search : public HttpServlet {
    protected:
        typedef std::vector<Category> categories_t;
        categories_t fetch_categories();
    public:
        void doGet(HttpServletRequest& request, HttpServletResponse &response);
    };
    

    Let's have a look a the definition of the doGet(...) method:

    void Search::doGet(HttpServletRequest& request, HttpServletResponse &response) {
        request.setAttribute("categories", categories_t());
        try{
            request.setAttribute("categories", fetch_categories());
        }catch(const exception& ex) {
            request.setAttribute<string>("error",ex.what());
        }
        request.getRequestDispatcher("SearchView.csp")->forward(request,response);
    }
    

    As you see the only responsibility of the doGet(...) method is to set attributes of the request and then redirect processing to the the proper view. It needs to retrieve all the categories from the database and put them in the "categories" attribute.
    First, the "categories" attribute is initialized with an empty std::vector, so that the view does not need
    to handle the lack of presence of the attribute. Then the attribute is overwritten with the std::vector of categories fetched from the DB. If there were any exceptions, the "error" attribute is set with an according message.
    The last thing the servlet needs to do is to pass the control flow to the view. This is done using the RequestDispather class.
    This is the typical behaviour of all the servlets in the store.

    Now, let's take a look on how the categories are fetched from the database:

    Search::categories_t Search::fetch_categories() {
        shared_ptr<MYSQL_RES> result = mysql.query("SELECT * FROM store_categories");
        MYSQL_ROW row;
        categories_t categories;
        while( (row = mysql_fetch_row(result.get())) ) {
            Category category;
            category.id=lexical_cast<long>(mysql.get(row,0));
            category.name=mysql.get(row,1);
            categories.push_back(category);
        }
        return categories;
    }
    

    As you see, this method uses the global mysql object to communicate with the database. The retrieves all the rows
    from a table. Every row is converted into a Category object. All the Category object are put in a std::vector and returned by the method.
    We'll look into the inner workings of the database communication in the next part of this tutorial series

    Creating a Book Store using C++ Server Pages. Part II

    Tuturials

    In this part I'll write about database access.
    The utility class I've written as a part of the book store is called Mysql and is declared in mysql.h.
    It's really a very simple class. In the constructor of the class, a database connection is opened. It is later closed by the destructor.

    Lets look at the Mysql::query(...) method. The first purpose of the method is to wrap MYSQL_RES pointer in boost::shared_ptr<...> so that I don't need to worry about calling mysql_free_result. The second is to throw exception when an error occurs during execution of the query.

    Now, the interesting part. As you might have noticed the Mysql object instance is
    created as a global variable. It's like a singleton. This way one instance of the Mysql object is created per process. And the processed are created automatically by Apache (by the prefork MPM module to be exact). Apache creates processed to serve request if the load is high and kills them when it is idle.
    This way we get database connection pooling without any effort. As a bonus we get no
    multithreaded programming: no mutexes, semaphores and stuff.

    So when I want to use the database in a servlet, I just use the global mysql object.

  • 相关阅读:
    android笔记5——同一个Activity中Fragment的切换
    JavaScript 刚開始学习的人应知的 24 条最佳实践
    位运算符之异或的化腐朽为奇妙
    unity常见问题之20题
    汉澳sinox不受openssl心血漏洞影响并分析修复其漏洞代码
    基于canvas和Web Audio的音频播放器
    poj2595(凸包)
    HDU 1257 最少拦截系统(dp)
    【iOS开发-33】学习手动内存管理临时抛弃ARC以及retain/assign知识——iOSproject师面试必考内容
    万能狗! 程序猿屌丝独自创业之路(一)
  • 原文地址:https://www.cnblogs.com/huqingyu/p/687106.html
Copyright © 2011-2022 走看看