你写代码会复用公共SQL么?

点击上方"程序员蜗牛g",选择"设为星标"

跟蜗牛哥一起,每天进步一点点

程序员蜗牛g

大厂程序员一枚 跟蜗牛一起 每天进步一点点

33篇原创内容

**

公众号

"你在写代码时会复用公共SQL吗?如果会的话,能详细介绍一下你是如何实现的吗?"

实现方式一:MyBatis的<sql>标签

在Java后端开发中,我最常用的ORM框架是MyBatis。MyBatis提供了一个非常方便的特性------<sql>标签,可以用来定义可复用的SQL片段。

比如,在一个用户管理的模块中,经常需要查询用户的某些基础字段,像idusernameemail等。如果每次都手写这些字段,既麻烦又容易出错,我就用<sql>标签把它们抽出来。

举个例子,我的UserMapper.xml可能会这样写:

xml 复制代码
<!-- 定义公共SQL片段 -->
<sql id="userBaseColumns">
    id, username, email, created_at, updated_at
</sql>

<!-- 查询用户列表 -->
<select id="selectUserList" resultType="User">
    SELECT <include refid="userBaseColumns"/>
    FROM users 
    WHERE status = #{status}
</select>

<!-- 查询单个用户 -->
<select id="selectUserById" resultType="User">
    SELECT <include refid="userBaseColumns"/>
    FROM users 
    WHERE id = #{id}
</select>

通过<include>标签,我可以在多个SQL语句中复用userBaseColumns这个片段。这样,如果以后需要调整查询字段(比如新增phone字段),只需要改动<sql>定义的地方,所有引用它的查询都会自动更新,省时省力。

实现方式二:动态SQL与Java代码封装

有时候,SQL的复用不仅仅是字段列表,还可能是复杂的条件逻辑。比如,很多业务场景下会有分页查询的需求,LIMITOFFSET是固定的模式。我会结合MyBatis的动态SQL和Java代码来实现复用。

比如,我会写一个通用的分页工具类:

arduino 复制代码
public class PageHelper {
    public static String appendPageSql(String sql, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        return sql + " LIMIT " + pageSize + " OFFSET " + offset;
    }
}

然后在Mapper接口中调用:

arduino 复制代码
@SelectProvider(type = UserSqlProvider.class, method = "getUserListSql")
List<User> getUserList(int status, int pageNum, int pageSize);

class UserSqlProvider {
    public String getUserListSql(int status, int pageNum, int pageSize) {
        String sql = "SELECT id, username, email FROM users WHERE status = #{status}";
        return PageHelper.appendPageSql(sql, pageNum, pageSize);
    }
}

这样,任何需要分页的查询都可以复用PageHelper,只需要传入页码和每页大小即可。这种方式在Java层实现了SQL的动态拼接,既灵活又可控。

实现方式三:常量类管理SQL片段

如果项目中不完全依赖MyBatis,或者有些SQL是直接通过JDBC执行的,我会用Java的常量类来管理公共SQL片段。比如:

arduino 复制代码
public class SqlConstants {
    public static final String USER_BASE_COLUMNS = "id, username, email, created_at, updated_at";
    public static final String USER_TABLE = "users";
    public static final String SELECT_USER_BY_ID = 
        "SELECT " + USER_BASE_COLUMNS + " FROM " + USER_TABLE + " WHERE id = ?";
}

然后在DAO层使用:

typescript 复制代码
public User getUserById(Long id) {
    String sql = SqlConstants.SELECT_USER_BY_ID;
    return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
}

这种方式的好处是简单直观,适合小型项目或者需要快速开发的场景。不过缺点是缺乏动态性,如果SQL逻辑复杂,维护起来会稍显麻烦。

"在Java后端开发中,复用公共SQL是一个很实用的习惯。我会根据项目规模和需求选择合适的方式,小项目可能用常量类就够了,大项目则更倾向于MyBatis的<sql>标签或者动态SQL结合工具类。关键是要让代码既高效又易于维护。"

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

相关推荐
阿拉斯攀登4 分钟前
无人售货机库存异步更新方案:解决高并发下单库存卡顿问题
后端
阿拉斯攀登8 分钟前
无人售货机MQ消息丢失、重复消费、超时异常全套兜底方案
后端
做系统的大强11 分钟前
我用中文从零写了一个操作系统(下篇):从45个BUG到165个——假持久化、USB地狱与OS自举
后端
程序员老赵12 分钟前
Docker 部署 Rocky Linux:轻松搭建 RHEL 兼容企业级基础镜像平台
linux·后端·docker
用户61526121321014 分钟前
Java主流框架与源码:Spring Framework
后端
yume_sibai1 小时前
03-Rust 函数式编程特性(闭包 + Iterator + Option/Result + 链式调用)
开发语言·后端·rust
吃饱了得干活2 小时前
Redis 不是死脑筋,它是一套“会进化”的存储系统
redis·后端
伩仁2 小时前
别再 HTTP 200 一把梭了:用 RFC 9457 Problem Details 给 FastAPI 错误响应"立规矩"
后端
MeetTanG2 小时前
Go 实战锦囊|errgroup:优雅地管理并发任务组
后端·go
PragmaticWorks2 小时前
DDD 学了很多却用不上?因为你把“责任”和“时机”揉在了一起
后端·领域驱动设计