ORM框架面试题常见考点解析
最近朋友小李去面试Java开发岗位,被问到好几个关于ORM框架的问题,当场有点懵。其实这种情况很常见,尤其是现在很多项目都用ORM框架,面试官自然会重点考察这块知识。
什么是ORM?为什么用它?
ORM,全称是对象关系映射(Object Relational Mapping),说白了就是让程序里的对象和数据库里的表能对应上。比如Java里的User类,对应数据库的user表,user.getId() 就等于查表的id字段。
不用ORM的时候,写SQL、手动封装结果集,代码又长又容易出错。用了像MyBatis、Hibernate这样的框架,操作数据库就像调用方法一样简单。
Hibernate和MyBatis有什么区别?
这是高频问题。Hibernate是全自动ORM,你定义好映射,它帮你生成SQL,连事务管理都包了。适合快速开发,但有时候生成的SQL不够优化。
MyBatis是半自动的,SQL得自己写,但灵活性高,适合对性能要求高的场景。比如做报表查询,字段多、关联复杂,用MyBatis写原生SQL更可控。
<select id="getUserById" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>延迟加载是什么?怎么实现的?
比如一个用户有多个订单,查用户的时候并不马上查订单,等真正调用user.getOrders()时才去数据库取,这就是延迟加载。可以减少不必要的查询,提升性能。
在Hibernate里,可以通过fetch = FetchType.LAZY来配置。注意别在session关闭后再访问延迟属性,不然会报异常。
一级缓存和二级缓存的区别
一级缓存是Session级别的,同一个Session中查询同一ID的对象,第二次不会走数据库。二级缓存是跨Session的,比如用Ehcache或Redis存公共数据,多个用户访问同一个数据时能复用。
缓存虽然快,但也可能数据不一致。比如别人改了数据库,缓存没及时更新,就会看到旧数据。所以得合理设置缓存策略。
怎么防止SQL注入?
用ORM框架本身就能很大程度避免这个问题。比如MyBatis用#{}而不是${}传参。#{}会被替换成预编译参数,数据库会当成值处理,不会拼进SQL语句里。
而${}是直接字符串替换,危险得多。比如order by ${column},如果column来自用户输入,就可能被注入恶意代码。
实体类和表是怎么映射的?
可以用注解或者XML配置。比如JPA里用@Entity、@Table、@Id这些注解,一眼就知道哪个类对应哪张表。
@Entity
@Table(name = "user")
public class User {
@Id
private Long id;
private String name;
// getter/setter省略
}这种方式比写一堆配置文件直观多了,现在大多数项目都用注解。
面试问到ORM,核心就是理解它怎么简化数据库操作,以及在实际使用中可能遇到的问题。掌握几个主流框架的特点,结合项目经验讲清楚,基本就能过关。