1. 程式人生 > >JAVA WEB從入門到精通 day25 專案:網上書城

JAVA WEB從入門到精通 day25 專案:網上書城

專案:網上書店

功能分析

網站分為前臺和後臺。前臺為使用者使用,後臺為管理員管理。 

前臺:
    使用者模組
        -註冊
        -啟用:通過電子郵件
        -登陸
        -退出

    圖書的分類模組
        -查詢圖書的分類顯示在頁面上 
        例如:文學書,動漫書之類 

    圖書模組
        -查詢所有圖書
        -分類查詢圖書
        -查詢圖書詳情(按圖書編號查詢)

    購物車模組
        -新增商品
        -清空購物車
        -刪除指定商品
        -我的購物車(按使用者查詢購物車)

    訂單模組
        -生成訂單
        -我的訂單(按使用者查詢訂單)
        -確認收貨
        -付款功能



後臺
    管理員模組:
        -登入

    圖書分類管理模組
        -新增分類
        -檢視分類
        -刪除分類
        -修改分類

    圖書管理模組
        -檢視所有圖書
        -按圖書編號查詢
        -修改圖書
        -刪除圖書
        -新增圖書

    訂單模組
        -查詢所有訂單
        -按訂單狀態查詢(未付款,未發貨之類的)
        -發貨

專案的搭建

    1.導包
        資料庫相關:資料庫驅動,c3p0連線池(jar包和配置檔案),DBUtils  
        郵箱相關:JavaMail,activation
        上傳相關:commons-fileupload,commons-io 
        其他依賴包 commons-logging
        我們自己製作的工具類等

    2.建立package  
         使用者模組
            domain
            dao
            service
            web 
        分類模組
            domain
            dao
            service
            web 
        圖書模組
            domain
            dao
            service
            web 
        購物車模組
            domain
            dao
            service
            web 
        訂單模組
            domain
            dao
            service
            web  

    3.建立資料庫表 
        /*建立資料庫*/
        CREATE DATABASE bookstore;

        /*建立使用者表*/
        CREATE TABLE user(
          uid CHAR(32) PRIMARY KEY,/*主鍵*/
          username VARCHAR(50) NOT NULL,/*使用者名稱*/
          `password` VARCHAR(50) NOT NULL,/*密碼*/
          email VARCHAR(50) NOT NULL,/*郵箱*/
          `code` CHAR(64) NOT
NULL,/*啟用碼*/ state BOOLEAN/*使用者狀態,有兩種是否啟用*/ );
/*建立圖書分類表*/ CREATE TABLE category ( cid CHAR(32) PRIMARY KEY,/*主鍵*/ cname VARCHAR(100) NOT NULL/*分類名稱*/ ); /*向圖書分類表插入三條記錄*/ INSERT INTO category(cid,cname) VALUES ('1','JavaSE'); INSERT INTO category(cid,cname) VALUES ('2','JavaEE'); INSERT INTO category(cid,cname) VALUES ('3','Javascript'); /*建立圖書表*/ CREATE TABLE book ( bid CHAR(32) PRIMARY KEY,/*主鍵*/ bname VARCHAR(100),/*圖書名*/ price DECIMAL(5,1),/*單價*/ author VARCHAR(20),/*作者*/ image VARCHAR(200),/*圖片*/ cid CHAR(32),/*所屬分類*/ FOREIGN KEY (cid) REFERENCES category(cid)/*建立主外來鍵關係*/ ); /*向圖書表插入幾條記錄*/ INSERT INTO book VALUES ('1','Java程式設計思想(第4版)','75.6','qdmmy6','book_img/9317290-1_l.jpg','1'); INSERT INTO book VALUES ('2','Java核心技術卷1','68.5','qdmmy6','book_img/20285763-1_l.jpg','1'); INSERT INTO book VALUES ('3','Java就業培訓教程','39.9','張孝祥','book_img/8758723-1_l.jpg','1'); INSERT INTO book VALUES ('4','Head First java','47.5','(美)塞若','book_img/9265169-1_l.jpg','1'); INSERT INTO book VALUES ('5','JavaWeb開發詳解','83.3','孫鑫','book_img/22788412-1_l.jpg','2'); INSERT INTO book VALUES ('6','Struts2深入詳解','63.2','孫鑫','book_img/20385925-1_l.jpg','2'); INSERT INTO book VALUES ('7','精通Hibernate','30.0','孫衛琴','book_img/8991366-1_l.jpg','2'); INSERT INTO book VALUES ('8','精通Spring2.x','63.2','陳華雄','book_img/20029394-1_l.jpg','2'); INSERT INTO book VALUES ('9','Javascript權威指南','93.6','(美)弗蘭納根','book_img/22722790-1_l.jpg','3'); /*建立訂單表*/ CREATE TABLE orders ( oid CHAR(32) PRIMARY KEY,/*主鍵*/ ordertime DATETIME,/*訂單生成時間*/ total DECIMAL(10,0),/*訂單合計*/ state SMALLINT(1),/*訂單狀態:未付款、已付款但未發貨、已發貨但未確認收貨、收貨已結束*/ uid CHAR(32),/*訂單的主人*/ address VARCHAR(200),/*訂單的收貨地址*/ FOREIGN KEY (uid) REFERENCES USER (uid)/*建立主外來鍵關係*/ ); /*建立訂單項表*/ CREATE TABLE orderitem ( iid CHAR(32) PRIMARY KEY,/*主鍵*/ COUNT INT,/*數量*/ subtotal DECIMAL(10,0),/*小計*/ oid CHAR(32),/*所屬訂單*/ bid CHAR(32),/*訂單項所指的商品*/ FOREIGN KEY (oid) REFERENCES orders (oid),/*建立主外來鍵關係*/ FOREIGN KEY (bid) REFERENCES book (bid)/*建立主外來鍵關係*/ );

