@Repository
是Spring
注解,标识数据访问层组件(DAO, Data Access Object
)
当一个类被标记为 @Repository 时:
1、组件扫描与自动代理: Spring
通过组件扫描(Component Scan
)机制发现带有 @Repository
的类,并将其纳入Spring IoC容器
管理,创建对应的Bean实例
。
2、异常处理增强: Spring
会针对标记了 @Repository
的类捕获特定的数据访问异常(如JDBC相关的SQLException),并将其转换为Spring DataAccessException
层次结构中的一个合适异常,简化异常处理。
3、事务管理: 在使用Spring AOP
进行声明式事务管理的情况下,标记为 @Repository
的类的方法可以自动参与到事务中去,无需额外配置事务切面。
4、语义清晰: 尽管 @Repository
在功能上等同于 @Component
或 @Service
注解,但是从语义上讲,它更明确地表明该类是用来执行数据库操作
或数据持久化
工作的。
使用样例
基础DAO类
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
// 假设这里有一个JdbcTemplate或EntityManager等数据访问工具对象
private JdbcTemplate jdbcTemplate;
@Autowired
public UserRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public User findByUsername(String username) {
// 使用jdbcTemplate执行SQL查询以根据用户名查找用户
// ...
}
public void save(User user) {
// 执行保存用户的SQL语句
// ...
}
}
结合Spring Data JPA
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
与MyBatis整合
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepositoryMapper {
@Select("SELECT * FROM users WHERE username = #{username}")
User findByUsername(@Param("username") String username);
}
自定义实现并处理特定异常
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
@Repository
public class CustomUserRepository {
@Autowired
private SomeDataAccessObject dataAccessObject;
public User getUserById(Long id) throws CustomNotFoundException {
try {
return dataAccessObject.getUser(id);
} catch (DataAccessException ex) {
throw new CustomNotFoundException("User not found", ex);
}
}
}
在组件扫描和事务管理中配合使用
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.example.repository"})
public class AppConfig {
// 配置数据源、JdbcTemplate或SessionFactory等
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
}
// 在应用中
@Repository
public class ProductRepository {
// 这里的方法将在事务中执行
public void updateProduct(Product product) {
// 更新产品逻辑
}
}
结合@Transactional注解实现事务管理
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private UserRepository userRepository;
@Transactional
public void placeOrder(Order order, User user) {
// 保存订单
order.setUser(user);
orderRepository.save(order);
// 更新用户购买记录
user.getOrders().add(order);
userRepository.save(user);
}
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> { }
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> { }
使用Spring Data REST配合@Repository
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends CrudRepository<Product, Long> {
// Spring Data JPA自动提供CRUD操作,无需编写SQL或查询方法
List<Product> findByCategory(Category category);
// 自定义查询方法
@Query("SELECT p FROM Product p WHERE p.name LIKE %:name%")
List<Product> findByNameLike(@Param("name") String name);
}
使用Spring Data R2DBC配合@Repository
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends R2dbcRepository<Product, Long> {
Flux<Product> findByCategory(String category);
@Query("SELECT * FROM products WHERE name LIKE $1")
Flux<Product> findByNameLike(String namePattern);
}