博远动画长期承接各类flash动画制作设计!

新疆flash动画制作,网站制作,程序开发

44317016(微信同号) 13565936697
博远动画工作室--专业flash动画制作,交互课件动画制作,产品演示动画制作,动画课件等各类动画制作。
当前位置:主页 > 新闻资讯>书城管理项目java
博远动画flash动画工作室长期承接各类flash动画,我们给客户的是高端的视觉体验,优质的售后服务...

书城管理项目java


项目的架构:三层架构

    表现层(web层,视图层,表示层...) : (用户能够直接访问的内容)Servlst、html...

    业务逻辑层(Service层) : java类,提供处理业务的方法

    数据持久化层: DAO层(和数据库交互)

                只操作数据库,提供对数据库数据的CURD

                项目中的DAO层因为需求经常发生变化,DAO层通常面向接口编程,使用接口规范对表的操作

     数据库




开发流程:

    1.数据库表【bookstore,bs_user】

    2.对应一张表创建一个javabean【user】

    3.导入数据库相关的jar包【mysqlconnection数据库驱动,c3p0数据库连接池jar包和相关配置文件,DBUtils工具类】

    4.修改c3p0配置文件的数据:数据库名、账号密码

    5.JDBUtils工具类【获取数据库连接和释放连接的方法】

    6.baseDAO提供对数据库的基本操作,包括【CURD,查询一条记录,查询一个集合】

    7.UserDAO提供对bs_user表的所有操作

            UserDAO 接口

            UserDAOImpl 具体表操作的实现

    8.完成注册功能注册

        注册页面(regist.html)-->提交注册需求-->RegistServlst(收集用户的注册请求,调用UserDAO插入到数据库中)

        -->如果插入成功-->重定向到注册注册成功页面(regist_success.html)

        RegistServlet:

            修改form表单的action的提交地址

            修改页面中引入的css和jQuery文件的路径

    9.完成登录功能

        登录页面(login.html)-->提交登录请求-->LoginServlet(收集用户的登录请求,调用UserDAO从数据库中获取用户)

        -->如果查询对象不为null-->登录成功-->重定向到登录成功的页面(login_success.html)

        -->如果为null-->登录失败-->转发到登录页面让用户继续登录(longin.html)

        LoginServlet:

》》 第三阶段 项目优化

   》》将html页面转换为jsp

   》》提取页面相同内容,通过 include 静态引入 base link script

   》》用户登录失败和注册失败,转发到登录或注册页面时,没有错误提示

   》》用户注册失败时,转发到注册页面时,可以将用户的输入信息进行 回显

   》》将一类的操作封装到一个servlet中,整合 servlet 到 userserlvet

   》》我们经常获取的参数封装为一个对象,如果参数过多、获取代码过多,提供一个工具类方法专门用来封装对象

   1.拷贝一个新的项目 bookstore——03

        修改工程名

        修改-首选项-web工程设置-修改 content root的值

   2.修改html页面为jsp页面

    》现在html页面添加jsp首行

    》再修改文件的后缀名.jsp

   3.提取页面中相同的内容,通过include引入

      》提取base标签:link jquery

        -每个页面引入base.jsp

      》提取页面用户访问的头部

        -在用户使用的页面中引入base.jsp

      》提取管理员用户的导航栏

        -在管理员用户页面中引入 manager_navigate.jsp

    4.修改提交页面中的页面后缀和路径<和base引入标签拼接>

    5.修改servlet中的重定向和转发文件后缀名

    6.动态获取base标签的url地址《base.jsp中的base标签》

    7.登录失败时,在转发的login.jsp页面给出错误tip

        用户在login.jsp页面输入账号密码

        提交给loginServlet,判断【if login fail,setAttr a errorMsg in request area 】

        如果失败 ,转发到login.jsp页面【getAttr a errorMsg in request area】

        此时显示登录失败

    8.注册失败时,在转发的regist.jsp显示错误tip

        用户在regist.jsp页面注册账号时

        提交给registServlet,判断【if regist fail,setAttr a errorMsg in request area】

        如果失败,转发到regist.jsp页面【this user is exist】

        此时显示注册失败

    9.模拟service对servlet进行整合

        一个功能对应一个方法

        在login.jsp页面的表单中添加一个参数,告诉servlet 的 请求方式

        参数name的属性值一样method,value值不同

        》提供一个userServlet处理所有的和用户有关的请求【登录 and 注册】

            提供登录和注册的方法,在servlet中判断请求参数的method的value 进而调用不同的方法

    10.使用反射,根据请求参数中的method的值来自动调用方法

        》创建一个baseServlet对httpServlet进一步封装,项目中的其他servlet都继承baseServlet

            在base中获得请求参数method的值,自动调用子类的方法

            只有baseServlet有doGet 和 doPost 方法

            所有的baseServlet的子类不能有doGet 和 doPost方法

    11.提供一个工具类测试方法 自动读取参数并封装为对象

        使用BeanUtils.jar包

