What is `@Repository` does?

发布时间:2024年01月15日

@RepositorySpring注解,标识数据访问层组件(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);
}
文章来源:https://blog.csdn.net/weixin_37646636/article/details/135607037
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。