在「先獲取 ID,再填寫表單提交」的業務中(如訂單號預生成、分布式 ID 預分配),需實現:前端點擊按鈕 → 異步請求後端 → 查詢數據庫最大 ID + 1 → 回填前端只讀輸入框。
<input id="userId" name="userId" value="" type="text" readonly/>
<input value="獲取最大 UserID" onclick="getUserId()" type="button">
<script>
function getUserId() {
$.getJSON('${basePath}user/getUserId.do', function(data) {
// data 格式: { "userId": 182888 }
$('#userId').val(data.userId);
}).fail(function(xhr) {
alert('獲取失敗: ' + xhr.status);
});
}
</script>
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired private UserSlaveService userSlaveService;
private static final Logger log = LoggerFactory.getLogger(UserController.class);
@GetMapping("/getUserId.do")
public Map<String, Object> getUserId() {
Map<String, Object> result = new HashMap<>();
try {
Integer nextId = userSlaveService.getUserId();
result.put("userId", nextId);
result.put("success", true);
} catch (Exception e) {
log.error("獲取ID異常", e);
result.put("success", false);
result.put("msg", "服務器內部錯誤");
}
return result; // 自動序列化為 JSON
}
}
public interface UserSlaveService {
Integer getUserId() throws Exception;
}
@Service
public class UserSlaveServiceImpl implements UserSlaveService {
@Autowired private IUserDAO userDAO;
@Override public Integer getUserId() throws Exception { return userDAO.getUserId(); }
}
public interface IUserDAO {
Integer getUserId() throws Exception;
}
<!-- UserMapper.xml -->
<mapper namespace="com.dao.IUserDAO">
<select id="getUserId" resultType="java.lang.Integer">
SELECT COALESCE(MAX(user_id), 0) + 1 AS userId FROM user_info
</select>
</mapper>
| 環節 | 要點 |
|---|---|
| SQL 寫法 | COALESCE(MAX(id),0)+1 兼容空表;MySQL 也可用 IFNULL |
| 併發風險 | 高併發下可能重複,生產環境建議: ① 數據庫自增主鍵 + LAST_INSERT_ID() ② Redis INCR 原子操作 ③ 雪花算法/UUID 分布式 ID |
| @ResponseBody | Spring 4+ 推薦用 @RestController 替代 |
| 字符編碼 | Spring MVC 配置 CharacterEncodingFilter 統一 UTF-8 |
@Autowired private StringRedisTemplate redisTemplate;
public Long getNextIdRedis(String key) {
return redisTemplate.opsForValue().increment(key); // 原子自增,高併發安全
}
本文方案適用於低併發、單體架構的傳統項目維護。新項目請優先考慮數據庫自增主鍵或分布式 ID 生成器,避免「查最大值+1」的固有併發缺陷。