專案前臺

使用者模組

建立相關類
        -在domain包下建立user類
        -dao包建立UserDao類
        -service包建立UserService類
        -web.servlet包下建立UserServlet

------------------------------註冊功能分析-----------------------------------------
        流程分析:
            註冊頁面regist.jsp : 請求UserServlet的註冊方法,傳送表單裡的資料 

            UserServlet#regist():將表單資料封裝到user物件中
                                  對資料進行校驗,如果資料有誤,將表單資料和錯誤資訊轉發回regist.jsp 頁面
                                  呼叫Service層的regist()方法,傳遞user物件 
                                  -如果丟擲異常,將異常資訊和表單資料轉發到regist.jsp中,為了回顯
                                  -如果成功註冊,傳送啟用郵件(收件人,發件人,主題,內容),傳送成功儲存成功資訊轉發到msg.jsp中。郵件內容應該包含一個用來啟用的url,連結中要有啟用碼。 

            UserService#regist(User user):
                                  校驗使用者名稱是否被註冊,如果註冊,丟擲自定義異常
                                  校驗郵箱是否被註冊,如果註冊,丟擲自定義異常 
                                  把user插入到資料庫中 

            UserDao:
                    findByUsername(String username):按使用者名稱查詢
                    findByEmail(String email):按email查詢使用者
                    void add(User user):插入使用者到資料庫中 

-----------------------------啟用功能分析-----------------------------------
            流程分析:
            註冊成功後向使用者郵箱傳送一封啟用郵件,裡面包含一個URL地址,攜帶了使用者的啟用碼。

            UserServlet#activate():
                                    獲取啟用碼引數,呼叫service層的activate(String code)啟用方法
                                  出現異常,儲存異常資訊轉發到msg頁面
                                  啟用成功,儲存成功資訊轉發到msg頁面

            UserService#activate(String code):
                                使用啟用碼去查詢資料庫,得到user物件
                                資料庫返回null,丟擲異常
                                如果使用者的狀態為已啟用,丟擲異常
                                如果使用者狀態為未啟用,則修改使用者狀態為true,啟用狀態

            UserDao:
                    findByCode(String code):通過啟用碼查詢使用者
                    updateState(String uid,boolean state):修改使用者狀態

    ------------------------------登入功能分析----------------------------------- 
    流程分析:
            login.jsp:一個表單,包含賬號密碼

            UserServlet#login():
                                將使用者名稱和密碼封裝成user物件
                                校驗使用者名稱和密碼
                                呼叫service層的login方法
                                如果出現異常就儲存異常資訊到request中,轉發回login.jsp頁面 
                                如果登入成功,就儲存使用者資訊到session中,重定向到主頁 

            UserService#login(User user):
                                使用username查詢資料庫,得到user物件。
                                如果結果為null,丟擲使用者不存在異常。

                                如果存在該使用者,比較表單中的使用者密碼和資料庫中的密碼是否相同
                                如果不同丟擲異常

                                檢視使用者狀態,如果使用者狀態未啟用,丟擲異常。

                                前面全部成功,返回user物件。

            UserDao:
                            findByUsername():根據使用者名稱查詢使用者 



