概述
Creating a Book Store using C++ Server Pages. Part I
Submitted by rzymek on Fri, 2005-11-04 22:26. TuturialsThis 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
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.
最后
以上就是阳光芹菜为你收集整理的Creating a Book Store using C++ Server PagesCreating a Book Store using C++ Server Pages. Part ICreating a Book Store using C++ Server Pages. Part II的全部内容,希望文章能够帮你解决Creating a Book Store using C++ Server PagesCreating a Book Store using C++ Server Pages. Part ICreating a Book Store using C++ Server Pages. Part II所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复