1. 基于Mybatis的增删改查,Mapper.xml标签中:
<select></select>
标签中的parameterType属性可省略,ResultSet属性必须写
insert/update/delete
标签只有id属性
2. Mybatis须手动操作事务,JDBC则是自动操作事务。
3. 为什么使用TreadLocal来实现?
TreadLocal可以当作一个容器,进行存和取。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本
4.代理模式(设计模式中的一种)代理模式的作用:功能增强、控制访问
参考笔记1参考笔记2
- 静态代理:需手写代理类,且目标类固定。
静态代理实现步骤:
- 创建接口,定义目标类和代理类共同完成的功能
- 创建目标类,实现接口中的功能
- 创建代理类,调用目标类中的方法,可进行功能的增强
- 创建客户类,调用代理类的方法间接访问目标类
静态代理缺点:接口中的功能一旦添加或者修改,目标类和代理类必须全部修改,违背OCP开发原则。
示例(买卖U盘)如下:
接口:
package com.zuo.function;
public interface sellU {
/*根据U盘数量定义价格的方法*/
float sell(int mount);
}
目标类:
package com.zuo.target;
import com.zuo.function.sellU;
public class factorySell implements sellU {
/*客户类不能直接访问工厂,所以需要一个代理*/
@Override
public float sell(int mount) {
float price = 85.0f;
return price;
}
}
代理类:
package com.zuo.daili;
import com.zuo.function.sellU;
import com.zuo.target.factorySell;
public class dailiSell implements sellU {
/*确定代理哪个工厂,调用工厂的方法,也可进行功能的增强*/
private factorySell factory = new factorySell();
@Override
public float sell(int mount) {
float price = factory.sell(100);
price += 25;
return price;
}
}
客户类:
package com.zuo.kehu;
import com.zuo.daili.dailiSell;
public class kehu1 {
public static void main(String[] args) {
/*客户确定代理*/
dailiSell daili1 = new dailiSell();
float price = daili1.sell(100);
System.out.println("客户买的U盘价格为:" + price);
}
}
- 动态代理(知道是啥,怎么用,莫深究):
why出现?解决了静态代理的缺点,目标类即使很多,代理数量可以很少,修改接口中的方法不会影响代理类。
概念:在程序执行过程中,使用jdk的反射机制,创建代理对象,并**动态的**指定要代理的目标类,为不同的目标随时创建代理。(是一种创建java对象的能力,不再需要手动写代理类)
jdk动态代理,必须有接口,目标类必须实现接口,没有接口时,需要使用cglib动态代理。
创建对象的条件:
@创建类文件,并将其编译成class字节码文件。
@使用构造方法,创建类的对象。
利用动态代理改造卖U盘例子:
功能接口:
package com.zuo.function;
/**
* @Author
* @Date 2022-06-01
* @Description:实现卖U盘的功能
**/
public interface sellU {
//提供卖U盘的功能
float sell(int mount);
}
目标类:
package com.zuo.target;
import com.zuo.function.sellU;
/**
* @Author
* @Date 2022-06-01
* @Description:目标类
**/
public class factory1 implements sellU {
@Override
public float sell(int mount) {
float price = 85.0f;
return price;
}
}
Handler类:
package com.zuo.handler;
import com.zuo.target.factory1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @Author
* @Date 2022-06-01
* @Description:利用动态代理模式,在这个类中完成代理的功能和目标类的调用
**/
public class Myhandler implements InvocationHandler {
Object res = null;
private Object target = null;
//动态代理目标是活动的,不是固定的,需要传入进来,创建动态目标对象的一个条件是构造方法
public Myhandler(Object target) {
this.target = target;
}
//目标类方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*执行目标类的方法*/
res = method.invoke(target,args);
/*如果返回值不为空*/
if (res!=null) {
/*进行功能增强*/
Float price = (Float)res;
price +=25;
/*相当于返回值*/
res = price;
}
/*功能更增强*/
System.out.println("淘宝商家给你一个优惠券");
return res;
}
}
客户类:
package com.zuo.test;
import com.zuo.function.sellU;
import com.zuo.handler.Myhandler;
import com.zuo.target.factory1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @Author
* @Date 2022-06-01
* @Description:
**/
public class test1 {
public static void main(String[] args) {
/*创建目标类对象*/
factory1 fac = new factory1();
/*创建handler对象,将目标类作为参数传进去*/
InvocationHandler handler = new Myhandler(fac);
/*利用反射机制创建代理对象,并将其转为接口*/
sellU proxy= (sellU)Proxy.newProxyInstance(fac.getClass().getClassLoader(),
fac.getClass().getInterfaces(), handler);
/*通过代理执行方法*/
float price = proxy.sell(1);
System.out.println("通过代理调用方法:"+price);
}
}