知识扫盲1

1. 使用JDBC(Java Database Connectivity)进行事务管理的步骤

建立数据库连接:使用DriverManager.getConnection()方法建立与数据库的连接。
关闭自动提交:通过调用连接对象的setAutoCommit(false)方法关闭自动提交功能。这样,在执行事务期间,不会自动将每个数据库操作作为一个单独的事务进行提交。
创建事务保存点(可选):使用连接对象的setSavepoint()方法创建一个事务保存点。保存点可以在事务执行过程中标记一个回退点,以便在必要时回滚到该点。
执行数据库操作:使用连接对象创建Statement或PreparedStatement对象执行数据库操作,例如插入、更新或删除数据。
处理事务逻辑:根据应用程序的需要,通过执行一系列数据库操作来处理事务逻辑。
提交事务:在事务执行成功且满足提交条件时,使用连接对象的commit()方法提交事务。在此之后,所有的数据库操作将正式应用到数据库。
回滚事务:如果在事务执行过程中发生错误或执行失败,可以使用连接对象的rollback()方法回滚事务,撤销之前进行的所有操作。
关闭连接:在事务结束后,使用连接对象的close()方法关闭数据库连接。
在这里插入图片描述

2. 为什么要进行t.remove()这个操作?

在这里插入图片描述

  • why

    在MyBatis中,使用ThreadLocal来管理数据库会话(SqlSession)的生命周期。ThreadLocal是一个线程局部变量,它可以确保每个线程都有自己独立的数据库会话实例。
    关闭ThreadLocal资源是为了避免潜在的内存泄漏和资源占用。在应用程序中,ThreadLocal对象通常是在静态字段中存储的,如果不手动进行资源关闭,会导致ThreadLocal持有的对象无法被垃圾回收,从而产生内存泄漏。
    MyBatis的SqlSession对象中持有了数据库连接和其他资源。如果不手动关闭ThreadLocal资源,会导致会话对象无法被释放,而且底层的数据库连接也无法被正确关闭和释放。这可能导致数据库连接池资源的浪费、连接泄漏和应用程序性能下降。
    为了正确地管理数据库会话和释放资源,应该在每次会话结束后手动调用close()或者使用try-finally或try-with-resources语句块来确保资源被正确关闭。这样可以保证在会话结束后,MyBatis能够将底层的数据库连接归还给连接池,并释放其他相关的资源。

  • how
    以下是一个示例代码片段,展示了如何在MyBatis中关闭ThreadLocal资源:

SqlSession sqlSession = null;
try {
    sqlSession = sqlSessionFactory.openSession();
    // 执行数据库操作
    // ...

    // 提交事务
    sqlSession.commit();
} catch (Exception e) {
    // 处理异常
    sqlSession.rollback();
} finally {
    if (sqlSession != null) {
        sqlSession.close(); // 关闭会话对象,释放资源
    }
}

通过手动关闭ThreadLocal资源,可以确保在使用MyBatis过程中充分释放与数据库相关的资源,避免潜在的问题和性能影响。

3. 学过的两种代理模式: cglib,gdk

  • cglib代理模式
    CGLIB(Code Generation Library)是一个基于Java字节码操作的代码生成库,它可以在运行时对类进行扩展和增强。CGLIB代理模式就是基于CGLIB库实现的一种动态代理模式。
    动态代理是一种在运行时生成代理对象的机制,它可以在不改变原始类的情况下,对其方法进行增强或拦截。CGLIB代理模式通过生成一个继承原始类的子类,从而实现对原始类方法的继承和扩展。
    CGLIB代理模式的核心是通过生成子类来代理原始类。当需要代理的类没有实现接口时,CGLIB就会生成一个子类,并重写原始类的方法,在子类中增加额外的逻辑来实现对方法的增强。代理对象是子类的实例,因此可以将代理对象强制转换为原始类的类型,然后调用原始类的方法。
    相比于Java的动态代理(基于接口),CGLIB代理可以代理一些没有实现接口的类,是一种更强大和灵活的代理方式。它可以拦截并增强任意类的方法,包括final方法、私有方法等,而不像动态代理只能代理接口的方法。
    然而,CGLIB代理也有一些限制。由于CGLIB是通过生成子类来代理原始类,所以无法代理有final修饰的方法和类。此外,由于CGLIB是通过继承来实现代理,因此无法代理final类。另外,由于CGLIB代理涉及字节码操作,生成代理类的过程相对较慢。
    总的来说,CGLIB代理模式是一种基于CGLIB库的动态代理实现方式,它通过生成子类来继承和扩展原始类的方法,实现对方法的增强和拦截。这种代理模式可以代理没有实现接口的类,具有更大的灵活性,但也存在一些限制和性能方面的考虑。
  • gdk
    JDK动态代理是一种基于接口的代理模式,通过使用Java的反射机制,在运行时动态生成代理类。JDK动态代理主要涉及以下两个关键类和接口:
    java.lang.reflect.Proxy 类:这是JDK提供的一个支持动态代理的类。通过调用 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) 方法,可以在运行时创建代理对象。该方法接受三个参数:类加载器(ClassLoader),代理对象要实现的接口(Class<?>[] interfaces),和一个代理对象的调用处理程序(InvocationHandler)。
    java.lang.reflect.InvocationHandler 接口:该接口定义了一个用于处理代理对象方法调用的统一接口。代理对象的方法调用会被转发到 InvocationHandler 的 invoke(Object proxy, Method method, Object[] args) 方法,开发人员可以在该方法中自定义处理逻辑。
    使用JDK动态代理的步骤如下:
    创建一个实现了 InvocationHandler 接口的类,该类将定义代理对象方法调用的处理逻辑。
    使用 Proxy.newProxyInstance() 方法创建代理对象,传入类加载器、实现的接口和处理逻辑。
    通过代理对象调用方法,实际上会转发到 InvocationHandler 的 invoke() 方法中进行处理。
    JDK动态代理的优点是简单易用,不需要手动编写代理类,适用于对接口进行代理的场景,如AOP(面向切面编程)。缺点是只能代理实现了接口的对象,对于没有实现接口的类无法进行代理。