项目第四阶段:

        在项目中使用EL和JSTL

    1.使用EL表达式替换jsp

        login.jsp

        regist.jsp

        base.jsp    base标签中 拼接url地址

        include 文件夹中所有的内容不希望用户能直接访问

    2.使用jstl+el 完成图书的增删改查

开发流程》》》从数据源--DAO--service--servlet【遍历调试】

        》创建bs_book

            int id,String title,String author,double price,int sales,int stock,String imgPath

        》对应表创建 javaBean Book

        》创建BookDao 和 BookDaoImpl

              Book  getBookById(String id)

              List<Book>  getBookList()

              int  saveBook(Book book)

              int  updateBook(Book newBook)

              int  delBook(String id)

         》创建BookService 和 BookServiceImpl

         》创建BookMangerServlet 继承BaseServlet

            getBookList() 查询所有图书

                点击后台管理-图书管理超链接时获取图书的列表并展示

                点击图书管理-请求交给BookMangerServlet的getBookList()方法处理再转发到bookManger.jsp展示

                修改图书管理的超链接<a href='manger/BookMangerServlet?method=getBookList'>图书管理</a>

            deleteBook() 删除指定的图书

                在book_manger.jsp页面点击删除的超链接[含有id]

                请求提交给BookMangerServlet的deleteBook()方法,修改<a href='manger/BookMangerServlet?method=getBookList'>删除</a>

                删除之后:需要重定向到getBookList方法中重新查询图书集合

                》点击删除时,提示友好提示框 confirm()

            addBook() 添加图书

                在book_manger.jsp页面点击添加图书跳转到book_add.jsp页面

                book_add.jsp中的from表单提交给BookMangerServlet的addBook()方法处理<from action="manger/BookMangerServlet" method="post">

                book_add.jsp 表单项的name属性值与book类属性名一致

            乱码问题:

                数据存到数据库时有乱码:post请求乱码

                解决:在BaseServlet中的doget()方法中第一行设置编码格式 request.setCharacterEndcoding("utf-8");

            getBook() 根据id查到需要修改的图书

                book_manger.jsp页面点击修改按钮提交给getBook方法处理:<a href="manger/BookMangerServlet?method=getBook">修改</a>

            editBook() 修改图书

                注意:book_edit.jsp页面需要使用隐藏域携带id和img参数

                book_edit.jsp页面点击提交时交给editBook()方法处理:<from action="manger/BookMangerServlet">

            》以后开发中不推荐使用不带条件的sql语句

                不带条件的sql语句查询效率低,影响用户体验

                SELECT * 不要使用

                一页数据过多,使用分页展示

                技术基础:SELECT * FROM bs_book limit index,size

                       例如: SELECT * FROM bs_book limit 5,0 从第0条到第5条数据

            》创建Page类

                List<T> data;

                int pageNumber;

                int totalPage;

                int totalCount;

                int size;

                int index;

            》分页访问流程

                用户访问 携带pageNumber --》BookManagerServlet【findPage()获取pageNumber,设置size】

                        --》调用BookService处理分页的业务逻辑【getPage():创建一个page类,将size和pageNumber设置给page对象,index可以计算得到】

                        --》调用BookDao查询分页数据【getPageBook(Page page):根据page对象的size和index查询data,查询图书总数量totalCount,totalPage可以计算得到】

                            page对象的所有属性都初始化成功,return

                开发流程:倒序开发

                        BookDao:Page<Book> getPageBook(Page<Book> page) ;

                            查询和数据库相关的数据[查询图书记录总条数,查询分页显示的图书集合]

                            》》在BaseDao中提供一个查询记录总条数的方法

                                getCount()

                            》》查询图书总条数:totalCount,page.setTotalCount(totalCount)

                            》》查询分页图书集合:booklist = getBeanList() --》 page.setData(booklist)

                        BookService:

                            创建Page对象,将size和pageNumber设置给对象

                                getPage()

                            》》创建Page()对象

                            》》pageNumber:转换为int类型设置给page对象

                            》》size:设置给page对象

                        BookManagerServlet:

                            findPage():处理用户的分页请求

                                      》》获取pageNumber,设置size

                                      》》调用service处理业务得到page对象

                                      》》将page设置到域中

                                      》》转发到book_manager.jsp页面展示分页数据

                        》》修改manager.jsp页面中图书管理的超链接,点击时访问BookManagerServlet?method=findPage查询分页数据

                        》修改manager.jsp页面中图书管理超链接,点击时访问BookMangerServlet.findPage查询分页数据

                        》修改book_manager.jsp页面获取域中数据显示的方式

                        》在page类的getPageNumber中可以显示pageNumber的范围

                        》分页导航栏

                            如果页码过多,页码显示太乱

                            控制一次显示5个页码

                                【1】  2   3   4   5

                                  1  【2】 3   4   5

                                  1   2  【3】 4   5

                                  2   3  【4】 5   6


                                                                    begin       end

                                                                                                   总页码《=5                   1            totalPage

                                                                                                 总页码》5

                                                                                                   pageNumber《3               1            5

                                                                                                   pageNumber》=3             pageNumber-2 pageNumber+2

                                                                                                     end》=totalPage          totalPage-4  totalPage

                                                                                                     end《totalPage

                        》提取页码导航栏:

                            在查询分页数据时:<a href="manager/BookManagerServlet?method=findPage&pageNumber=${page.pageNumber+1 }">下一页</a>

                                url地址需要动态获取

                                第一次访问BookManagerServlet.findPage时,获取路径

                            --Page类:添加Path属性,访问当前页面的路径

                            --创建Utils工具类方法 getPath():第一次请求时获取分页路径

                            --在book_manager.jsp页面中修改navigate页码导航栏中的地址为动态获取,page.path

                            --提取导航栏到navigate.jsp页面中

                            --在book_manager.jsp页面中引用导航栏

                        》》项目优化:

                            --以前的删除修改后都是调用getBookList方法替换成findPage方法

                            --删除图书以后,跳转到首页

                                修改:跳转到删除时所在页面

                                获取referer:上一个页面的路径

                                删除后:跳转到上一个页面 referer

                》》提供一个用户端查询图书的信息的Servlet

                        --BookClientServlet

                            findPage

                        --index.jsp:展示图书分页的数据

                        --解决index.jsp页面不能直接访问的问题

                            index.jsp页面访问时,直接转发到BookClientServlet.findPage()

                            查询到数据之后转发到图书展示界面,再提供一个页面用来展示首页数据(采用转发到另一个页面防止index页面的死循环)

                        --完成客户端:根据价格查询分页数据的功能

                            BookDao:提供根据价格查询分页数据的方法 getPageByPrice()

                            BookService:getPageByPrice()

                            BookClientServlet:findPageByPrice()

                            --点击list.jsp中的查询按钮

