@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);
}
                


















