MyBatis
代理模式
-
代理模式的作用:
-
控制目标对象的访问
-
增强功能
-
静态代理
-
静态代理的特点
-
目标对象和代理对象实现同一个业务接口
-
目标对象必须实现接口
-
代理对象再程序运行前就已经存在
-
能够灵活的进行目标对象的切换,却无法进行功能的灵活处理(动态代理的主要解决此问题)
-
-
静态代理的实现:静态代理要求目标对象和代理对象实现同一个业务接口,代理对象中的核心功能是由目标对象来完成,代理对象负责增强功能
-
目标对象:实现业务接口中的功能
-
代理对象:完成除主业务之外的其他业务(实现业务接口,但业务功能必须由目标对象亲自实现)
-
在测试时,有接口和实现类,必须使用接口指向实现类(规范)
面向接口编程
-
类中的成员变量设计为接口,方法的形参设计为接口,方法的返回值设计为接口,调用时接口指向实现类
动态代理
-
代理对象在程序中运行的过程中动态在内存中构建,可以灵活的进行业务功能的切换
JDK动态代理
-
JDK动态代理的特点
-
目标对象必须实现业务接口
-
代理对象不需要实现业务接口
-
动态代理的对象在程序运行前不存在,在程序运行时动态的在内存中构建
-
动态代理灵活地进行业务功能的切换
-
本类中的方法(非接口中的方法)是不能被代理的,并不能将Proxy类型的数据转换成实现类的数据(会报出异常,类转换异常ClassCastException)
-
-
JDK动态代理用到的类和接口
-
是使用现有的工具类完成JDK的动态实现
-
Proxy类
-
是java.lang.reflect.Proxy包下的类,使用Proxy.newProxyInstance()方法专门用来生成动态代理对象
-
public static Object newProxyInstance(ClassLoader loader,//类加载器 Class<?>[] interfaces,//目标对象实现的所有接口 InvocationHandler h//类似于Agent代理对象的功能,代理的功能和目标对象的业务功能调用在这 ) throws IllegalArgumentException {...}
-
-
Method类
-
反射使用的类,用来进行目标对象的方法的反射调用
-
Method对象接受我们正在调用的方法,sing(),show()
-
method.invoke();-->手工调用目标方法
-
-
InvocationHandler接口
-
实现代理和业务功能的,调用时使用匿名内部实现
-
-
-
在代码中进行动态代理的实现
-
public class ProxyFactory { //类中的成员变量设计为接口,目标对象 Service service; //传入目标对象 public ProxyFactory(Service service) { this.service = service; } //返回代理对象 public Object getService(){ return Proxy.newProxyInstance( //ClassLoader loader,类加载器,完成目标对象的加载 service.getClass().getClassLoader(), //Class<?>[] interfaces,目标对象实现所有接口 service.getClass().getInterfaces(), //InvocationHandler h);实现代理功能的接口,我们使用的是匿名内部实现 new InvocationHandler() { @Override public Object invoke( //创建代理对象 Object proxy, //method就是目标方法sing(),show() Method method, //目标方法的参数 Object[] args) throws Throwable { //代理功能 System.out.println("预定时间..."); //代理功能 System.out.println("预定场地..."); //主业务功能 //无论传入的什么方法,都会进行调用 Object invoke = method.invoke(service, args); //代理功能 System.out.println("结算费用..."); //目标方法的返回值 return invoke; } } ); } }
-
CGLib动态代理(子类代理)
-
通过动态的在内存中构建子类对象,重写父类的方法进行代理功能的增强,若目标对象没有实现接口,则只能通过CGLib子类代理来进行功能的增强
-
子类代理是通过对象字节码框架ASM来实现的
-
后期可以通过spring框架来轻松实现
-
工具类Enhancer en = new Enhancer()完成子类代理对象的创建
-
en.setSuperclass(service.getClass())设置父类
-
en.setCallback(this(这里指的是成员变量));设置回调函数
-
en.create();创建子类对象
-
注意:
-
被代理的类不能被final修饰
-
目标对象的方法如果为final/static,那么就不会拦截,即不会执行目标对象额外的业务方法
-
MyBatis框架
框架概述
三层架构
-
在项目的开发中,遵循的一种形式模式:分为三层
-
界面层:用来接受客户端的输入,调用业务逻辑层进行功能处理,返回结果给客户端,过去的servlet就是界面层的功能
-
业务逻辑层:用来进行整个项目的业务逻辑处理,向上为界面层提供处理结果,向下对数据访问层索要数据
-
数据访问层:专门用来进行数据库的增删改查操作,向上为业务逻辑层提供数据
-
各层之间的调用顺序是固定的,不允许跨层访问
-
界面层-------->业务逻辑层------>数据访问层
-
界面层<-------业务逻辑层<------数据访问层
MyBatis框架入门
添加框架的步骤:
-
添加依赖
-
添加配置文件
具体步骤:
-
创建数据库,新建表
-
新建maven项目,选quickstart模板
-
修改目录,添加缺失的目录,修改目录属性
-
修改pom.xml文件,添加MyBatis的依赖,添加mysql依赖
-
<!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <!--mysql依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency>
-
-
修改pom.xml文件,添加资源文件指定
-
<!--添加资源文件的指定--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build>
-
-
在idea中添加数据库的可视化
-
添加jdbc.properties属性文件(数据库的配置)
-
添加SqlMapConfig.xml文件(系统核心配置文件),MyBatis的核心配置文件
-
头文档文件位置
-
<?xml version = "1.0" encoding = "UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 读取属性文件 属性: resource:从resource目录下寻找指定名称的properties文件 url:使用绝对路径寻找加载文件 --> <properties resource="jdbc.properties"></properties> <!-- SqlMapConfig.xml文件配置 配置数据库环境变量(数据库连接配置) default:在environments标签中对指定id的environment进行配置 --> <environments default="development"> <!-- 测试环境变量--> &
-