----------------------退出功能分析-------------------------------------------
            UserServlet#quit()
                            :呼叫session的invalidate()方法銷燬使用者session,然後返回主頁即可

程式碼實現

    domain包下的User類 
public class User {

    private String uid;           //使用者id,主鍵
    private String username;      //使用者名稱 
    private String password;      //密碼
    private String email;         //郵箱
    private String code;          //啟用碼
    private boolean state;        //使用者狀態,是否啟用
    public String getUid() {
        return uid;
    }
    public void setUid(String uid) {
        this.uid = uid;
    }
    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 getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public boolean isState() {
        return state;
    }
    public void setState(boolean state) {
        this.state = state;
    }
    @Override
    public String toString() {
        return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", email=" + email + ", code="
                + code + ", state=" + state + "]";
    }   
}

登入和註冊頁面

這裡寫圖片描述

這裡寫圖片描述

    UserServlet 
    我們繼承我們以前編寫的BaseServlet,來方便我們使用反射操作。

public class UserServlet extends BaseServlet {
    //依賴service層
    private UserService userservice=new UserService();

    //生成UUID的方法
    public String UUID(){
        return UUID.randomUUID().toString().replaceAll("-", "");
    } 
    //註冊功能
    public String regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取表單資料,封裝成user物件
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        String email=request.getParameter("email"); 
        User user=new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(email);
        user.setUid(UUID());
        user.setCode(UUID()+UUID());  
        //對錶單資料進行校驗,錯誤資訊存放在map集合中
        Map errors=new HashMap();
        //校驗使用者名稱
        if(username==null||username.trim().isEmpty()){
            errors.put("username", "使用者名稱不能為空");
        }else if(username.length()<5||username.length()>=16)
        {
            errors.put("username", "使用者名稱必須在6-15位之間");
        }
        //校驗密碼
        if(password==null||password.trim().isEmpty()){
            errors.put("password", "密碼不能為空");
        }else if(password.length()<5||password.length()>=16)
        {
            errors.put("password", "密碼必須在6-15位之間");
        }
        //校驗郵箱
        if(email==null||email.trim().isEmpty()){
            errors.put("email", "郵箱不能為空");
        }else if(!email.matches("\\[email protected]\\w+\\.\\w+"))
        {
            errors.put("email", "郵箱錯誤");
        }

        //判斷是否有錯誤,有的話就將表單資料(為了回顯)和錯誤資訊轉發到註冊頁面
        if(errors.size()>0){
            request.setAttribute("errors", errors);
            request.setAttribute("formuser", user);
            return "forward:/jsps/user/regist.jsp";
        } 

        //沒錯誤就呼叫service層的regist方法
        try {
            userservice.regist(user);
        } catch (UserException e) {
            //丟擲異常的話就將異常資訊儲存在request中,轉發到註冊頁面
            request.setAttribute("msg", e.getMessage());
            request.setAttribute("formuser", user);
            return "forward:/jsps/user/regist.jsp";
        } 

