@Mapper
是 MyBatis-Spring 集成库中的一个注解,用于标识一个接口作为 MyBatis 的 Mapper 接口。当你使用 MyBatis 与 Spring 框架一起时,你可以使用这个注解来自动扫描和注册 Mapper 接口,这样 Spring 容器就可以自动管理这些 Mapper 接口的实现,而无需手动配置。
这里是一个简单的例子,展示如何使用 @Mapper
注解:
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(int id);
// 还可以定义其他CRUD操作的方法
}
在上面的例子中,UserMapper
接口使用 @Mapper
注解标识,这意味着 MyBatis 会为这个接口创建一个代理实现,这个实现会处理与数据库相关的操作。@Select
注解用于指定 SQL 查询语句。
如果你有很多 Mapper 接口,并且想要避免在每个接口上都写 @Mapper
注解,你可以使用 @MapperScan
注解在配置类上,一次性扫描多个 Mapper 接口:
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.example.demo.mapper") // 指定Mapper接口所在的包路径
public class MyBatisConfig {
// 其他配置...
}
在上面的例子中,@MapperScan
注解用于指定 MyBatis 应该扫描哪个包下的 Mapper 接口。这样,在该包下的所有接口都会被自动注册为 MyBatis 的 Mapper 接口,而无需在每个接口上都添加 @Mapper
注解。
需要注意的是,虽然 @Mapper
注解本身提供了足够的功能来标识 Mapper 接口,但使用 @MapperScan
通常更加方便,因为它允许你一次性配置多个 Mapper 接口,减少了代码的重复。
Spring Cloud Alibaba的示例项目 integrated-account 中代码:
import org.springframework.stereotype.Repository;
/**
* @author TrevorLink
*/
@Mapper
@Repository
public interface AccountMapper {
@Select("SELECT money FROM account WHERE user_id = #{userId}")
Integer getBalance(@Param("userId") String userId);
@Update("UPDATE account SET money = money - #{price},update_time = #{updateTime} WHERE user_id = #{userId} AND money >= ${price}")
int reduceBalance(@Param("userId") String userId, @Param("price") Integer price,
@Param("updateTime") Timestamp updateTime);
}
服务层调用代码:
@Service
public class AccountServiceImpl implements AccountService {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private AccountMapper accountMapper;
@Override
@Transactional
public void reduceBalance(String userId, Integer price) throws BusinessException {
logger.info("[reduceBalance] currenet XID: {}", RootContext.getXID());
checkBalance(userId, price);
Timestamp updateTime = new Timestamp(System.currentTimeMillis());
int updateCount = accountMapper.reduceBalance(userId, price, updateTime);
if (updateCount == 0) {
throw new BusinessException("reduce balance failed");
}
}
@Override
public Result<?> getRemainAccount(String userId) {
Integer balance = accountMapper.getBalance(userId);
if (balance == null) {
return Result.failed("wrong userId,please check the userId");
}
return Result.success(balance);
}
private void checkBalance(String userId, Integer price) throws BusinessException {
Integer balance = accountMapper.getBalance(userId);
if (balance < price) {
throw new BusinessException("no enough balance");
}
}
}
上面代码中,自动注入 AccountMapper 对象,然后用其执行了 sql 语句,实现账户余额查询和扣减的功能。