Mybatis(一) —— 基础的知识储备

1.Mybatis相比于jdbc的优势

public static void main(String[] args) {
			Connection connection = null;
			PreparedStatement preparedStatement = null;
			ResultSet resultSet = null;
			
			try {
				//1、加载数据库驱动
				Class.forName("com.mysql.jdbc.Driver");
				//2、通过驱动管理类获取数据库链接
				connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis", "root", "root");
				//3、定义sql语句 ?表示占位符
			    String sql = "select * from user where id = ?";
				//4、获取预处理preparedStatement
				preparedStatement = connection.prepareStatement(sql);
				//5、设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
				preparedStatement.setString(1, id);
				//6、向数据库发出sql执行查询,查询出结果集
				resultSet =  preparedStatement.executeQuery();
				//7、遍历查询结果集
				while(resultSet.next()){
					System.out.println(resultSet.getString("username"));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				//8、释放资源
				if(resultSet!=null){
					try {
						resultSet.close();//释放结果集
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(preparedStatement!=null){
					try {
						preparedStatement.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
				if(connection!=null){
					try {
						connection.close();//关闭数据库连接
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
 
			}
 
		}

mybatis相对jdbc的优势:
1.mybatis将数据库连接的信息写在配置文件中,方便维护;
2.mybatis执行的sql语句都是通过配置文件进行配置,不需要写在java代码中。
3.mybatis的连接池管理、缓存管理可以减少连接的频繁创建和关闭,提高查询效率。

2.动态代理

代理概念【什么是代理?】

代理类似于生活中的代购或者是中介,比如买家和卖家,卖家就是商品的代理,个人买东西是无法接触到厂家的。
代理模式即是指为其它对象提供一种代理,以控制对这个对象的访问。
代理对象在客户端和目标对象之间起到中介作用,使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象

  • 功能增强:在原有功能的基础上增加了一些额外的功能;
  • 控制访问:代理类不让访问目标对象

代理分类【静态代理和动态代理】

1. 静态代理(static-proxy):代理类是自己手工实现的,自己创建一个java类作为代理类;

  • 特点:实现简单,容易理解
  • 举例说明:卖u盘
    步骤:1.定义接口,接口里面定义方法——商家和厂家的行为(可以定义多个方法,表示功能的接口)
    2.定义一个厂家的实现类(目标类),不支持用户的 单独购买
    3.定义一个商家也实现接口,调用厂家的方法,加价操作(增强功能)
    4.测试类购买u盘调用商家的方法
  • 代理类完成的功能:调用目标对象的方法 AND 功能增强
  • 静态代理的优缺点:
    目标类增加了,代理类可能需要成倍的增加,代理类数量过多;
    当接口中增加了方法(功能),所有代理类也都要实现该方法,影响较多,不方便维护和管理。

2.动态代理(dynamic-proxy):动态代理实在程序的执行过程中使用jdk的反射机制创建代理类对象,并动态的指定要代理的目标类。换句话说,动态代理是一种创建java对象的能力,使得不用创建代理类就可以创建代理对象。
在静态代理中目标类很多的时候,可以使用动态代理,避免静态代理的缺点;动态代理中目标类即使很多,代理类数量可以很少,修改接口中的方法时,不会影响代理类
在这里插入图片描述

动态代理的两种方式
1.jdk动态代理(掌握)

  • jdk动态代理(理解):使用java反射包中的类和接口实现动态代理的功能,反射包java.lang.reflect,里面有三个类:InvocationHandler,Method,Proxy

2.cglib动态代理(了解)

  • cglib是第三方的工具库,创建代理对象,
    cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法,实现功能的修改。因为cglib是继承,重写方法,所以要求目标类不能是fina1的,方法也不能是final的。cglib的要求目标类比较宽松,只要能继承就可以了。cglib在很多的框架中使用,比如mybatis,spring框架中都有使用

jdk动态代理的实现
java.lang.reflect包下有3个类InvocationHandler,Method,Proxy

  • InvocationHandler:是一个接口,有一个方法invoke,在invoke方法中完成代理类的功能, 调用目标方法,增强功能
  • Method:方法类,method.invoke(目标对象,参数),调用目标类中的方法
    ​ object ret= method. invoke(service22,“李四”)
  • Proxy:代理类,创建代理对象,取代new创建对象的方式。调用静态方法newProxyInstance(),方法原型
    public static Object newProxyInstance( ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
    参数:1. ClassLoader loader类加载器,负责向内存中加载对象,使用反射机制获取对象的classLoader,类 a, a.getCalss().getClassLoader(),目标对象的类加载器
    2.Class<?>[] interfaces: 接口,目标对象实现的接口,也是反射获取的
    3.InvocationHandler h : 我们自己写的,代理类要完成的功能
    返回值也就是代理对象。

简单来说jdk动态代理就是有固定的模式,我们不需要写代理类,将增强的部分写在InvocationHandler的invoke方法里即可。再利用Pxoxy.newProxyInstance获取目标对象,再调用方法即可。
代码实现

//  接口
public interface UsbSell {
    float sell(int amount);
}
// 目标类实现接口
public class UsbKingFactory implements UsbSell {
    @Override
    public float sell(int amount) {
        System.out.println("目标类中,执行了sell目标方法");
        return 85.02f;
        
    }
}

public class MyHandle implements InvocationHandler {

	public MyHandle(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         Object res =null;
         res = method.invoke(target,args);       //待执行目标方法,执行后返回值
         // 增强方法
         if(res!=null){
         Float price = (Float)res;
         price = price + 25;
         res = price;
         }
        return res;
    }
}

public class MainShop {
    public static void main(String[] args){ 
//            1.创建对象,使用Proxy
//            2.创建目标对象
        UsbSell factory = new UsbKingFactory();
//        3.创建Invocationhandler对象
        InvocationHandler myHandle = new MyHandle(factory);

//        4.创建代理对象
        UsbSell proxy = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),
                myHandle);
//        通过代理执行方法
        float price = proxy.sell(1);
        System.out.println("通过动态代理对象,调用方法:" +price);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值