        //註冊成功就傳送郵件,我們將郵件的一些引數放在配置檔案中
        Properties prop=new Properties();
        //載入郵件相關配置檔案prop.load(this.getClass().getClassLoader().getResourceAsStream("email.properties"));
        String host=prop.getProperty("host");     //獲取郵箱主機
        String ename=prop.getProperty("ename");   //獲取郵箱使用者名稱
        String epasswd=prop.getProperty("epasswd");//獲取使用者密碼
        String from=prop.getProperty("from");     //獲取發件人
        String to=user.getEmail();                //獲取收件人
        String subject=prop.getProperty("subject");//獲取郵件主題
        String content=prop.getProperty("content");//獲取郵件內容
        content=MessageFormat.format(content, user.getCode()); 
        Properties props = new Properties(); 
        props.setProperty("mail.host", host);//設定伺服器主機名
        props.setProperty("mail.smtp.auth", "true");//設定需要認證
        Authenticator auth = new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication () {
                return new PasswordAuthentication(ename, epasswd);//使用者名稱和密碼
        }
        };
        Session session=Session.getInstance(props, auth);
        MimeMessage msg=new MimeMessage(session);   //獲取MimeMessage物件
        try{
        msg.setFrom(new InternetAddress(from));   //設定發件人
        msg.setRecipients(RecipientType.TO, to);  //設定收件人

        msg.setSubject(subject);  //設定主題
        msg.setContent(content, "text/html;charset=utf-8"); //設定正文
        Transport.send(msg); //傳送郵件
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
        request.setAttribute("msg", "恭喜註冊成功。請到郵箱啟用");

        return "forward:/jsps/msg.jsp";
    }

    //啟用方法
    public String activate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        //獲取啟用碼
        String code=request.getParameter("code");
        try { 
            //呼叫service的啟用方法,成功就儲存成功資訊轉發到msg頁面 
            userservice.activate(code);
            request.setAttribute("msg", "恭喜您,啟用成功");
            return "forward:/jsps/msg.jsp";
        } catch (UserException e) { 
            //出現異常就儲存異常資訊轉發到msg頁面
            request.setAttribute("msg",e.getMessage());
            return "forward:/jsps/msg.jsp";
        }
    }

    //登入功能
    public String login(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); 
        Map errors=new HashMap();
        //校驗使用者名稱
        if(username==null||username.trim().isEmpty()){
            errors.put("username", "使用者名稱不能為空");
        }else if(username.length()<5||username.length()>=16)
        {
            errors.put("username", "使用者名稱必須在6-15位之間");
        }
        //校驗密碼
        if(password==null||password.trim().isEmpty()){
            errors.put("password", "密碼不能為空");
        }else if(password.length()<5||password.length()>=16)
        {
            errors.put("password", "密碼必須在6-15位之間");
        }
        if(errors.size()>0){
            request.setAttribute("errors", errors);
            request.setAttribute("formuser", user);
            return "forward:/jsps/user/login.jsp";
        } 
        //如果登入成功,就將使用者資訊儲存在session中,否則儲存錯誤資訊返回登陸頁面
        try {
            User _user=userservice.login(user); 
            request.getSession().setAttribute("sessionuser", _user);
            request.getSession().setAttribute("cart", new Cart());
            return "redirect:/index.jsp";
        } catch (UserException e) {
            request.setAttribute("msg", e.getMessage());
            request.setAttribute("formuser", user);
            return "forward:/jsps/user/login.jsp";

        }
    } 
    //退出功能
    public String quit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().invalidate();
        return "redirect:/index.jsp";
    }

}
    UserService :處理業務邏輯 

public class UserService { 
    //依賴dao層
    private UserDao userdao=new UserDao(); 

    //註冊功能
    public void regist(User formuser) throws UserException{ 

        //呼叫dao層方法校驗使用者名稱是否被註冊,如果已註冊丟擲自定義異常
        User user=userdao.findByUsername(formuser.getUsername());
        if(user!=null) throw new UserException("使用者名稱已被註冊");  

        //校驗郵箱是否被使用,如果已使用丟擲自定義異常
        user=userdao.findByEmail(formuser.getEmail());
        if(user!=null) throw new UserException("郵箱已被使用"); 

        //新增使用者
        userdao.addUser(formuser);
    } 

    //啟用功能
    public void activate(String code) throws UserException{ 
        //根據啟用碼查詢使用者
        User user=userdao.findByCode(code);
        //如果為空,丟擲使用者不存在異常
        if(user==null) throw new UserException("使用者不存在"); 
        //不為空,如果使用者狀態為未啟用,則將狀態設定為啟用
        if(user.isState()==false) userdao.updateState(user.getUid(), true);
        //如果已啟用,則丟擲異常
        else throw new UserException("使用者已經啟用,請勿重複啟用"); 
    }  

    //登入功能
    public User login(User formuser) throws UserException{ 
        //判斷使用者是否存在,如果不存在丟擲自定義異常
        User user=userdao.findByUsername(formuser.getUsername());
        if(user==null) throw new UserException("使用者不存在");  

        //判斷使用者輸入的密碼是否和資料庫裡的密碼相同,不同則丟擲異常
        if(!user.getPassword().equals(formuser.getPassword())) throw new UserException("您的密碼錯誤"); 

        //判斷使用者是否啟用,未啟用丟擲異常
        if(user.isState()==false) throw new UserException("您的賬號未啟用"); 
        //返回user物件
        return user;
    }
}
UserDao :對資料的操作  

