美文网首页
第十五篇学习总结

第十五篇学习总结

作者: 拼搏男孩 | 来源:发表于2020-02-01 11:25 被阅读0次

    第十五篇学习总结

    一、购物车的实现

    购物车在数据库中需要单独一张表,字段有id、userId、goodsId、num、createTime。所有用户的购物车数据都在这张表中,对购物车的增删改查也在这张表中。

    1、购物车Dao层

    购物车Dao层需要实现的操作有添加购物车、根据用户id和商品id查询记录、修改购物车商品的数量、删除购物车、查询某个用户所有的购车车记录

    import com.qianfeng.shop.bean.Cart;
    import com.qianfeng.utils.DBUtils;
    import com.qianfeng.utils.JDBCUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.List;
    
    /**
     * 购物车
     */
    public class CartDao {
    
        /**
         * 添加一条购物车记录
         * @param cart
         * @return
         */
        public int saveCart(Cart cart){
    
            Connection cn = null;
            PreparedStatement ps = null;
    
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("insert into cart values(default ,?,?,?,?)");
    
                ps.setInt(1, cart.getUserId());
                ps.setInt(2, cart.getGoodsId());
                ps.setInt(3, cart.getNum());
                ps.setLong(4, cart.getCreateTime());
    
                int num = ps.executeUpdate();
    
                return num;
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return 0;
        }
    
        /**
         * 根据用户id和商品id查询购物车记录的id值
         * @param cart
         * @return
         */
        public int getCartByUserIdAndGoodsId(Cart cart){
    
            Connection cn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("select id from cart where userId=? and goodsId = ?");
    
                ps.setInt(1, cart.getUserId());
                ps.setInt(2, cart.getGoodsId());
    
                rs = ps.executeQuery();
    
                if(rs.next()){
                    return rs.getInt(1);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(rs,ps,cn);
            }
            return 0;
        }
    
        /**
         * 根据用户id和商品id修改购物车记录的数量
         * @param cart
         * @return
         */
        public int editCartNumByUserIdAndId(Cart cart){
            Connection cn = null;
            PreparedStatement ps = null;
    
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("update cart set num=num+? where userId=? and id=? ");
    
                ps.setInt(1, cart.getNum());
                ps.setInt(2, cart.getUserId());
                ps.setInt(3, cart.getId());
    
                int num = ps.executeUpdate();
    
                return num;
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return 0;
    
        }
    
        /**
         * 根据用户id和商品id删除购物车记录的数量
         * @param cart
         * @return
         */
        public int deleteCartByUserIdAndId(Cart cart){
            Connection cn = null;
            PreparedStatement ps = null;
    
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("delete from cart where userId=? and id=? ");
    
                ps.setInt(1, cart.getUserId());
                ps.setInt(2, cart.getId());
    
                int num = ps.executeUpdate();
    
                return num;
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return 0;
    
        }
    
        /**
         * 根据用户id查询购物车中的所有记录
         * @param cart
         * @return
         */
        public List<Cart> getCarts(Cart cart){
    
            Connection cn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("select c.*,g.img,g.price ,g.name as goodsName ,t.name as typeName from cart c left join goods g on g.id = c.goodsId " +
                        " left join types t on t.id = g.typeId " +
                        "where c.userId=? order by c.createTime DESC");
    
                ps.setInt(1, cart.getUserId());
    
                rs = ps.executeQuery();
    
                List<Cart> list = DBUtils.selectMore(Cart.class,rs);
    
                return list;
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(rs,ps,cn);
            }
            return null;
        }
    
    
    }
    
    

    2、前端页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ include file="/resource/pages/header.jsp"%>
    <html>
    <head>
        <title>我的购物车</title>
        <style>
            .goods{
                border:1px black solid;
                margin: 10px 0px;
            }
            .goods img{
                height: 100px;
            }
            #sumPrice{
                color: red;
                font-size: 30px;
                font-weight: 600;
            }
        </style>
    </head>
    
    <body>
    
    <div>
        <div>
            <input id="all" type="checkbox"> 全选
        </div>
    
        <c:forEach items="${list}" var="item">
            <div class="goods">
                <input class="one" type="checkbox">
                <img src="${item.img}">
                <span>${item.goodsName}</span>
                <span>${item.typeName}</span>
                <span class="price">${item.price*item.num}</span>
                <button onclick="miNum(${item.id})">-</button><span>${item.num}</span><button onclick="addNum(${item.id})">+</button>
                <a href="/shop/deleteCart?id=${item.id}">删除</a>
            </div>
        </c:forEach>
        <div>
            <div id="sumPrice">0.00</div>
        </div>
    </div>
    
    </body>
    <script>
        //使用js实现全选与反选,总价格是由js计算出来然后通过修改html来显示的
        $("#all").click(function () {
            var flg = $(this).prop("checked");
            $(".one").each(function () {
                $(this).prop("checked",flg);
            })
            sumPrice(); //每点击一个全选按钮都要重新计算
        })
    
        $(".one").each(function () {
            $(this).click(function () {
                var flg = $(this).prop("checked");
                if(flg){
                    if($(".one:checked").length==$(".one").length){
                        $("#all").prop("checked",flg);
                    }
                }else{
                    $("#all").prop("checked",flg);
                }
                sumPrice(); //每点击一次子选框也要重新计算
            });
        })
        //计算出总价格
        function sumPrice(){
            var sum = 0.00;
            $(".price").each(function(){
                //先获取价格区域的父级,然后再找子级的多选框
                var one = $(this).parent().children(".one");
                if(one.prop("checked")){//如果多显框时勾上的,就计算总价格
                    var price = $(this).text();
                    sum+=parseInt(price);
                }
            })
            $("#sumPrice").text(sum);
        }
        //减少
        function miNum(id){
            location.href="/shop/editCartNum?num=-1&id="+id;
        }
        //增加
        function addNum(id){
            location.href="/shop/editCartNum?num=1&id="+id;
        }
    
    
    </script>
    </html>
    
    

    二、订单实现

    订单在数据库中需要单独一张表来存储,一个订单中有多件商品,一件商品可以在多个订单中,所以这两者是多对多的关系。需要第三张表订单-商品映射表来存储订单与商品的关系,还要存储商品的数量。对于订单的操作同样有增删改查,但是此时比较麻烦,因为要同时对三张表进行操作。提单提交完成之后需要清空购物车。

    import com.qianfeng.shop.bean.Cart;
    import com.qianfeng.shop.bean.Goods;
    import com.qianfeng.shop.bean.OrderBean;
    import com.qianfeng.utils.DBUtils;
    import com.qianfeng.utils.JDBCUtils;
    
    import javax.management.Query;
    import javax.xml.transform.Result;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.List;
    
    public class OrderDao {
    
        /**
         * 根据用户id和订单id删除订单信息
         * @param orderBean
         * @return
         */
        public int deleteOrderByOrderIdAndUserId(OrderBean orderBean){
            Connection cn = null;
            PreparedStatement ps = null;
    
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("delete from orders where id= ? and userId=?");
    
                ps.setInt(1, orderBean.getId());
                ps.setInt(2, orderBean.getUserId());
    
                return ps.executeUpdate();
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return 0;
        }
    
        /**
         * 根据订单id删除映射商品信息
         * @param orderId
         * @return
         */
        public int deleteMappingByOrderIdAndUserId(int orderId){
            Connection cn = null;
            PreparedStatement ps = null;
    
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("delete from order_goods_mapping where orderId=?");
    
                ps.setInt(1, orderId);
    
                return ps.executeUpdate();
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return 0;
        }
    
        /**
         * 根据订单id查询映射商品的详细信息
         * @param orderId
         * @return
         */
        public List<Goods> getGoodsByOrderId(int orderId){
            Connection cn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("select ogm.num,ogm.price ,g.name,t.name as typeName,g.img " +
                        "from order_goods_mapping ogm " +
                        "left join goods g on g.id = ogm.goodsId " +
                        "left join types t on t.id = g.typeId " +
                        "where ogm.orderId=?");
                ps.setInt(1,orderId);
    
                rs = ps.executeQuery();
    
                List<Goods> list = DBUtils.selectMore(Goods.class,rs);
    
                return list;
    
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return null;
        }
    
        /**
         * 根据用户id查询当前用户的所有订单
         * @param userId
         * @return
         */
        public List<OrderBean> getOrdersByUserId(int userId) {
            Connection cn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("select o.id,o.sumPrice,o.status,o.createTime,ad.content" +
                        " from orders o " +
                        "left join address ad on ad.id = o.addressId " +
                        "where o.userId=?");
                ps.setInt(1,userId);
    
                rs = ps.executeQuery();
    
                List<OrderBean> list = DBUtils.selectMore(OrderBean.class,rs);
    
                return list;
    
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return null;
        }
    
    
        /**
         * 保存订单商品映射信息
         * @param carts
         * @param orderId
         * @return
         */
        public int[] saveMapping(List<Cart> carts,int orderId){
            Connection cn = null;
            PreparedStatement ps = null;
    
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("insert into order_goods_mapping values(?,?,?,?)");
    
                for (Cart cart : carts) {
                    ps.setInt(1,orderId);
                    ps.setInt(2,cart.getGoodsId());
                    ps.setInt(3,cart.getNum());
                    ps.setDouble(4,cart.getPrice());
                    ps.addBatch();
                }
                int[] num = ps.executeBatch();
                return num;
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return null;
        }
    
        /**
         * 保存订单,并且返回订单的id
         * @param orderBean
         * @return
         */
        public int saveOrder(OrderBean orderBean){
            Connection cn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                cn = JDBCUtils.getConnection();
                ps = cn.prepareStatement("insert into orders values(default ,?,?,?,?,?)",PreparedStatement.RETURN_GENERATED_KEYS);
                ps.setInt(1,orderBean.getUserId());
                ps.setInt(2, orderBean.getAddressId());
                ps.setDouble(3, orderBean.getSumPrice());
                ps.setInt(4,orderBean.getStatus());
                ps.setLong(5, orderBean.getCreateTime());
                int num = ps.executeUpdate();
    
                rs = ps.getGeneratedKeys();
                if(rs.next()){
                    return rs.getInt(1);
                }
            } catch (Exception e) {
                e.printStackTrace();
    
            }finally {
                JDBCUtils.close(ps,cn);
            }
            return 0;
    
        }
    }
    
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ include file="/resource/pages/header.jsp"%>
    <html>
    <head>
        <title>我的订单</title>
        <style>
            .order{
                border: 1px solid black;
            }
            .goods img{
                height: 100px;
            }
        </style>
    </head>
    <body>
    
        <c:forEach items="${orders}" var="item">
            <div class="order">
                <div>
                    <span>编码 : ${item.id}</span>
                    <span>${item.time}</span>
                    <span>${item.sumPrice}</span>
                    <c:if test="${item.status==1}">
                        <span>已支付</span>
                    </c:if>
                    <c:if test="${item.status==0}">
                        <span>未支付</span>
                    </c:if>
                    <a  href="/shop/deleteOrder?id=${item.id}">删除</a>
                    <br>
                    <span>${item.content}</span>
                </div>
                <div>
                    <c:forEach items="${item.goods}" var="goods">
                        <div class="goods">
                            <img src="${goods.img}">
                            <span>${goods.name}</span>
                            <span>${goods.typeName}</span>
                            <span>${goods.price} * ${goods.num}</span>
                        </div>
                    </c:forEach>
                </div>
            </div>
        </c:forEach>
    
    </body>
    </html>
    
    

    三、枚举

    枚举可以理解为有限制的多例,在当前类中定义多个实例供别人使用。我们之前学过单例模式,在程序运行期间只允许一个实例存在,如果要允许多个实例存在的话就需要使用多例模式。

    1、枚举类的注意事项

    • 定义枚举类都要使用关键字enum
    • 所有枚举类都是Enum的子类
    • 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,建议不要省略
    • 枚举类可以有构造器,但必须是private,默认就是private
    • 灭聚类也可以有抽象方法,但是枚举项必须重写该方法
    • switch语句可以使用枚举
    //枚举: 多例的简化形式
    public enum Message {
        //将零散的公共静态常量进行了分装, 将他们约束成一组
        REQUEST_SUCCESS (1,"请求成功"){
            public void method() {
    
            }
        },
        REQUEST_FAIL(-1,"请求失败"){
            public void method() {
    
            }
        },
        LGOIN_SUCCESS(2,"登陆成功"){
            public void method() {
            }
        },
        LGOIN_FAIL(-2,"登陆失败"){
            public void method() {
    
            }
        };
    
        private int code ;
        private String message;
    
        Message(int code, String message) {
            this.code = code;
            this.message = message;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getMessage() {
            return message;
        }
        //抽象方法必须在枚举项中重写
        public abstract void method();
    }
    
    

    2、常用方法

    • int ordinal() 获取枚举项的序号
    • int compareTo(E o) 比较两个枚举项
    • String name() 获取枚举枚举项的名称
    • String toString() 获取枚举项的字符串表现形式
    • <T> T valueOf(Class<T> type,String name) 使用字节码和名称获取枚举项
    • values() 它遍历枚举类的所有枚举值非常方便

    四、类加载

    1、定义

    如果程序要使用某个类,系统会通过加载、连接、初始化三步来实现对这个类进行初始化

    • 加载就是将.class文件读入内存,并为之创建一个Class对象
    • 连接:验证、准备、解析
    • 初始化:执行类的静态代码块,为类的静态成员初始化

    2、加载的时机

    只有当类真正被使用时,类才会被加载

    • 创建类的实例
    • 访问类的静态变量,或者为静态变量赋值
    • 调用类的静态方法
    • 使用反射方式强制创建某个类或接口对象的java.lang.Class对象
    • 加载某个类的子类
    • 直接使用java.exe命令来运行某个主类

    3、类加载器

    类加载器负责将.class文件加载到内存中,并为之生成对应的Class对象

    3.1 类加载器的作用

    • BootstrapClassLoader 根类加载器
      • 也被称为引导类加载器,负责Java核心类的加载
      • 比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
    • ExtensionClassLoader 扩展类加载器
      • 负责JRE的扩展目录中jar包的加载。
      • 在JDK中JRE的lib目录下ext目录
    • SysetmClassLoader 系统类加载器
      • 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
    • AppClassLoader 加载其他类
      • 负载一些非核心类和程序猿自己写的类

    3.2 双亲委派模型

    类加载器总是先让父类加载器去加载,如果父类加载器加载不了,一直到跟类加载器,如果父类加载器加载不了,则会让子类加载器加载。这样做的好处有两个:安全性,避免用户自己编写的类动态替换Java的一些核心类;同时也避免了类的重复加载。

    五、反射

    Java的反射是通过一个类的字节码获取这个类的所有信息,还可以进行操作

    1、获取字节码的三种方式

    • 对象.getClass()
    • 类名.class
    • Class.forName("类名")

    2、反射获取构造函数

    Class类的newInstance()方法是使用该类无参的构造函数创建对象,如果要使用有参构造,可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance("张三",20)方法创建对象

    3、反射获取成员变量

    • Class.getField(String)方法可以获取类中的指定字段(可见的)
    • 如果是私有的可以用getDeclaredField("name")方法获取
    • 通过get(obj) 和set(obj, "李四")方法可以获取和设置指定对象上该字段的值, obj指的是这个类的对象
    • 如果是私有的需要先调用setAccessible(true)设置访问权限放开

    4、反射获取成员方法

    • Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
    • 调用invoke(Object, Object...)可以调用对象的这个方法

    六、动态代理

    动态代理让我们在不破坏代码的情况下增加新的功能,常用于Java项目检测代码运行效率。

    1、Java中动态代理

    利用对象的类的字节码接口,写出一个新的类到本地区,通过编译器直接编译成.class文件,再通过类加载器加载进来。但是这样做有一个缺点,就是代理的对象必须实现接口。

    • 在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象
    • public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
    • 最终会调用InvocationHandler的方法InvocationHandler Object invoke(Object proxy,Method method,Object[] args)

    2、cglib

    非Java原生的动态代理,效率更高,限制更小,并且可以代理没有接口的类,它的原理是生成一个原始类的子类对象

    • 要想使用cglib必须要导入四个包:ant、ant-launcher、asm、cglib。
    public static void main(String[] args) {
        //创建运行器
        MethodInterceptor mi = new MethodInterceptor() {
            @Override
            public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
                System.out.println("运行前");
                arg3.invokeSuper(arg0, arg2);
                System.out.println("运行后");
                return null;
            }
        };
        //获取代理类
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(Demo.class);
        //运行任务
        enhancer.setCallback(mi);
        //创建代理对象
        Demo d = (Demo)enhancer.create();
        d.method();
    }
    

    相关文章

      网友评论

          本文标题:第十五篇学习总结

          本文链接:https://www.haomeiwen.com/subject/riwtxhtx.html