(78条消息) 代理模式的使用总结_ZYF-ZYF的博客-CSDN博客_代理模式有啥用
代理的目的:目的对象不可访问,通过代理对象来进行访问
作用:控制目标的访问,增强的功能
代理的分类:静态代理和动态代理
代理模式的特点:
1.目标对象和代理对象实现同一个业务接口
2.目标对象必须实现接口
3.代理对象在对象运行前就已经存在
4.能够实现目标对象的切换,但是无法实现功能的灵活切换
下面的三个程序:
总结一定是要面向接口编程
统一来写一个service.Service 这样的类,然后就是要把imp.。。。放在service下面和Service这个接口是并列的,面向接口编程,只要是实现了某个接口,后面来实现的时候一定是要将接口放在前面的,但凡有接口实现类,就要用接口来指向实现类
面向接口编程:
类中的成员变量设计为接口;
方法的形参设置为接口;
方法的返回值设计为接口;
调用时接口指向类;
package org.example.service;
public interface Service {
void sing();
}
package org.example.service.imp;
import org.example.service.Service;
public class Agent implements Service {
Service target;
public Agent(Service target) {
this.target=target;
}
@Override
public void sing(){
System.out.println("预定地点");
System.out.println("预定时间");
System.out.println("预定费用");
target.sing();
}
}
package org.example.service.imp;
import org.example.service.Service;
public class SuperLiu implements Service {
@Override
public void sing() {
System.out.println("刘德华在唱歌");
}
}
package org.example.service.imp;
import org.example.service.Service;
public class SuperZhou implements Service {
@Override
public void sing() {
System.out.println("周润发在唱歌");
}
}
动态代理:
1.目标对象必须实现接口
2.代理对象不用实现接口
3.动态代理的对象在运行之前是不存在的,程序运行时动态地在内存中构建
4.动态代理灵活来进行业务的切换
5.本类中的方法是不能够被代理的,所以不能实现增强的目的
JDK动态代理的类和接口:
Proxy的类:
它是java.lang.reflect.Proxy下面的类,他有一个方法newProxyInstance()来生成专门的动态代理对象。
动态代理真的是太神奇了:
package org.example.service;
public interface Service {
void sing();
String show();
}
package org.example;
import org.example.service.Service;
public class SuperLiu implements Service {
@Override
public void sing() {
System.out.println("liuzaichangge");
}
@Override
public String show() {
return "SuperLiu is singing";
}
}
package org.example;
import org.example.service.Service;
public class SuperZhou implements Service {
@Override
public void sing() {
System.out.println("zhouzaichange");
}
@Override
public String show() {
return "SuperZhou is singing";
}
}
package org.example.proxy;
import org.example.service.Service;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
Service target;
public ProxyFactory(Service target){
this.target=target;
}
public Object getAgent(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理开始了");
Object invoke = method.invoke(target, args);
System.out.println("代理结束了");
return invoke;
}
}
);
}
}
GGLib代理又称为子类代理,通过动态地在子类中构建子类对象,重写父类地方法来实现增强,如果目标地接口没有对应地方法,那么就需要CGLib来实现代理
CGLib被代理地类不能是final/static的,否则报错
MVC三层架构:
界面层:全局的大佬儿,向下为业务逻辑层
业务逻辑层:向上为界面层,向下为数据管理层
数据管理层:专门来进行数据的增删改查,向上为业务层来提供数据
SSM
spring:核心是IOC和AOP,是用来集合框架的,有20多个模块
SpringMVC:这是用来优化servelet的,数据上传处理更简单
MYbatis:在持久层里面,极大的简化了JDBC
框架是一个半成品的软件,将公共的、重复的功能解决掉
所有的框架都是1添加依赖
2 添加配置文件
数据库连接池:
我发现了一件非常好玩的事儿,就是进行增删改查的时候主要先看的是StudentMap里面的语句和参数根据里面的语句和参数然后来更新我们的参数
mybatis主要是有一个SqlMapConfig的配置文件,里面主要是三个一个是propertites一个是enviroments还有一个是maps propertites里面是jdbc的各种原始参数,envirments里面主要是要配置一个datasources和transactionManager,datasource里面涉及到了常量池一些知识,transactionManager里面就涉及由程序员控制还是由SPRING来控制的问题
<?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>
<!--读取属性文件-->
<properties resource="jdbc.properties"></properties>
<!--配置环境变量-->
<environments default="development">
<environment id="development">
<!-- 这个transaction里面的JDBC表示的是由程序员自己来操作数据库-->
<transactionManager type="JDBC">
</transactionManager>
<!-- 这个dataSource里面的POOLED表示的是
jndi表示在服务器端、TOMCAT端来进行数据库的控制
POOLED表示在数据连接池来进行数据库的操作
UNPOOLED表示不使用数据库连接池
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 注册map.xml文件-->
<mappers>
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
</configuration>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="wsy">
<!-- 完成查询全部学生的功能,返回的数值必须是泛型-->
<select id="getAll" resultType="org.example.pojo.student">
select id,name,email,age
from student
</select>
<select id="getById" parameterType="int" resultType="org.example.pojo.student">
select id,name,email,age
from student
where id = #{id}
</select>
<select id="getByName" parameterType="String" resultType="org.example.pojo.student">
select id,name,email,age
from student
where name like '%${name}%'
</select>
<insert id="insert" parameterType="org.example.pojo.student">
insert into student(id,name,email,age) values(#{id},#{name},#{email},#{age})
</insert>
<delete id="delete" parameterType="int">
delete from student where id=#{id}
</delete>
<update id="update">
update student
set name=#{name},email=#{email},age=#{age}
where id=#{id}
</update>
</mapper>
package org.example.pojo;
public class student {
private Integer id;
private String name;
private String email;
private Integer age;
public student() {
}
public student(Integer id, String name, String email, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
public student(String name, String email, Integer age) {
this.name = name;
this.email = email;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
package org.example;
import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.example.pojo.student;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestStudent {
@Test
public void test01() throws IOException {
// 读取配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 取出sqlsession完成操作
SqlSession sqlSession = build.openSession();
List<student> list = sqlSession.selectList("wsy.getAll");
list.forEach(student->System.out.println(student));
// 关闭session
sqlSession.close();
}
@Test
public void test02() throws IOException {
// 第一步先读取配置的文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 第二步创建SESSION的工厂
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
// 取出sqlSession
SqlSession sqlSession = build.openSession();
student stu = sqlSession.selectOne("wsy.getById", 1);
System.out.println(stu);
sqlSession.close();
//
}
@Test
public void test03() throws IOException {
// InputStream in =
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 第二步创建SESSION的工厂
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
// 拿出sqlSession
SqlSession sqlSession = build.openSession();
// 进行sql命令的操作
List<student> list=sqlSession.selectList("wsy.getByName", "张");
list.forEach(student->System.out.println(student));
sqlSession.close();
}
@Test
public void test04() throws IOException {
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = build.openSession();
int n = sqlSession.insert("wsy.insert", new student(3,"张张", "zhangzhang@qq.com", 20));
System.out.println(n);
// 增删改一定要切记添加事务 进行事务的提交
sqlSession.commit();
sqlSession.close();
}
@Test
public void test05() throws IOException {
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = build.openSession();
int delete = sqlSession.delete("wsy.delete", 3);
System.out.println(delete);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test06() throws IOException {
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = build.openSession();
int number = sqlSession.update("wsy.update", new student(3, "小张张", "xiaozhangzhang@qq.com", 13));
System.out.println(number);
sqlSession.commit();
sqlSession.close();
}
}
crtl+h可以来查看接口和类点击右边的小箭头可以查看子接口
SqlSession sqlSession;
@Before
public void openSession() throws IOException {
// 读取配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 取出sqlsession完成操作
sqlSession = build.openSession();
}
@After
public void closeSession(){
// 关闭session
sqlSession.close();
}
@Test
public void test01() throws IOException {
List<student> list = sqlSession.selectList("wsy.getAll");
list.forEach(student->System.out.println(student));
}
优化测试类
优化实体类的别名注册
<typeAliases>
<!-- 单个注册-->
<typeAlias type="org.example.pojo.student" alias="student"></typeAlias>
<!-- 驼峰命名法注册,批量注册-->
<package name="org.example.pojo"/>
</typeAliases>
设置setting可以显示日志
<?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>
<!--读取属性文件-->
<properties resource="jdbc.properties"></properties>
<!-- 在这里面设置setting可以用来显示日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<!-- 单个注册-->
<typeAlias type="org.example.pojo.student" alias="student"></typeAlias>
<!-- 驼峰命名法注册,批量注册-->
<!-- <package name="org.example.pojo"/>-->
</typeAliases>
<!--配置环境变量-->
<environments default="development">
<environment id="development">
<!-- 这个transaction里面的JDBC表示的是由程序员自己来操作数据库-->
<transactionManager type="JDBC">
</transactionManager>
<!-- 这个dataSource里面的POOLED表示的是
jndi表示在服务器端、TOMCAT端来进行数据库的控制
POOLED表示在数据连接池来进行数据库的操作
UNPOOLED表示不使用数据库连接池
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 注册map.xml文件-->
<mappers>
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
</configuration>
模糊查询的时候有sql注入的风险
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1076607567.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@402bba4f]
==> Preparing: select id,name,email,age from student where name like '%张%'
==> Parameters:
<== Columns: id, name, email, age
<== Row: 1, 张三, zhangsan@qq.com, 22
<== Row: 3, 张张, zhangzhang@qq.com, 20
<== Row: 4, 小张张, xiaozhangzhang@qq.com, 13
<== Row: 5, 张张, zhangzhang@qq.com, 20
<== Row: 6, 张张, zhangzhang@qq.com, 20
<== Total: 5
student{id=1, name='张三', email='zhangsan@qq.com', age=22}
student{id=3, name='张张', email='zhangzhang@qq.com', age=20}
student{id=4, name='小张张', email='xiaozhangzhang@qq.com', age=13}
student{id=5, name='张张', email='zhangzhang@qq.com', age=20}
student{id=6, name='张张', email='zhangzhang@qq.com', age=20}
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@402bba4f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@402bba4f]
Returned connection 1076607567 to pool.