商品订单的完成
首先在购物车页根据当前登陆用户id查询数据库中购物车表的该用户所有购物车记录,并显示出来
<form action="/shop/toOrder">
<input name="userId" value="${item.userId}" type="hidden">
<div><input type="checkbox" id="all">全选</div>
<%--为了到订单页面只显示以选择的商品,所以要把当前每件以选择的goodsId传过去,让订单页自己查询购物车相应商品--%>
<c:forEach items="${list}" var="item">
<div class="goods">
<input type="checkbox" class="one" name="goodsIds" value="${item.goodsId}">
<img src="${item.img}" >
<div>${item.goodsName}</div>
<div>${item.typeName}</div>
<div class="price">${item.price*item.num}</div>
<button type="button" onclick="miNum(${item.goodsId})">-</button>
<span>${item.num}</span>
<button type="button" onclick="addNum(${item.goodsId})">+</button>
<a href="/shop/deleteCart?id=${item.id}">删除</a>
</div>
</c:forEach>
<div>
<div id="sumPrice">0.00</div>
</div>
<input type="submit" value="提交订单">
</form>
/toOrder
显示在form表单中,c:each 循环展示每个购物记录。提交按钮,根据当前check 复选框绑定的goodsid在数据库中查询相关购物记录并显示订单。。
//展现 已选择的商品,总价,地址。
//list显示
//传过来goodsIds和隐藏的userId ,查找.
Cart cart=WebUtils.populate(Cart.class,req);
List carts=cartService.getCartsInGoodsIds(cart);
req.setAttribute("carts",carts);
double sumPrice=0.0;
for (Cart cart1 : carts) {
sumPrice+=cart1.getPrice()*cart1.getNum();
}
req.setAttribute("sumPrice",sumPrice);
List addrs=addrService.getAddrs(cart.getUserId());
req.setAttribute("addrs",addrs);
req.getRequestDispatcher("/WEB-INF/pages/toOrder.jsp").forward(req,resp);
toorder.jsp 显示当前已购物车车中的记录,和地址。生成初步订单模型,点击确定按钮,调用web层应用,保存订单信息和映射表
<form action="/shop/toPay">
<div>
<div id="addr">
请选择收货地址
<select name="addressId">
<c:forEach items="${addrs}" var="address">
<option value="${address.id}">${address.content}</option>
</c:forEach>
</select>
</div>
<div id="head">
<c:forEach items="${carts}" var="item">
<input name="goodsIds" value="${item.goodsId}" type="hidden">
<div class="goods">
<img src="${item.img}">
<span>${item.goodsName}</span>
<span>${item.typeName}</span>
数量<span>${item.num}</span>
单价<span>${item.price}</span>
价格<span>${item.price*item.num}</span>
</div>
</c:forEach>
</div>
<div id="sumPrice">
订单价格:${item.sumPrice} <br>
<input type="submit" value="去支付">
</div>
</div>
</form>
插入订单表信息,包括订单表,和第三张表,联系用户id和商品详细信息的表。同时删除购物车记录。
OrderBean orderBean=WebUtils.populate(OrderBean.class,req);
User user= (User) req.getSession().getAttribute("user");
orderBean.setUserId(user.getId());
//保存用户订单和映射表
boolean flg=orderService.saveOrder(orderBean);
req.getRequestDispatcher("/shop/toCartPage").forward(req,resp);
public boolean saveOrder(OrderBean orderBean){
// orderBean传过来有addressid,userId,goodsIds
//需要设置sumPrice,status,createTime
Cart cart=new Cart();
cart.setGoodsIds(orderBean.getGoodsIds());
cart.setUserId(orderBean.getUserId());
List carts=cartDao.getCartsInGoodsIds(cart);
double sumPrice=0.0;
for (Cart cart1 : carts) {
sumPrice+=cart1.getPrice()*cart1.getNum();
}
orderBean.setSumPrice(sumPrice);
orderBean.setStatus(1);
orderBean.setCreateTime(System.currentTimeMillis());
//保存订单,返回订单号
int orderId=orderDao.SaveOrder(orderBean);
int num=0;
if (orderId>0){//保存订单成功,并返回订单id,继续保存映射表
int n[]=orderDao.SaveMapping(carts,orderId);
if (n!=null&&n.length>0){//映射表保存之后,删除购物车信息Cart
for (Cart cart1 : carts) {
num=cartDao.deleteCartById(cart1);
}
}
return num>0;
}
return false;
}
枚举类
public enum Week2 {
//定义变量,指向对象
MON("星期一") ,TUE("星期二") ,WED("星期三") ,THU("星期四") ,FRI("星期五") ,SAT("星期六") ,SUN("星期日") ;
String name ;
//私有化构造
private Week2(String name){
this.name = name;
}
public String getName() {
return name;
}
}
定义枚举类要用关键字enum
所有枚举类都是Enum的子类
枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略
枚举类可以有构造器,但必须是private的,它默认的也是private的。
枚举类也可以有抽象方法,但是枚举项必须重写该方法
swicth语句可以使用枚举
类加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化
加载
就是指将.class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化 就是我们以前讲过的初始化步骤
类加载器的分类
Bootstrap ClassLoader 根类加载器
Extension ClassLoader 扩展类加载器
Sysetm ClassLoader 系统类加载器
AppClassLoader 应用类加载器
类加载器的作用
BootstrapClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载 、比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
ExtensionClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录
SysetmClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
AppClassLoader 加载其他类
负载一些非核心类和程序猿自己写的类
反射
榨汁机案例
interface Fruit {
public void squeeze();
}
class Apple implements Fruit {
public void squeeze() {
System.out.println("榨出一杯苹果汁儿");
}
}
class Orange implements Fruit {
public void squeeze() {
System.out.println("榨出一杯桔子汁儿");
}
}
class Juicer {
public void run(Fruit f) {
f.squeeze();
}
}
public static void main(String[] args) throws Exception {
//从本地读取配置文件
BufferedReader br = new BufferedReader(new FileReader("config.txt"));
//创建输入流对象,关联配置文件
Class<?> clazz = Class.forName(br.readLine()); //读取配置文件一行内容,获取该类的字节码对象
Fruit f = (Fruit) clazz.newInstance(); //通过字节码对象创建实例对象
Juicer j = new Juicer();
j.run(f);
}
动态代理
代理: 本来应该自己做的事情,请了别人来做,被请的人就是代理对象
动态代理:在程序运行过程中产生的这个对象,而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理对象
代理可以使我们在不破坏源代码的情况下增加新的功能
原始jdk动态代理
public static Object get(String str){
//想要实现一个日志系统,给所有的方法加上时间测试,假设有100个类,共1000个方法
//第一种方式: 在原始类的原始方法中添加检测时间的代码 缺点 : 原始类中的代码较多,修改时的安全性得不到保障 耗时耗力 扩展性极差
//第二种方式: 静态代理, 不修改任何原始代码, 重新定义一个类,实现和原始类一样的接口,重写一样的方法
// 在代理类的方法中调用原始类的方法,并且加上检测代码,
// 优点 : 安全性较高 提高了扩展性
// 缺点 : 代码量太大了 重写100个类, 重写1000个方法
//第三种方式: 动态代理, 创建一套工具, 提供必要的参数, 由这套工具来帮我们生成代理类的对象
// 优点 : 节省代码量 重写100次代理方法
//帮助我们自动生成代理类
if(str.equals("com.qianfeng.part04.Demo")){
Demo demo =new Demo();
//提供 原始类的类加载器, 原始类的所有接口, 需要执行的代码
DemoInterface demoInterface = (DemoInterface) Proxy.newProxyInstance(demo.getClass().getClassLoader(),
demo.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
long start = System.currentTimeMillis();
Object obj = method.invoke(demo,args);
long end = System.currentTimeMillis();
System.out.println(new Date().toString()+method.getName()+"方法运行耗时:"+(end-start)+"毫秒");
return obj;
}
});
return demoInterface;
}
return null;
}
cglib
定义
非java原生的动态代理, 效率更高,限制更小
可以代理没有接口的类
使用
导包
演示
public static void main(String[] args) {
//导入包 cglib-core asm ant ant-launcher
//创建运行器
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();
}