》》第五阶段

    》1、保存用户的登录状态

            -UserServlet,用户登录成功后将获取user对象保存到session域中

            -在所有页面显示用户登录的状态

            -所有的javaBean实现序列化接口

    》2、注销用户

    》3、注册验证码图片

            -引入Kpatcha.jar包

            -配置KaptchaServlet

            -regist.jsp页面中使用验证码

            -点击图片自动刷新验证码

                给验证码绑定点击属性 并拼接自增字符串,兼容IE等浏览器

            -UserServlet中验证Kaptcha

完成购物车功能:

    》1、基于Cookie:每次用户可以将购买的商品信息交给服务器,服务器将信息作为cookie交给浏览器  《不使用》

    》2、基于Session:用户第一次购买图书时,服务器会为其创建一个购物车对象存到session域中

                    用户以后再次购买图书时,服务器将添加的图书保存到session域中的购物车

                    用户结账时,取出session中的购物车进行结账操作

                  在服务器内存中保存

    》3、基于数据库: 比session多了Dao

                    持久化保存数据

1、创建购物车和购物项类

    CartItem:

        Book book;

        int count;

        double amount;

    ShoppingCart:

        Map<String bookId,CartItem> map = new LinkHashMap<>();

        int totalCount;

        double totalAmount;

       -没有Dao操作,所有的购物项的CURD都写在购物车中

        -addBook2Cart(String bookId); 添加图书到购物车

        -delCartItem(String bookId); 删除购物项

        -clearCart(); 清空购物车

        -getCartItemList(); 将map转换为list,b便于查询数据

        -解决double类型的精度问题

    CartServlet:处理用户的购物车和相关请求

        -addBook2Cart():

        -给list页面加入购物车按钮绑定事件,点击提交给addBook2Cart,并将参数bookId一同传入

        -clear():清空购物车

        -delCartItem():删除指定购物项

        -updateCount():修改购物项的数量

    cart.jsp:

        -完成购物车数据的显示


