MyBatis面试题--(与数据库连接的相关知识)

news/2024/11/15 20:12:13/文章来源:https://www.cnblogs.com/yangcurry/p/18548579

目录
  • 在MyBatis中,Mapper接口的作用是什么?
  • 当实体类中属性名和表中的字段名不一样,怎么办?
    • 1. 使用@Result注解
    • 2. 使用resultMap元素
    • 3. 使用@Results注解(MyBatis 3.4.1+)
    • 4. 使用mapUnderscoreToCamelCase属性
  • 在MyBatis中如何实现分页功能?
    • 1. 使用MyBatis分页插件
    • 2. 手动编写分页 SQL
    • 3. 使用 MyBatis 的拦截器
    • 4. 使用 MyBatis 分页注解
  • MyBatis#()和$()有什么区别?
    • #{}(预处理参数)
    • $()(字符串替换)

在MyBatis中,Mapper接口的作用是什么?

在MyBatis中,Mapper接口是一种重要的组件,它定义了数据库操作的方法,这些方法与SQL语句相对应。Mapper接口的作用主要包括以下几点:

  1. 定义数据库操作的方法
    Mapper接口中定义的方法代表了对数据库的某种操作,例如查询、插入、更新或删除。每个方法通常对应一个SQL语句。

  2. 解耦SQL语句和Java代码
    通过将SQL语句放在XML映射文件中或使用注解的方式与Mapper接口中的方法关联,MyBatis允许开发者将SQL语句与Java代码分离,从而提高了代码的可维护性和可读性。

  3. 提供清晰的操作定义
    Mapper接口为数据库操作提供了一个清晰和直观的定义,使得其他开发者可以容易地理解和使用这些操作。

  4. 支持动态SQL
    MyBatis支持在Mapper接口中使用动态SQL特性,如<if><choose><when><otherwise>等,这使得构建复杂的查询变得更加灵活。

  5. 简化事务管理
    在Spring框架中,Mapper接口的方法可以与Spring的事务管理集成,简化了事务的配置和管理。

  6. 提高代码重用性
    通过定义通用的数据库操作方法,Mapper接口可以被多个地方重用,减少了代码的重复。

  7. 便于单元测试
    Mapper接口的方法可以被单独测试,这有助于实现单元测试的自动化和持续集成。

  8. 支持映射配置
    Mapper接口的方法可以配置复杂的结果映射,将数据库查询结果映射到Java对象或对象集合。

  9. 与MyBatis框架集成
    Mapper接口与MyBatis框架紧密集成,使得开发者可以利用MyBatis提供的各种特性,如缓存、插件等。

  10. 提高开发效率
    使用Mapper接口可以减少样板代码,让开发者专注于业务逻辑的实现,从而提高开发效率。

总的来说,Mapper接口是MyBatis框架中定义数据库操作的关键部分,它为数据库交互提供了一个简洁、灵活且强大的抽象层。

当实体类中属性名和表中的字段名不一样,怎么办?

当实体类中的属性名和数据库表中的字段名不同时,您可以使用MyBatis的映射功能来解决这个问题。MyBatis提供了以下几种方式来处理属性名和字段名不一致的情况:

1. 使用@Result注解

在MyBatis的映射文件中,您可以使用@Result注解来指定结果映射,将数据库字段映射到实体类的属性上。

public interface BlogMapper {@Select("SELECT id AS blogId, title AS blogTitle, content AS blogContent FROM blogs")@Results({@Result(property = "blogId", column = "id"),@Result(property = "blogTitle", column = "title"),@Result(property = "blogContent", column = "content")})List<Blog> selectBlogs();
}

2. 使用resultMap元素

在MyBatis的XML映射文件中,您可以定义一个resultMap,并在查询语句中引用它。

<resultMap id="BlogResultMap" type="Blog"><result property="blogId" column="id" /><result property="blogTitle" column="title" /><result property="blogContent" column="content" />
</resultMap><select id="selectBlogs" resultMap="BlogResultMap">SELECT id, title, content FROM blogs
</select>

3. 使用@Results注解(MyBatis 3.4.1+)

MyBatis 3.4.1及更高版本支持在Mapper接口的方法上使用@Results注解。

public interface BlogMapper {@Select("SELECT id, title, content FROM blogs")@Results({@Result(property = "blogId", column = "id"),@Result(property = "blogTitle", column = "title"),@Result(property = "blogContent", column = "content")})List<Blog> selectBlogs();
}

4. 使用mapUnderscoreToCamelCase属性

在MyBatis配置文件中,您可以设置mapUnderscoreToCamelCase属性为true,这样MyBatis会自动将下划线命名的数据库字段映射到驼峰命名的Java属性。

<configuration><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
</configuration>

