在provity集合中的表示:
绿色#是注释
黑色的是key
蓝色的是value
pattern:模式
+:右对齐
-:左对齐
apperder:追加器 (自动生成)
rollfile:(自动生成)
rootlogger:日志记录器 控制输出日志的级别
掌握三点即可:
①、级别:rootlogger
②、输出到什么位置: console
③、格式:
%C:找出哪个类
%L:找出哪一行
%M:具体的日志信息
%N:换行
设计模式有23种
一、回调模式:
回调模式不属于23种设计模式之一
some类的某个对象some的某个方法doTest()调用了other类对象的某个方法doOther(),而doOther()方法又反过来调用了some对象的另一个方法doSome(),那么这种程序结构,被称为回调模式,doSome()方法被称为回调方法,some类称为回调类,some对象称为回调对象。
一般情况下,doSome()方法是以下面的形式出现在some类中的
让some类实现一个接口,而接口中有方法doSome(),这样的话,some类必须要实现doSome()方法,也就是说,doSome()方法就以接口的形式出现在了some类,此时的这个接口被称为回调接口。
没有方法的接口被称为标识接口
二、代理模式:
1、什么是代理模式?
代理模式是GoF四人组提出的23种设计模式之一,若一个类T不能或者不适合让另外一个类C直接访问,或者类T在不修改自身源码的前提下,想增强业务逻辑功能,此时就可以通过一个中间类P来完成这些需求,那么这个中间类P就成为代理类,T称为目标类
换个角度思考,那就是说,这个客户类C若想与目标类T打交道,那么都需要通过代理类P完成,即客户类只能与代理类P类发生直接的联系。代理类P的对象可以代表目标类T与客户类打交道。
(客户类不能直接访问目标类)
==========================================================================================
2、代理模式中的角色?
目标类
代理类
客户类
3、代理模式的目的?
①为了保护和隐藏某一个类,可以使用代理模式
②在不修改某个类的源码的情况下,为了增强某个类的功能,可以使用代理模式
4、代理模式的分类?
根据代理类创建时间的不同,或者说根据代理关系确立时机的不同,可以将代理模式分为两类 1》静态代理
2》动态代理
动态代理又根据实现技术的不同,可分为若干类,例如:
1) JDK的动态代理
2)CGLIB动态代理
3)Javassist动态代理
==========================================================================================
.......
5、静态代理模式:
①什么是静态代理?
静态代理的代理类是由程序员手工编写的,代理关系是在代码运行之前就已经确立。
②使用静态代理模式的要求?
1)代理类要与目标类具有相同的业务方法。这个要求一般是通过相同的业务接口来进行约束。当然也可以让代理类与目标类继承自相同的父类。
目标类的对象,称为目标对象;代理类的对象称为代理对象。
目标类中的方法,称为目标方法;代理类中的方法,称为目标方法。
2)代理类中要执有目标类对象的引用,以便于代理方法直接调用目标对象的目标方法。
3)静态代理类中的目标对象,在代理类中创建,而不是由外部传入的,这样代理类就起到了保护和隐藏目标对象的作用。
③实现
==========================================================================================
6、动态代理模式
①什么是动态代理?
动态代理的代理类是由工具类或工厂类动态生成的,不是由程序员手工定义的。代理关系是在程序运行过程中确立的。
②使用动态代理模式的要求?
1)动态代理模式中没有不用定义代理类。
2)目标对象是在客户类中创建的,因为工具或工厂在生成代理类时,需要目标对象。而工具或工厂类是由客户类调用的,由客户类调用工具或工厂类生成代理类,并创建代理对象。
3)由于目标对象在客户类中创建,所以这种代理模式无法实现保护和隐藏目标对象的目的。使用动态代理的目的是在不修改目标类的前提下,增强目标方法功能。
4)由于目标类是由工具类或工厂类动态生成的,其生成过程具有一般性,可以为任何目标类生成代理类及代理对象,不同的目标类其增强需求是不同的,是具有个性化的。这个个性化功能增强,代理类委托给了另外一个类E实现。这个类 称为委托类。
5)使用静态代理和动态代理的目的是不同的:
1>使用静态代理的目的是:保护和隐藏对象
2>使用动态代理的目的是:在不修改目标类的前提下,增强目标对象
③JDK的Proxy动态代理
1>使用要求:目标类必须实现业务接口,使用JDK的Proxy动态代理,要求目标类必须是实现接口的类。
2>动态代理类的名称:
名称由三部分构成:$+Proxy+数字,其中数字表示当前的JDK的Proxy所生成的代理类的索引,索引从0开始计数。
==========================================================================================
7、CGLIB动态代理:
①什么是CGLIB
CGLIB,Code Gereration Library代码生成库是一个开源项目,是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。
CGLIB的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
②应用场景
CGLIB动态代理,其所要增强的目标类可以没有实现任何业务接口,当然若目标类实现了业务接口,也可以使用CGLIB生成代理类。
③代理生成原理
CGLIB使用子类扩展父类的方式来生成代理对象的,即CGLIB会动态生成目标类的子类作为代理类,并创建其对象,即代理对象。
④使用要求
1)使用目标类不能使用final
2)要求类要具有无参构造器
⑤jar包下载
从github官网下载
=========================================================================================== 当执行代理对象的代理方法时,代理方法会调用invoke()方法
proxy:代理对象
method:目标方法
args:目标方法参数列表
proxy:目标方法的代理对象
8、适配器设计模式
1)适配器模式的应用场景
将一个接口转换成客户希望的接口
在一个接口中的功能扩展到另一个类中
使原本由于接口不兼容而不能一起工作的那些类一起工作
2)适配器实现方式分类
①多功能适配器
②单功能适配器
3)缺省适配器模式
当一个接口中有大量抽象方法时,若一个类只需要使用其中一个部分方法时,其他类并不需要访问,那么会出现一个问题:需要定义的这个类(实现了该接口)必须实现这个接口中的所有方法,而这些方法中由于大多数方法并不需要访问,所以采用空实现的方法来实现(只有一对大括号,你没有真正的内容),这是比较麻烦的
此时可以定义一个一般性的类,让这个类空实现所有方法,当然,也可空实现不使用的方法,让真正要使用的方法以抽象方法的形式出现,这样以后再定义该接口的实现类,就不需要直接实现这个接口,而是对继承这个一般性的类,重写所有真正访问的方法即可。
这种程序结构称为缺省适配器设计模式。
9、模板方法设计模式
该设计模式解决的问题是:具有固定算法(步骤)的应用。但这些算法步骤,又针对不同的用户(情况)具有不同的实现方式。
在该设计模式中,具有两大类方法:模板方法、步骤方法
步骤方法又根据其实现情况分为三种:抽象方法、最终方法、钩子方法
抽象方法:要求子类必须要实现的方法,
抽象方法只能出现在抽象类中,抽象类中不一定有抽象方法
最终方法:final修饰的方法,不能被子类重写。
钩子方法:具有默认的实现,但可以被子类重写。
===========================================================================================
10、mybatis
工具类中的异常一般是要抛出给调用者的,不应该使用try-catch。
?: <=1,表示当前子标签最多出现一次
* : >=0,表示当前子标签可以出现多个,也可以不出现
+ : >=1,表示当前子标签最少出现一次,也可以出现多次
(无符号):=1,表示当前子标签有且仅有一个
==================================================
,:表示前后两个子标签间有顺序关系
| :表示前后两个子标签间无顺序关系
11、主配置文件
1)<transactionManager type = "JDBC"/>
该标签用于指定事务管理器,type的取值有两个:
JDBC:使用JDBC事务管理器
MANAGED:使用第三方事务管理器,例如使用Spring的事务管理器
2)<dataSource type = "POOLED">
该标签用于指定数据源类型,type的取值有三个:
POOLED :使用连接池技术(默认使用的是mybatis内置连接池)
UNPOOLED :不使用连接池技术
JNDI :Java Naming-Directory Interface,Java命名与目录接口,这是一个容器。
12、注册映射文件:
使用下面的注册方式需要满足以下四点要求
1)映射文件要与Dao接口在同一个包中
2)映射文件名要与Dao接口的简单类名相同
3)映射文件的<mapper/>标签的namespace属性值为Dao接口的全限定性类名
4)使用动态Mapper
满足以上四个条件,那么这里的class属性就可以填写Dao接口所在的包名
这里的parameterType属性可以省略
SQL语句中的values中的内容,要求必须满足#{},其中name,age,score
指的是参数对象的属性,其底层是通过反射机制从参数对象的get方法中获取到其相应的属性值。
13、API详解:
0、线程安全问题出现的条件:
1)只有单例对象才可能出现线程安全问题
2)多线程环境,即多个线程会共享这个单例对象
3)单例对象中具有可修改的成员变量
1、SqlSession接口:
该对象是多例的(与单例模式相反)
2、SqlSessionFactory接口:
这个对象的作用为了创建SqlSession对象,而由于SqlSession对象是多例的,每创建一次 SqlSession对象,都需要一个SqlSessionFactory对象去创建。
但SqlSessionFactory对象是重量级组件,但DefaultSqlSessionFactory类中不存在可修改的 成员变量。所以SqlSessionFactory对象可以定义为单例的,其生命周期与整个应用的相同。
3、SqlSessionFactoryBuilder类:
该类对象的作用仅仅是为了创建SqlSessionFactory对象,由于SqlSession是单例对象,一旦创建完毕,SqlSessionFactoryBuilder对象就可以定义为一个局部变量。SqlSessionFactory创建完毕,就可以销毁了。
对单表CURD操作
CURD:增删改查
c:create,插入
u:update,修改
r:retrive,查询
d:delete,删除
当动态参数类型为基本数据类型或者String时,#{}作用仅仅是个占位符,其中填写什么内容都可以。当动态参数类型为自定义类型的对象时,#{}中填写的是该对象的属性名。
resultType与resultMap指的是查询出每一条记录所要封闭的对象类型,并非查询的结果集类型
ofType解释为element of type,元素类型
总结:
#{}中可以填写什么内容:
1、参数对象的属性
2、任意内容,参数对象为基本数据类型或者String时,起占位符作用
3、map的key
4、map的key属性,当map的key为对象时
================================================================================================
1、mapper的动态代理对象底层也是通过调用SqlSession的selectOne()或selectList()方法执行查询
2、但若方法的返回类型为List,则系统会调用selectList()方法,其他所有类型的返回值,系统调用的都是selectOne()
3、即系统调用selectOne()或selectList()方法的判别方法标准是方法的返回值类型是否为List.
使用mapper的动态代理要求:
1、session.getMapper()中的参数为所要代理的接口类型
2、映射文件的namespace属性值为所要代理的接口的全限定性类名
3、映射文件中的statement的ID名称必须要与接口中相应方法的名称相同