》》结账功能:将购物车转换为订单

        -判断用户是否登录【订单和用户相关联】

        -处理结账【将购物车转换为订单】

        -订单需要保存在数据库里

        -OrderDao【将订单保存在数据库里】

        -OrderService【处理订单相关业务】

        -OrderServlet【处理订单相关的请求】



    流程:

        用户对订单相关的操作:

            保存订单

            根据用户id查询自己的订单:

            修改某个订单的状态:1-->2

            根据订单id查看所有的订单项

            OrderClientServlet【表现层】


        管理员对订单相关的操作:

            查询所有的订单:

            根据id修改订单的状态:0-->1

            根据订单id查看所有的订单项

            OrderManagerServlet【表现层】

        【业务层】

            OrderService【业务层,管理员和用户的业务在此处理】

                String createOrder(ShoppingCart cart,User user);创建订单的业务方法,如何将购物车转为订单,将购物项转为订单项

                List<Order> getOrderListById(String userId);查询用户订单的业务

                Boolean updateState(String orderId,int state);修改订单的状态【用户和管理员都会使用】

            OrderItemService【处理和订单项的业务层】

                List<OrderItem> getOrderItemListById(String orderId);根据订单id查询所属订单项【管理员和用户都会使用】

        【持久化层】

            OrderDao;

                int saveOrder(Order order);用户保存订单的方法

                List<Order> getOrderListById(String userId);用户用户id查询订单

                List<Order> getOrderList();管理员查询所有订单集合

                Boolean updateState(String orderId,int state);修改订单状态

            OrderItemDao;

                int saveOrderItem(OrderItem item);用户保存订单项的方法

                List<OrderItem> getOrderItemListById(String orderId);根据订单id查询所属订单项


        购物车-----》订单     一个购物车对应一个订单

        购物项-----》订单项    一个购物项对应一个订单项

            购物车通过ShoppingCart的Map保存购物项

            订单 单独保存,为订单创建一个id,保存订单项时可以为订单项设置一个外键关联的id

            订单表和订单项表 一对多

    创建表:

        订单表----》购物车

            int totalCount;商品总数量

            double totalAmount;商品总金额

            Date orderTime;创建订单的时间

            int state;订单状态【0:未发货,1:已发货,2:已完成】

            String id; 【订单的id,比较重要

                订单唯一的id

                便于售后查询

                不能暴露公司隐私(使用当前的时间戳+用户id,确保保存在数据库的id是唯一的)】

         int userId;【创建一个外键和bs_user表外键关联】

         user表和order表   【1:n】

         订单项表---》购物项【要保存购买时的信息】

            Integer id;订单项id

            String title;图书标题

            String author;图书作者

            String img_path;图书封面

            double price;单价

            int count;单品数量

            double amount;单品总价

            String order_id;关联订单项表和订单表

        -根据表创建对应的类:

            Order:订单类--对应购物车类

            OrderItem:订单项类---对应购物项

        -创建OrderDao

        -创建OrderItemDao

        -测试OrderDao和OrderItemDao

        -创建OrderService:

            String createOrder(ShoppingCart cart,User user);创建业务订单的方法

            List<Order> getOrderListByUserId(int userId);根据用户id查询用户订单集合

            List<Order>  getOrderList();管理员查询所有订单

        -创建OrderClientService:

            checkOut(); 用户结账方法

        -优化项目

        提供批处理:在修改图书销量和库存时,使用的sql语句一样,可以使用批处理

        -BaseDao : 提供批处理的方法 batchUpdate();

        -BookDao: 批量修改图书销量和库存的方法 batchUpdateStockAndSales();

        -OrderItemDao:批量出入orderItem的方法 batchSaveOrderItem();

