0
点赞
收藏
分享

微信扫一扫

Linux系统基础-进程间通信(4)_模拟实现进程池

落拓尘嚣 2024-11-04 阅读 23

一、Mybatis面试题:$和#的区别是什么?

1.1 #是预编译SQL,$是即时SQL

SQL执行流程

1.语法解析,校验SQL有没有问题。

2.SQL优化,编译,制定执行计划。

3.执行SQL

我们分别使用Integer与String类型参数举例

我们编写如下代码。用#和$分别去取值Integer类型参数和String类型参数。

参数为Integer类型时

@Select("select * from userinfo where id = #{userId}")
UserInfo queryUserInfo(Integer userId);


@Select("select * from userinfo where id = ${userId}")
List<UserInfo> queryUserInfo2(Integer userId);

2.参数为String类型时

    @Select("select * from userinfo where username = #{name}")
    List<UserInfo> queryUserByName1(@Param("name") String name);

    @Select("select * from userinfo where username = ${name}")
    List<UserInfo> queryUserByName2(@Param("name") String name);
    @Test
    void queryUserByName2() {
        log.info(userInfoMapper.queryUserByName2("admin").toString());
    }

    @Select("select * from userinfo where username = '${name}'")
    List<UserInfo> queryUserByName2(@Param("name") String name);
    @Test
    void queryUserByName2() {
        log.info(userInfoMapper.queryUserByName2("admin").toString());
    }

注:


1.2最主要区别($存在SQL注入的问题。

1.1.1$存在SQL注入的问题

最主要的区别是:$存在SQL注入的问题。

SQL注入:

这个就相当于

执行SQL语句后,我们得到的结果是将表内所有内容都打印出来了。相当于没有where

由于存在SQL注入的问题因此$符号不被广泛使用了。

早期SQL注入的问题:

通过SQL注入完成无密码就可以登录

也不是说使用$就一定会存在SQL注入问题。而是看你的代码如何去实现的

模拟SQL注入 完成用户登录 代码演示:

1.在Controller包控制器层中(也算是三层架构中的视图层)
​​​​​​​​​    @RequestMapping("/login")
    public UserInfo login(String userName,String password){
        return userService.queryUserByNameAndPassword(userName,password);
    }
2.在Service服务层包中
    public UserInfo queryUserByNameAndPassword(String name,String password) {
        List<UserInfo> userInfos = userInfoMapper.queryUserByNameAndPassword(name,password);
        if(!userInfos.isEmpty()){
            //如果查出来
            return userInfos.get(0);
        }
        //如果没查出来
        return null;
    }
3.在Mapper数据访问层中:

​​​​​​​

4. 访问的数据库表如下

5.最终访问的结果如下:

我们发现:

当我们的密码输入为'or 1='1时数据也可以被访问到,这就是很严重的SQL注入问题。  

这就是一个漏洞。

如果我们根据userName去查再去通过password校验,这种情况使用' or 1='1也登录不进去

1.3在使用上的其他区别

1.3.1使用淘宝进行排序问题(不能使用#):

此时需要使用$符号,

注:

此时也存在SQL注入的风险

解决办法:如果不让用户传参的话,那么就不存在SQL注入风险了

也就是不给用户在用$取值的输入框。

如何来去做呢?请往下看

SQL语句七 由Id进行倒序排序。

假如我们这样在Mapper包中写数据。那么就会报错。

SQL语句出错,是因为#若参数是字符串会默认加上' '此时

SQL语句变成了

因此会报错,如果我们改成用$来取值,那么此时就可以编译通过了

注:

此时也存在SQL注入的风险,解决办法:如果不让用户传参的话,那么就不存在SQL注入风险了

也就是不给用户在用$取值的输入框。

如何来去做呢?请往下看

$存在SQL注入风险,如何处理?

实现方式非常多,简单列举以下方式

例如1:不接收用户输入的参数,参数由后台来处理。

代码要写的很严谨,就不存在SQL注入问题了。

order参数是Controller包中被用户传进来的

还有哪些情况#不能使用

不需要加引号的时候,比如表名,字段名。

表名,字段名作为变量的时候,

表明作为变量:

在分库分表的情况下,若将userinfo这张表分成userinfo1,userinfo2,...userinfo10这十张表,我们查询的时候,根据一定的规则,看哪张表里有我们想要的userId,此时表名就是变量了。

字段名作为变量:

1.一些大公司不让直接连数据库(不然账号密码直接登录数据库),连了就会有风险,如何规避风险,而是开发一个MySQL客户端,申请权限就可以直接连数据库不需要账号密码。需要解析SQL。字段都是生成的,

2.数据的导出,若只想导出某一些列,此时列名就会被作为变量。#不能使用。

1.3.2模糊查询问题(不能直接使用#,需要通过CONCAT(str1,str2,..)方式再用#实现):

SQL语句八:模糊查询

例:select * from userinfo where username like "%admin%"

数据库表

我们在Mapper中写出如下代码进行迷糊查询并进行测试:

只查询出来了一条,因为输入结果为admin,我们虽然加了%%但是被弄丢了。因此相当于我们只查了admin没有进行模糊查询。相当于等号。

也就是拼接成了

select * from userinfo where username like admin 

相当于

select * from userinfo where username = admin

换一种写法,我们将百分号写在外面

又报错了,SQL语句出错。 拼接成了

select * from userinfo where username like %'admin'%

在里面又加上了引号。

因此模糊查询通过#无法实现。

通过$实现模糊查询

我们发现,成功得到了我们想要的结果。

模糊查询$存在SQL注入风险,如何处理?

使用MySQL的CONCAT(str1,str2,....)

CONCAT()是mysql内置函数

使用示例如下

改成这种形式 就可以使用#来实现模糊查询

总结

#和$的区别

相同点:

二、数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接, 而不是再重新建立一个。

使用数据库连接池的好处:

常见数据库连接池:C3P0、DBCP、Druid、HiKari。

目前比较流行的数据库连接池是Hikari,Druid

2.1Hikari :

Hikari 是日语"光"的意思(ひかり),Hikari也是以追求性能极致为目标

是SpringBoot默认使用的数据库连接池

Hikaricp和Druid对比_数据库_晚风暖-华为云开发者联盟 (csdn.net)

2.2Druid

如果我们想把默认的数据库连接池切换为Druid数据库连接池,只需要引入相关依赖即可 

官方参考地址

Druid连接池是阿里巴巴开源的数据库连接池项目 功能强大,性能优秀是Java语言最好的数据库连接池之⼀。

学习文档:https://github.com/alibaba/druid/wiki/%E9%A6%96%E9%A1%B5

大总结

举报

相关推荐

0 条评论