4. 类加载器

Java中有几种不同的类加载器,主要包括以下几种:

  • 启动类加载器(Bootstrap Class Loader):它是Java虚拟机内置的类加载器,负责加载Java核心库(如rt.jar等)。
  • 扩展类加载器(Extension Class Loader):它负责加载Java的扩展库,位于Java扩展目录(jre/lib/ext)下的jar包。
  • 应用程序类加载器(Application Class Loader):又称为系统类加载器,它负责加载应用程序的类,一般通过classpath指定的路径来搜索和加载类。
  • 自定义类加载器(Custom Class Loader):除了上述内置的类加载器外,开发者还可以自定义类加载器。自定义类加载器可以根据应用程序的需求,实现特定的类加载策略,如动态从网络加载类、从非标准的文件系统加载类等。

这些类加载器构成了类加载器层次结构,按照双亲委派模型工作。即当一个类加载器收到类加载请求时,它首先将该请求传递给父类加载器,只有在父类加载器无法完成加载时,才由当前类加载器自己尝试进行加载。这种层次结构保证了类的一致性和安全性。
每个类加载器负责加载特定范围的类,有效地划分了类的命名空间,避免不同类之间的命名冲突,并提供了更为灵活和可扩展的类加载机制。

动态代理模式

5. 什么时候创建被代理类?

程序运行过程中,JVM帮我们创建的

6. 逻辑

在这里插入图片描述

扩展
在这里插入图片描述
在这里插入图片描述
后续就需要引入过滤器(拦截器)

重点

在这里插入图片描述

sql注入

  • what
    sql注入是一种常见的安全漏洞,它发生在应用程序与数据SQL代码注入到应用程序的数据库查询中。它允许攻击者通过恶意的SQL语句,将非法的SQL代码注入到应用程序的数据库查询中。当应用程序没有对用户输入进行充分的验证和过滤时,攻击者可以利用这个漏洞来执行未经授权的数据库操作。

  • why
    SQL注入攻击的原理是利用应用程序对用户输入的信任,攻击者可以通过在用户输入中插入恶意的SQL代码来欺骗应用程序,绕过验证和过滤机制。一旦成功注入恶意SQL代码,攻击者可以执行各种恶意操作,例如:删除、修改、插入或者泄露数据库中的敏感信息。

    eg:

    String username = request.getParameter("username);
    String password= request.getParameter("password);
    
    String query = "select * from userwhere username = '?'";
    Statement statement = connection.crreateStatement();
    ResultSet resultSet = statement.executeQuery(query);
    

    在上面的示例中,如果攻击者将username参数设置为’ OR ‘1’='1,password参数设置为任意值,那么最终构建的SQL查询语句将是:

    SELECT * FROM users WHERE username='' OR '1'='1' AND password='任意值'
    

    由于’1’='1’这个条件始终为真,攻击者将能够绕过认证,获取该查询中的所有用户记录,而不需要提供有效的用户名和密码。

  • how
    为了防止SQL注入攻击,应用程序应该始终对用户输入进行验证、过滤和转义。使用参数化查询或预编译语句可以有效防止SQL注入,因为这些方法会将用户输入作为参数而不是将其直接拼接到SQL查询中。此外,限制数据库用户的权限、使用安全的连接和访问控制也是防止SQL注入的重要措施。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值