项目阶段六:

        在项目中使用Filter

        1、在解决post请求乱码和响应乱码

            创建EncodeFilter解决乱码问题

        2、OrderClientServlet每个操作都需要验证登录,可以通过Filter来统一验证

            创建LoginFilter

        3、用户在创建订单时,如果订单保存失败,会造成订单创建失败,订单外键关联也会失败,但是商品的数量和库存被修改了

            这三个操作可以看作为一个整体,要么一起成功要么一起失败,所有可以当作一个事务来处理

            事务必须使用同一个数据连接

            -获取连接

            Connection conn = new Connection();

            -设置手动提交 【开启事务】

            conn.setAutoCommit(false);

            -完成事务操作【创建订单,保存订单项。修改图书销量库存】

            -捕获异常,如果有异常,则回滚

            coon.rollback();

            -如果没有异常

            coon.commit();

        4、创建TransactionFilter 统一处理事务,将每一个请求都当作一个事务

            问题1、You can't operate on a closed Connection!!!

                在查询首页分页的数据时,有两次操作数据,第一次使用完关闭,导致第二次不能使用

                解决:不要再Base中关闭数据库

            问题2、事务不起作用

                解决:所有异常向上抛出,交给TransactionFilter处理

            问题3、反射调用异常

                保存订单和订单项时发生了sql异常,我们再BaseServlet中捕获

                解决:在BaseServlet中的异常向上抛出

                     最后通过Exception进行捕获

            问题4、You can't operate on a closed Connection!!!

                原因:一次请求服务器时,浏览器可能发生了多次请求【比如请求css img】

                    多个请求使用的是同一个数据库连接,有些线程比较快,回来在过滤器中提前关闭了数据库连接

                解决: 多个线程要使用的对象尽量不要使用单例

                    获取数据库连接时,为当前的线程绑定数据库连接对象,一个线程使用一个,使用完就可以关闭

            问题5、使用HashMap多线程不安全

                    ConcurrentHashMap

                    ThreadLocal解决

            问题6、注册失败,跳转到错误页面

                    希望跳转到注册页面【注册失败的异常不要在TransactionFilter处理,自己处理】

            问题7、库存不能为负数

                在数据的表中修改表结构    stock修改为Unsigned约束数据不为负数

                在OrderService中对stock进行判断

项目优化:

        使用AJAX完成局部刷新

        1、首页:点击加入购物车,页面只更新【图书标题,购物车数量】

        2、注册页面:用户输入用户名之后可以检查用户名是否可用

        3、购物车页面:修改图书数量后,只有 单个图书总价格和总数量、总价格发生局部改变


如果遇到技术问题,请尽快联系本站QQ:44317016 我们会尽快帮您解决
上一篇: 家庭管理系统毕业设计ASP.NET
下一篇: 基于java物流配送管理系统

新疆博远云创网络科技有限公司—专业flash动画制作