当前位置:首页 > 学习笔记 > 数据库 > 数据库教程 设计模式(单例模式、代理模式、工厂模式)

数据库教程 设计模式(单例模式、代理模式、工厂模式)

刘广法2022年04月06日 10:59:51数据库3650
数据库教程 设计模式(单例模式、代理模式、工厂模式)-第1张图片-刘广法IT博客

Java中常用的设计模式:

概况:

1、单例模式

  1. 饱汉式

  2. 饿汉式

  3. 内部类实现

2、工厂模式

3、代理模式

  1. 静态代理

  2. 动态代理

num1:单例模式

1.1 饱汉式

public class Singleton {
	private static final Student STUDENT = new Student();

	// 私有的构造函数,防止实例化
	private Singleton() {
	}

	public Student setStudent() {
		return STUDENT;
	}

}

1.2饿汉式

public class Singleton {
	private static Student STUDENT = null;

	// 私有的构造函数,防止实例化
	private Singleton() {
	}

	public Student setStudent() {
		if (STUDENT == null) {
			STUDENT = new Student();
		}
		return STUDENT;
	}
}

1.3 内部类实现

public class Singleton {
	// 创建内部类
	private static class newStudent {
		private static final Student STUDENT = new Student();
	}

	// 私有的构造函数,防止实例化
	private Singleton() {
	}

	// 调用内部类
	public static Student getStudent() {
		return newStudent.STUDENT;
	}
}

关于饱汉式单例设计模式、饿汉式单例设计模式 以及 内部类实现单例模式模式 的对比:

1、饱汉式单例设计模式:线程安全,不使用也加载

2、饿汉式单例设计模式:线程不安全,延迟加载,可以通过加 synchronized 关键字来实现线程安全

3、内部类实现单例模式:不适用不加载(减少使用内存),线程式安全的


更多的方法,增加关键字,双检锁


num2:工厂模式

设计模式之工厂模式:就是把创建实例交个一个指定的类(工厂类)进行实现,至于工厂类怎么实现,我不管

num3:代理模式

1.1静态代理


1.2动态代理

运用的方法:

第一个参数:类加载器

第二个参数:动态代理要实现的接口

第三个参数:拦截器的作用(拦截所代理类的行为)

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) {
        Objects.requireNonNull(h);
        @SuppressWarnings("removal")
        final Class<?> caller = System.getSecurityManager() == null
                                    ? null
                                    : Reflection.getCallerClass();
        /*
         * Look up or generate the designated proxy class and its constructor.
         */
        Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
        return newProxyInstance(caller, cons, h);
    }

实例化:

Global 类(全局变量类):

package com.lgf.shejimoshi;

import java.sql.Connection;

/**
 * 全局的变量或方法
 */
public class Global {
    public static final String url =
        "jdbc:mysql://localhost:3306/employee?charaterEncoding=UTF-8&useSSL=false&autoReconnect=true&serverTimeZone=Asia/Shanghai";
    public static final String username = "root";
    public static final String password = "123456";

    /**
     * 获取数据库连接
     * 
     * @return
     */
    public static Connection getConnection() {
        return JdbcUtils.getConnection(url, username, password);
    }
}

连接池类

package com.lgf.shejimoshi;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库链接池
 * 
 * @author liuguangfa
 *
 */
public class MySql {

	private final int databaseMin = 5;
	private final int datebaseMax = 15;
	List<PooledDatabase> conns = new ArrayList<>();

	/**
	 * 创建数据库链接
	 */
	public Connection getConnection() {
		return Global.getConnection();
	}

	/**
	 * 初始化链接池
	 */
	public void iniPool() {

		for (int i = 0; i < databaseMin; i++) {
			Connection conn = getConnection();

			// 创建实例
			PooledDatabase pd = new PooledDatabase();
			pd.setUsed(true);
			pd.setConnectoion(conn);
			//
			conns.add(pd);
		}
	}

	/**
	 * 链接池中的连接代理
	 */
	public void buildConnectionProxy(PooledDatabase pd) {
		Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { Connection.class },
				new InvocationHandler() {

					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						if (method.getName().equals("close")) {
							return null;
						} else {
							return method.invoke(pd, args);
						}
					}

				});
	}

	/**
	 * 从数据库池中拿链接
	 */
	public Connection gtConnection() {
		for (int i = 0; i < conns.size(); i++) {
			if (!conns.get(i).isUsed()) {
				conns.get(i).setUsed(true);
				return conns.get(i).getConnectoion();
			}
		}
		// 数据库连接不够了,小于最大的数据库连接,创建数据库
		if (conns.size() < datebaseMax) {
			Connection conn = getConnection();

			PooledDatabase ps = new PooledDatabase();
			ps.setConnectoion(conn);
			ps.setUsed(true);

			conns.add(ps);
			return ps.getConnectoion();
		}
		throw new RuntimeException("数据库已经达到最大的连接数");

	}

	/**
	 * 判断链接池中的链接是否在使用
	 */
	public static class PooledDatabase {
		private Connection connectoion;
		private boolean used = false;

		public Connection getConnectoion() {
			return connectoion;
		}

		public void setConnectoion(Connection connectoion) {
			this.connectoion = connectoion;
		}

		public boolean isUsed() {
			return used;
		}

		public void setUsed(boolean used) {
			this.used = used;
		}

	}

}


文章作者:刘广法,转载请注明出处。

扫描二维码推送至手机访问。

版权声明:本文由刘广法博客发布,如需转载请注明出处。

本文链接:https://liuguangfa.com/database/162.html

分享给朋友:
返回列表

上一篇:数据库练习 数据库查询练习 ***

没有最新的文章了...

“数据库教程 设计模式(单例模式、代理模式、工厂模式)” 的相关文章

数据库教程 DDL数据定义语言

数据库教程 DDL数据定义语言1. 基本操作查看所有数据库名称:【语法:show databases;】切换数据库:【语法:use test;】,切换到test数据库;显示表:【语法:show tables;】查询表:【语法:select * from goods;】2.操作数据库2.1 创建数据库...

数据库教程 存储过程

数据库教程 存储过程关于数据库存储过程的相关描述:1、优点:性能强2、缺点:无法移植3、mysql 存放在函数类型中,不调用不会执行(存储过程需要单独调用)参数类型:in:传入参数out:传出参数intout:既可以传入又可以传出-- 存储过程,不需要返回值create procedure...

数据库教程 jdbc

java 和 数据库 连接技术odbc:淘汰10年了。只能用在windows系统上关于jdbc 的相关描述:关于jdbc的实操七步:package com.liuguangfa.jdbc; import java.sql.Connection; import j...

数据库练习 数据库查询练习 ***

冰人集团系统数据库设计1. 使用MySQL 8.x版本数据库,使用Navicat作为数据库客户端管理图形界面工具。2. 创建名为“iceman2018”的数据库。字符集使用utf8 -- UTF-8 Unicode,排序规则使用utf8_general_ci。3. 创建“部门”表,表名为t_depa...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。