public class UserDao {
    private QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); 

    //按照使用者名稱查詢使用者 
    public User findByUsername(String username){

        try {
            String sql="select * from user where username=?";
            User user=qr.query(sql, new BeanHandler<User>(User.class), username);

            return user;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    } 

    //按照email查詢使用者   
    public User findByEmail(String email){
        String sql="select * from user where email=?";
        try {
            return qr.query(sql, new BeanHandler<User>(User.class), email);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }  
    //按照啟用碼查詢使用者
    public User findByCode(String code){
        String sql="select * from user where code=?";
        try {
            return qr.query(sql, new BeanHandler<User>(User.class), code);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    } 

    //修改使用者狀態功能  
    public void updateState(String uid,boolean state){
        String sql="update user set state=? where uid=?";
        try {
            qr.update(sql,state,uid);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    } 

    //新增使用者
    public void addUser(User user){
        try {

            String sql="insert into user values(?,?,?,?,?,?)";
            Object []params={user.getUid(),user.getUsername(),user.getPassword(),user.getEmail(),user.getCode(),user.isState()};
            qr.update(sql, params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }       
}

圖書分類模組

建立相關類
            domain包建立Category類
            dao包建立CategoryDao類
            service包建立CategoryService類
            servlet包下建立CategoryServlet 

-------------------------查詢所有圖書分類功能分析-------------------------
        CategoryDao:
                    findAll():查詢所有圖書分類,封裝成list<Category>返回 

        CategoryService:
                    findAll():呼叫dao層方法,返回List<Category>

        CategoryServlet:
                    findAll():呼叫service層的方法,得到List<Category>
                    儲存在request域中,轉發到left.jsp頁面

        left.jsp:遍歷查詢得到的圖書分類,顯示在頁面上 

程式碼實現

domain下建立Category類  

public class Category {
    private String cid; //分類id
    private String cname;//分類名稱
    public String getCid() {
        return cid;
    }
    public void setCid(String cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    @Override
    public String toString() {
        return "Category [cid=" + cid + ", cname=" + cname + "]";
    }

}
CategoryServlet

public class CategoryServlet extends BaseServlet  { 
    //依賴service層
    private CategoryService categoryservice=new CategoryService();

    //查詢所有分類
    public String findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        //呼叫service的查詢所有分類功能,得到list集合儲存在request域中,轉發到顯示頁面
        request.setAttribute("categorylist", categoryservice.findAll());
        return "forward:/jsps/left.jsp";
    }

}
    CategoryService:處理業務邏輯 

public class CategoryService { 
    //依賴dao層,同時還依賴Book的dao層
    private CategoryDao categorydao=new CategoryDao();  
    private BookDao bookdao=new BookDao(); 

    //查詢所有分類
    public List<Category> findAll(){
        return categorydao.findAll();
    }  

    //後臺功能:新增分類
    public void add(Category category) throws CategoryException { 
        //判斷分類是否存在,存在就丟擲異常
        Category _category=categorydao.isExist(category.getCname());
        if(_category!=null) throw new CategoryException("分類已存在"); 
        //新增分類
        categorydao.add(category);
    } 

    //後臺功能:刪除分類
    public void delete(String cid) throws CategoryException { 
        //呼叫bookdao的通過分類查詢圖書的方法,獲取該分類下圖書的數量
        int count=bookdao.findBycid(cid); 
        //如果數量大於0,則丟擲異常
        if(count>0) throw new CategoryException("該分類下還有圖書,不能刪除該分類");
        categorydao.delete(cid);
    }  

    //通過cid載入分類功能
    public Category load(String cid) {
        return categorydao.load(cid);
    } 

    //編輯分類功能
    public void edit(Category category) throws CategoryException { 
        //判斷分類是否存在
        Category _category=categorydao.isExist(category.getCname());
        if(_category!=null) throw new CategoryException("分類已存在"); 
        //呼叫dao層的編輯方法
        categorydao.edit(category);
    }
}
    CategoryDao:進行資料的操作  

    public class CategoryDao {
    QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); 

    //查詢所有分類功能,返回list集合
    public List<Category> findAll(){
        String sql="select * from category";
        try {
            return  qr.query(sql, new BeanListHandler<Category>(Category.class));
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //新增分類功能
    public void add(Category category) {
        try {
            String sql="insert into category values(?,?)";
            Object []params={category.getCid(),category.getCname()};
            qr.update(sql,params);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }   
    }

    //通過分類名稱判斷分類是否存在的方法
    public Category isExist(String cname){
        try {
            String sql="select * from category where cname=?";
            return qr.query(sql, new BeanHandler<Category>(Category.class),cname);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    } 

    //刪除分類
    public void delete(String cid) {
        String sql="delete from category where cid=?";
        try {
            qr.update(sql, cid);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //通過分類id返回分類物件的方法
    public Category load(String cid) {
        try {
            String sql="select * from category where cid=?";
            return qr.query(sql, new BeanHandler<Category>(Category.class),cid);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //編輯分類的方法
    public void edit(Category category) {
        try {
            String sql="update category set cname=? where cid=?";
            Object[] params={category.getCname(),category.getCid()};
            qr.update(sql,params);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
left.jsp:顯示分類的頁面 

<body>
<div>
    <a href="<c:url value='/BookServlet?m=findAll'/>">全部分類</a>
</div>
<!--迴圈遍歷分類列表,顯示分類-->
<c:forEach items="${categorylist}" var="category">
<div>
    <!--點選分類時請求servlet,顯示不同分類的圖書-->
    <a href="<c:url value='/BookServlet?m=findBookByCategory&cid=${category.cid }'/>">${category.cname }</a>
</div>
</c:forEach>
</body>

這裡寫圖片描述

圖書模組

建立相關類
            在book.domain包下建立book類
            在book.dao包下建立BookDao類
            在book.service包下建立BookService類、
            在book.web.servlet包下建立BookServlet


-----------------------------查詢所有圖書功能分析-----------------------------

            BookDao:
                    findAll():查詢所有圖書,返回List<Book>集合

            BookService:
                    findAll():呼叫dao層方法,返回List集合 

            BookServlet:
                    findAll():呼叫service層的findAll方法,獲取List集合。
                    儲存到request域,轉發到顯示頁面。

            list.jsp:迴圈遍歷圖書集合,顯示圖書  



-------------------------按照圖書分類查詢圖書功能分析----------------------
            BookDao:
                    findBookByCategory(String cid):通過傳進來的cid查詢圖書,返回List<Book>集合

            BookService:
                    findBookByCategory(String cid):呼叫dao層方法,返回List集合 

            BookServlet:
                    ffindBookByCategory(String cid):獲取頁面傳入的cid,呼叫service層方法,獲取List集合。
                    儲存到request域,轉發到顯示頁面。

            list.jsp:迴圈遍歷圖書集合,顯示圖書 


--------------------------載入圖書詳情功能分析-----------------------------

            BookDao:
                    load(String bid):通過圖書編號查詢指定圖書,返回book物件


            BookService:
                    load(String bid):呼叫dao層方法查詢指定圖書,返回book物件

            BookServlet:
                    load(String bid):
                                    獲取頁面傳遞的bid,呼叫service層load方法獲得book物件。
                                    然後儲存在request中,轉發到顯示的頁面。

            desc.jsp:顯示圖書詳情。 

程式碼實現

    domain下建立Book類  

public class Book {
    private String bid;      //圖書編號
    private String bname;    //圖書名字
    private double price;    //圖書價格 
    private String author;   //作者
    private String image;    //圖片路徑
    private Category category; //資料庫中為cid,這裡可以直接對應物件
    public String getBid() {
        return bid;
    }
    public void setBid(String bid) {
        this.bid = bid;
    }
    public String getBname() {
        return bname;
    }
    public void setBname(String bname) {
        this.bname = bname;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getImage() {
        return image;
    }
    public void setImage(String image) {
        this.image = image;
    }
    public Category getCategory() {
        return category;
    }
    public void setCategory(Category category) {
        this.category = category;
    }
    @Override
    public String toString() {
        return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + ", auther=" + author + ", image=" + image
                + ", category=" + category + "]";
    }

}
    BookServlet  

public class BookServlet extends BaseServlet { 
    //依賴service層
    private BookService bookservice=new BookService(); 

    //查詢所有圖書功能
    public String findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        //呼叫service層的findAll方法獲取圖書的集合,存放在request中,轉發到list頁面
        request.setAttribute("booklist", bookservice.findAll());
        return "forward:/jsps/book/list.jsp";
    } 

    //通過分類查詢圖書功能
    public String findBookByCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        //獲取分類編號
        String cid=request.getParameter("cid"); 
        //獲取該分類下的圖書的集合,存放在request中,轉發到list頁面
        request.setAttribute("booklist", bookservice.findBookByCatyegory(cid));
        return "forward:/jsps/book/list.jsp";
    } 

    //載入圖書詳情功能
    public String load(HttpServletReq