在一次Java后端開發的面試中,面試官問了我一個問題:“你在寫代碼時會復用公共SQL嗎?如果會的話,能詳細介紹一下你是如何實現的嗎?”這個問題讓我眼前一亮,因為在實際項目中,SQL復用確實是一個非常實用且能提升代碼質量的做法。下面是我當時的回答,也借此機會整理成一篇博客,和大家分享一下我的經驗。
我的回答:是的,我會復用公共SQL
我告訴面試官:“是的,我在開發中經常會復用公共SQL,尤其是在Java后端項目中。復用SQL不僅能減少代碼重復,還能提高可維護性和一致性。我通常會結合具體的業務場景和框架特性來實現,比如使用MyBatis這樣的ORM框架,或者通過自定義工具類來管理公共SQL片段。”
接著,面試官讓我詳細講講實現方式,我就從以下幾個方面展開了說明。
實現方式一:MyBatis的標簽
在Java后端開發中,我最常用的ORM框架是MyBatis。MyBatis提供了一個非常方便的特性——標簽,可以用來定義可復用的SQL片段。比如,在一個用戶管理的模塊中,經常需要查詢用戶的某些基礎字段,像id、username、email等。如果每次都手寫這些字段,既麻煩又容易出錯,我就用標簽把它們抽出來。
舉個例子,我的UserMapper.xml可能會這樣寫:
xml 體驗AI代碼助手 代碼解讀復制代碼
id, username, email, created_at, updated_at
通過標簽,我可以在多個SQL語句中復用userBaseColumns這個片段。這樣,如果以后需要調整查詢字段(比如新增phone字段),只需要改動定義的地方,所有引用它的查詢都會自動更新,省時省力。
實現方式二:動態SQL與Java代碼封裝
有時候,SQL的復用不僅僅是字段列表,還可能是復雜的條件邏輯。比如,很多業務場景下會有分頁查詢的需求,LIMIT和OFFSET是固定的模式。我會結合MyBatis的動態SQL和Java代碼來實現復用。
比如,我會寫一個通用的分頁工具類:
java 體驗AI代碼助手 代碼解讀復制代碼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接口中調用:
java 體驗AI代碼助手 代碼解讀復制代碼@SelectProvider(type = UserSqlProvider.class, method = “getUserListSql”)
List 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片段。比如:
java 體驗AI代碼助手 代碼解讀復制代碼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層使用:
java 體驗AI代碼助手 代碼解讀復制代碼public User getUserById(Long id) {
String sql = SqlConstants.SELECT_USER_BY_ID;
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
}
這種方式的好處是簡單直觀,適合小型項目或者需要快速開發的場景。不過缺點是缺乏動態性,如果SQL邏輯復雜,維護起來會稍顯麻煩。
為什么復用SQL很重要?
我還跟面試官補充了一下為什么要這樣做。復用公共SQL有幾個明顯的好處:
減少重復代碼:避免在多個地方寫相同的SQL片段,符合DRY(Don’t Repeat Yourself)原則。
提高可維護性:改動一處,全局生效,降低出錯風險。
提升一致性:比如字段順序、命名規范都能統一,避免開發人員各自發揮。
總結
最后,我總結道:“在Java后端開發中,復用公共SQL是一個很實用的習慣。我會根據項目規模和需求選擇合適的方式,小項目可能用常量類就夠了,大項目則更傾向于MyBatis的標簽或者動態SQL結合工具類。關鍵是要讓代碼既高效又易于維護。”