Spring系列之DAO-17

DAO

Spring 中的数据访问对象 (DAO) 支持旨在以一致的方式轻松使用数据访问技术(例如 JDBC、Hibernate 或 JPA)。这使您可以相当轻松地在上述持久性技术之间切换,并且还可以让您编写代码而不必担心捕获每种技术特定的异常。

保证您的数据访问对象 (DAO) 或存储库提供异常转换的最佳方法是使用@Repository注释。此注释还允许组件扫描支持查找和配置您的 DAO 和存储库,而无需为它们提供 XML 配置条目。

任何 DAO 或存储库实现都需要访问持久性资源,具体取决于所使用的持久性技术。例如,基于 JDBC 的存储库需要访问 JDBC DataSource,而基于 JPA 的存储库需要访问 EntityManager. 完成此操作的最简单方法是使用 、 或 注释之一注入此资源@Autowired依赖@Inject项 。以下示例适用于 JPA 存储库:@Resource``@PersistenceContext

@Repository
public class JpaMovieFinder implements MovieFinder {

    @PersistenceContext
    private EntityManager entityManager;

    // ...
}

如果您使用经典的 Hibernate API,则可以注入SessionFactory,如以下示例所示:

@Repository
public class HibernateMovieFinder implements MovieFinder {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    // ...
}

我们在这里展示的最后一个示例是针对典型的 JDBC 支持。您可以将 DataSource注入注入到初始化方法或构造函数中,您可以在其中 使用 this创建一个JdbcTemplate和其他数据访问支持类(例如和其他) 。以下示例自动装配 a :SimpleJdbcCall``DataSource``DataSource

@Repository
public class JdbcMovieFinder implements MovieFinder {

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void init(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    // ...
}

简化实例

倘若肯再多写一点样板代码,就可以把AbstractDao改成泛型,并实现getById()getAll()deleteById()这样的通用方法:

public abstract class AbstractDao<T> extends JdbcDaoSupport {
    private String table;
    private Class<T> entityClass;
    private RowMapper<T> rowMapper;

    public AbstractDao() {
        // 获取当前类型的泛型类型:
        this.entityClass = getParameterizedType();
        this.table = this.entityClass.getSimpleName().toLowerCase() + "s";
        this.rowMapper = new BeanPropertyRowMapper<>(entityClass);
    }

    public T getById(long id) {
        return getJdbcTemplate().queryForObject("SELECT * FROM " + table + " WHERE id = ?", this.rowMapper, id);
    }

    public List<T> getAll(int pageIndex) {
        int limit = 100;
        int offset = limit * (pageIndex - 1);
        return getJdbcTemplate().query("SELECT * FROM " + table + " LIMIT ? OFFSET ?",
                new Object[] { limit, offset },
                this.rowMapper);
    }

    public void deleteById(long id) {
        getJdbcTemplate().update("DELETE FROM " + table + " WHERE id = ?", id);
    }
    ...
}

这样,每个子类就自动获得了这些通用方法:

@Component
@Transactional
public class UserDao extends AbstractDao<User> {
    // 已经有了:
    // User getById(long)
    // List<User> getAll(int)
    // void deleteById(long)
}

@Component
@Transactional
public class BookDao extends AbstractDao<Book> {
    // 已经有了:
    // Book getById(long)
    // List<Book> getAll(int)
    // void deleteById(long)
}

可见,DAO模式就是一个简单的数据访问模式,可以基于泛型实现更通用、更简洁的DAO模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吕布辕门

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值