请注意,这种方法只适用于简单的映射,如果字段名和属性名的映射不是简单的下划线到驼峰的转换,您仍然需要使用@ResultresultMap来指定映射。

通过以上方法,您可以灵活地处理实体类属性名和数据库字段名不一致的问题,确保MyBatis能够正确地将数据库查询结果映射到Java对象。

在MyBatis中如何实现分页功能?

在MyBatis中实现分页功能通常有以下几种方法:

1. 使用MyBatis分页插件

MyBatis 分页插件,如 PageHelper,是一种流行的选择,它可以简化分页逻辑的处理。以下是如何使用 PageHelper 实现分页的步骤:

  1. 添加依赖:在项目的pom.xml文件中添加 PageHelper 依赖。
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>最新版本</version>
</dependency>
  1. 配置分页插件:在 Spring Boot 的配置文件中配置 PageHelper。
# application.yml
pagehelper:helperDialect: mysqlreasonable: truesupportMethodsArguments: trueparams: count=countSql
  1. 使用分页插件:在 Mapper 接口的方法中直接使用 PageHelper。
public interface UserMapper extends MyBatisPlusMapper<User> {// 其他 CRUD 方法
}@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public IPage<User> selectPageVo(Page page, @Param("name") String name) {PageHelper.startPage(page.getPageNum(), page.getPageSize());return userMapper.selectPage(new QueryWrapper<User>().eq("name", name));}
}

2. 手动编写分页 SQL

如果您不想使用分页插件,可以手动在 MyBatis 的 Mapper XML 文件中编写分页 SQL。

<select id="selectPagedBlogs" resultType="Blog">SELECT * FROM blogsLIMIT #{offset}, #{pageSize}
</select>

在这种情况下,您需要在服务层传递offset(偏移量)和pageSize(页面大小)参数,并计算分页参数。

3. 使用 MyBatis 的拦截器

您可以创建一个 MyBatis 拦截器,在拦截器中修改 SQL 语句以添加分页逻辑。

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class PaginationInterceptor implements Interceptor {// 实现拦截器逻辑,修改 SQL 以添加分页
}

4. 使用 MyBatis 分页注解

MyBatis 提供了@Select注解,您可以在 Mapper 接口中直接使用注解编写分页 SQL。

public interface BlogMapper {@Select("SELECT * FROM blogs LIMIT #{offset}, #{pageSize}")List<Blog> selectPagedBlogs(@Param("offset") int offset, @Param("pageSize") int pageSize);
}

注意事项

  • 分页插件通常是实现分页的最简单方法,特别是对于复杂的查询。
  • 手动编写分页 SQL 给您更多的控制权,但可能会更复杂,尤其是在处理复杂查询时。
  • 使用拦截器可以实现更通用的分页逻辑,但实现起来较为复杂。
  • 分页注解提供了一种简便的方法,但在复杂的分页逻辑中可能不够灵活。

根据您的具体需求和项目情况,您可以选择最适合您项目的方法来实现分页功能。

MyBatis#()和$()有什么区别?

在MyBatis中,#{}$()是用于在SQL语句中嵌入参数的两种不同方式,它们的主要区别在于处理方式和用途:

#{}(预处理参数)

  1. 预处理语句(Prepared Statements)#{}在MyBatis中用于参数占位符,它会被转换成预处理语句中的参数。这意味着参数是在SQL语句执行之前就被传递给数据库的,这有助于防止SQL注入攻击。

  2. 自动转义:使用#{}时,MyBatis会自动对参数值进行转义,以防止SQL注入。

  3. 安全性#{}是推荐的方式,因为它更安全,可以防止SQL注入。

  4. 示例

    <select id="selectBlog" resultType="Blog">SELECT * FROM Blog WHERE id = #{id}
    </select>
    

$()(字符串替换)

  1. 字符串替换$()在MyBatis中用于直接替换,它会将参数值直接拼接到SQL语句中。这种方式不会使用预处理语句。

  2. 无转义:使用$()时,参数值不会被自动转义,这可能会导致SQL注入的风险。

  3. 不安全性$()通常不推荐使用,因为它可能会导致SQL注入问题。

  4. 用途$()有时用于那些需要动态表名、列名或动态SQL片段的场景,但这些场景也应该尽量避免使用$(),转而使用其他更安全的方法,如MyBatis的动态SQL功能。

  5. 示例

    <select id="selectBlog" resultType="Blog">SELECT * FROM ${tableName} WHERE id = ${id}
    </select>
    

最佳实践

  • 安全性:总是使用#{}来传递SQL参数,以确保安全性。
  • 动态SQL:对于需要动态构建的SQL语句,使用MyBatis提供的动态SQL功能,如<if><choose><when><otherwise>等,而不是使用$()
  • 避免$():尽量避免使用$(),特别是在涉及用户输入的场景中,以防止SQL注入攻击。

