package me.test.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Queue;
import javax.annotation.Resource;
import me.test.db.router.DataSourceKey;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
@Service("userService")
public class UserServiceImpl implements UserService {
@Resource(name = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Resource(name = "testTransService")
private TestTransService testTransService;
private UserRowMapper userRowMapper = new UserRowMapper();
private static class UserRowMapper implements RowMapper<User> {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getLong("ID"));
user.setHospitalId(rs.getLong("HOSPITAL_ID"));
user.setName(rs.getString("NAME"));
user.setRemark(rs.getString("REMARK"));
return user;
}
}
@Override
@Transactional(readOnly = true)
@DataSourceKey("#hospitalId")
public User selectById(Long hospitalId, Long userId) {
return jdbcTemplate.queryForObject("SELECT ID, HOSPITAL_ID, NAME, REMARK FROM T_USER WHERE ID=?",
new Object[] { userId }, userRowMapper);
}
@Override
@Transactional(readOnly = true)
public List<User> selectAll(@DataSourceKey Long hospitalId) {
return jdbcTemplate.query("SELECT ID, HOSPITAL_ID, NAME, REMARK FROM T_USER WHERE HOSPITAL_ID=?",
new Object[] { hospitalId }, userRowMapper);
}
@Override
@Transactional
public Long insert(Long hospitalId, String name, String remark) {
Assert.notNull(hospitalId, "hospitalId must not be null");
// 如果两家医院的数据放 [不] 在同一个库内,则应where条件带 HOSPITAL_ID = ? 查询条件
// Long maxUserId = jdbcTemplate.queryForObject("SELECT MAX(ID) FROM T_USER WHERE HOSPITAL_ID = ?", Long.class,
// hospitalId);
// 如果两家医院的数据放在同一个库内,则应where条件不带 HOSPITAL_ID = ? 查询条件
Long maxUserId = jdbcTemplate.queryForObject("SELECT MAX(ID) FROM T_USER", Long.class);
Long newUserId = maxUserId + 1;
jdbcTemplate.update("INSERT INTO T_USER (ID, HOSPITAL_ID, NAME, REMARK) VALUES (? , ?, ?, ?)",
new Object[] { newUserId, hospitalId, name, remark });
return newUserId;
}
@Override
@Transactional
public void updateById(Long hospitalId, Long userId, String remark) {
jdbcTemplate.update("UPDATE T_USER SET REMARK=? WHERE ID=?",
new Object[] { remark, userId });
}
@Override
@Transactional
public void deleteById(Long hospitalId, Long userId) {
jdbcTemplate.update("DELETE FROM T_USER WHERE ID=?", new Object[] { userId });
}
// -------------------------------------------------------
@Override
public void multiUpdate(Queue<UpdateRecord> leftRecs) {
UpdateRecord nextRec = leftRecs.poll();
if (nextRec == null) {
return;
}
// 递归调用
// 由于Spring AOP不支持同一个类内部的方法1调用被AOP的方法2,
// 也不支持被AOP的方法的递归自调用,
// 因此将需要事务控制的方法定义在其他的类中。
switch (nextRec.getPropagation()) {
case REQUIRES_NEW:
testTransService.multiUpdateRequiresNewTrans(nextRec.getHospitalId(), nextRec, leftRecs);
break;
default:
testTransService.multiUpdateRequiredTrans(nextRec.getHospitalId(), nextRec, leftRecs);
}
}
@Override
public void multiUpdate(Long hospitalId, UpdateRecord curRec, Queue<UpdateRecord> leftRecs) {
// 更新
jdbcTemplate.update("UPDATE T_USER SET REMARK=? WHERE ID=?",
new Object[] { curRec.getRemark(), curRec.getUserId() });
UpdateRecord nextRec = leftRecs.poll();
// 退出递归
if (nextRec == null) {
return;
}
// 递归调用
switch (nextRec.getPropagation()) {
case REQUIRES_NEW:
testTransService.multiUpdateRequiresNewTrans(nextRec.getHospitalId(), nextRec, leftRecs);
break;
default:
testTransService.multiUpdateRequiredTrans(nextRec.getHospitalId(), nextRec, leftRecs);
}
// 更新状态
if (!curRec.isSucceed()) {
throw new RuntimeException("Failed update at " + curRec.getI() + " : " + curRec);
}
}
}