从手写SQL到ORM:一个小电商后台的转变
老张是公司里干了十年的老程序员,一直负责维护一个小型电商平台的后台系统。最开始,所有的数据操作都是直接拼接SQL语句,比如查订单要这么写:
String sql = "SELECT * FROM orders WHERE user_id = " + userId + " AND status = '" + status + "'";
// 然后手动执行查询,再一行行读取结果,映射成对象
这种写法不仅容易出错,还容易被注入攻击。有一次用户输入了个特殊字符,整个订单页直接报错,客服电话都快被打爆了。
引入MyBatis Plus:告别拼接字符串
后来团队决定引入MyBatis Plus,一个基于MyBatis的增强ORM框架。改完之后,查订单变成了这样:
QueryWrapper<Order> wrapper = new QueryWrapper<>();
wrapper.eq("user_id", userId).eq("status", status);
List<Order> orders = orderMapper.selectList(wrapper);
代码清爽了不说,连分页都能自动处理。更关键的是,参数都通过预编译传入,SQL注入的风险基本没了。
另一个场景:快速搭建内部管理系统
新来的实习生小李被安排做一个员工考勤记录的小功能。按以前的节奏,建表、写DAO、写Service、写Controller,怎么也得两三天。这次他用了Spring Data JPA,事情变得简单多了。
先定义一个实体类:
@Entity
@Table(name = "attendance")
public class Attendance {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String employeeName;
private LocalDate checkDate;
private String status;
// getter 和 setter 省略
}
然后写个接口继承 JpaRepository:
public interface AttendanceRepository extends JpaRepository<Attendance, Long> {
List<Attendance> findByEmployeeName(String name);
List<Attendance> findByCheckDate(LocalDate date);
}
就这么两步,增删改查全有了。Controller里直接注入这个接口就能用,连SQL都不用写一句。小李一天就把功能做完了,还顺手加了个按日期范围查询的功能。
Django中的ORM:非Java生态也能高效开发
朋友老刘在一家新媒体公司做后台,他们用的是Python的Django框架。每次要加个新栏目,比如“读者投稿”,他只需要在models.py里定义一下:
class Submission(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
content = models.TextField()
submitted_at = models.DateTimeField(auto_now_add=True)
然后跑个迁移命令:python manage.py makemigrations 和 python manage.py migrate,数据库表就自动生成了。前端要查最近一周的投稿?一行代码搞定:
Submission.objects.filter(submitted_at__gte=timezone.now() - timezone.timedelta(days=7))
这种写法既直观又安全,连刚学Python的新人都能看懂。
ORM不是银弹,但确实省了不少事
当然,ORM也不是万能的。遇到特别复杂的报表查询,还是得写原生SQL或者视图来优化性能。但在日常开发中,80%的CRUD操作用ORM完全够用,还能大幅减少低级错误。
像订单管理、用户信息、商品分类这些结构清晰的模块,用上ORM之后,开发速度明显加快,代码也更容易维护。关键是,不用再半夜被数据库语法错误叫起来改bug了。