总结来说,#{}是安全的参数传递方式,而$()是字符串替换方式,但在实际开发中,应尽量避免使用$(),以确保应用程序的安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834218.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文件共享服务之实时备份(inotify+rsync)

任务需求 1.对NFS服务器上的静态资源实时备份(inotify+rsync) 主机列表 # 外网地址 内网地址 主机名 192.168.122.207 172.16.1.207 web-test-209 192.168.122.231 172.16.1.231 nfs-test-231 192.168.122.241 172.16.1.241 rsync-test-241架…

专题四:信息安全

信息系统安全属性 机密性:确保信息不暴露给未授权的实体或进程。 完整性:只有得到允许的人才能修改数据,并且能够判断出数据是否已被篡改。 可用性:得到授权的实体在需要时可访问数据,即攻击者不能占用所有的资源而阻碍授权者的工作。 可控性:可以控制授权范围内的信息流…

生产环境中AI调用的优化:AI网关高价值应用实践

随着越来越多的组织将生成式AI引入生产环境,他们面临的挑战已经超出了初步实施的范畴。如果管理不当,扩展性限制、安全漏洞和性能瓶颈可能会阻碍AI应用的推广。实际问题如用户数据的安全性、固定容量限制、成本管理和延迟优化等,需要创新的解决方案。 本文我们深入探讨了一些…

MobileViT-v1-所有patch内相对位置相同的token之间计算自注意力

paper def my_self(x: torch.Tensor):通过这段代码 可以把每张图片图片中相对位置相同的若干个tokens放到最后两个维度# [B, C, H, W] -> [B, C, n_h, p_h, n_w, p_w] # n_h是高度方向上可以分多少个patch p_h patch的高度 n_w 宽度方向上可以分多少个patch p_w patch的宽…

27. 使用MySQL之全球化和本地化

1. 字符集和校对顺序 数据库表被用来存储和检索数据。不同的语言和字符集需要以不同的方式存储和检索。因此,MySQL需要适应不同的字符集(不同的字母和字符),适应不同的排序和检索数据的方法。 在讨论多种语言和字符集时,将会遇到以下重要术语:字符集为字母和符号的集合;…

TCP/IP上三层协议

TCP/IP上三层的角色 同一台设备上的进程间通信有多种方式,如管道、消息队列、共享内存、信号等。而不同设备间的进程通信需要网络通信,由于设备具有多样性,因此协商出了一套通用的网络协议。这个网络协议是分层的,每一层都有各自的作用和职责,接下来将依据 “TCP/IP 网络模…

无线部分

AC堆叠(VAC) 配置两台AC设备,使用虚拟化方案组合成1台虚拟AC。 AC1和AC2之间的G 0/3-4端口作为虚拟交换链路。配置AC1为主,AC2为备。主设备 description为AC1,备用设备description为AC2。 AC1 virtual-ac domain 100device 1 device 1 priority 200 device 1 description …

DHCP欺骗

DHCP 欺骗原理DHCP 协议(Dynamic Host Configuration Protocol) 动态主机配置协议:主要给客户机提供 TCP/IP 参数,包括:IP 地址、子网掩码、网关、DNS、租期工作原理应用层协议,基于UDP 主机向服务器 67 号端口发送 DHCP 请求 服务器响应给客户机的 68号端口配置设置DHCP 服…

Redis运行的时候碰到# Creating Server TCP listening socket *:6379: bind: No error

Redis运行的时候碰到# Creating Server TCP listening socket *:6379: bind: No error 解决方案: 1、启动redis客户端:redis-cli.exe。 2、执行关闭命令:输入shutdown3、执行退出命令:exit4、重新启动Redis输入:redis-server.exe redis.windows.conf

https实验

https 实验原理httphttps https = http + SSL/TLS •SSL: Secure Socket Layer 安全套接层 •TLS: Transport Layer Security 传输层安全协议加密方式:PKI(公钥基础设施)使用公钥技术和数字签名来保证信息安全由公钥密码算法、数字证书(Certificate)、CA(Certificate Aut…

手把手教你搭建OpenScenario交通场景(上)

经纬恒润动力学仿真软件ModelBase基于OpenScenario1.0标准,开发内嵌了场景编辑器,可用于对仿真测试过程中的车辆行驶道路模型之外,继续进行周边动态场景的搭建。 OpenScenario是一种专为自动驾驶系统仿真测试设计的场景描述语言,它基于XML格式,旨在提供一个标准化、…

动态规划题单2

第一个题单编辑到后面实在是太卡了,就新开了一个,以后应该也会 \(30\) 题为一个题单。 31.CF1580D Subsequence CF1580D Subsequence 不会笛卡尔树,但是看到题解区的妙妙解法...... 题目的式子非常大便,我们考虑把它翻译成人话: 一个子序列的价值为: \(sum*m - 每两个数及他…