跳到主要内容

7.1 最佳实践

使用建议

场景推荐方式说明
简单 CRUDPojo类型安全,推荐
动态表名Table灵活
复杂查询Jdbc / Sql可读性好
报表统计Sql(预设 SQL)便于维护
批量操作Batch性能好

代码组织

推荐分层:Controller + Service

// Service 层(业务逻辑和事务)
@Service
public class UserService {
@Transactional
public void createUserWithLog(User user) {
DB.Pojo.insert(user);
Long id = user.getId();
DB.Pojo.insert(new UserLog(id, "created"));
}

public List<User> findActiveUsers() {
return DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.queryBeanList();
}
}

// Controller 层
@RestController
public class UserController {
@Autowired
private UserService userService;

@PostMapping("/users")
public void create(@RequestBody User user) {
userService.createUserWithLog(user);
}
}

简化场景:Controller 直接调用

@RestController
public class UserController {
@GetMapping("/users")
public List<User> list(@RequestParam(required = false) Integer status) {
return DB.Pojo.select(User.class)
.eq(status != null, User::getStatus, status)
.queryBeanList();
}
}

性能优化

只查需要的字段

// ✅ 只查需要的字段
DB.Pojo.select(User.class)
.columns(User::getId, User::getName)
.queryBeanList();

避免 N+1

// ❌ N+1
for (Order order : orders) {
User user = DB.Pojo.select(User.class)
.eq(User::getId, order.getUserId()).queryBean();
}

// ✅ 批量查询
List<Long> userIds = orders.stream().map(Order::getUserId).distinct().collect(toList());
Map<Long, User> userMap = DB.Pojo.select(User.class)
.in(User::getId, userIds)
.queryBeanList().stream()
.collect(Collectors.toMap(User::getId, u -> u));

批量插入

// ✅ 使用批量操作
DB.Batch.insert(users);

SQL 注入防护

// ✅ 安全:参数化查询
DB.Pojo.select(User.class).eq(User::getName, userInput).queryBeanList();
DB.Jdbc.select("SELECT * FROM user WHERE name = ?", userInput).queryList();

// ❌ 危险:字符串拼接
// String sql = "SELECT * FROM user WHERE name = '" + userInput + "'";

常见错误

  • queryList() 返回 List<ResultMap>,要 Bean 用 queryBeanList()
  • sql()#{key}apply(){0}(新代码请用 sql
  • 预设 SQL key 必须加 "key." 前缀
  • 写操作必须 .execute() 结尾
  • in() 不可传单值,传 List 或 CSV 字符串