`

Spring数据访问策略

阅读更多
Spring封装的数据访问异常
与SQLException是一个Checked Exception不同,Spring定义的基本书籍访问异常DataAccessException是一个RuntimeException,DataAccessException继承自NestedRuntimeException,完整的保留了原始异常信息。

异常定义
DataAccessExceptionSpringDAO异常体系跟类
ConcurrencyFailureException在多个并发访问时,无法乐观锁定或者获得数据库锁等
DataAccessResourceFailureException访问数据彻底失败,例如无法连接数据库
DataRetrievalFailureException无法获得指定数据,例如,根据主键无法查到相应记录
InvalidDataAccessResourceUsageException无效的数据访问方法,使用了语法错误的SQL语句
PermissionDeniedDataAccessException没有数据访问权限,例如,当前数据库登录用户无权访问特定表
UncategorizedDataAccessException无法归类的异常


准备数据库环境
// HsqldbUtil类,创建Book表,并插入两条数据
public static void startDatabase() {
    server = new Server();
    server.setDatabaseName(0, "test");
    server.setDatabasePath(0, "mem:bookstore");
    server.setLogWriter(null);
    server.setErrWriter(null);
    server.start();
}


<!-- 定义DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
	<property name="url" value="jdbc:hsqldb:mem:bookstore" />
	<property name="username" value="sa" />
	<property name="password" value="" />
</bean>
<!-- 使用DriverManagerDataSource为了方便调试  实际中可方便更换为 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/xxxDataSource"/>
</bean>


主键生成策略
1.数据库内置自增 (不好移植)
2.整形字段,程序控制主键自动增长 (集群时要严格控制同步)
3.UUID 根据计算机MAC地址和时间,随机计算生成,唯一 (128位整数,浪费空间)


public interface BookDao {
    List<Book> queryAll();
    List<Book> queryByAuthor(String author);
    void create(Book book);
    void update(Book book);
    void delete(String id);
}



JdbcTemplet
<!-- 注入dataSource -->
<bean id="jdbcTemplateBookDao" class="example.chapter5.JdbcTemplateBookDao">
	<property name="dataSource" ref="dataSource" />
</bean>

public class JdbcTemplateBookDao extends JdbcDaoSupport implements BookDao {
    // ResultSet映射为Bean的方式
    class BookRowMapper implements RowMapper {
        public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            Book book = new Book();
            book.setId(rs.getString("id"));
            book.setName(rs.getString("name"));
            book.setAuthor(rs.getString("author"));
            return book;
        }
    }

    @SuppressWarnings("unchecked")
    public List<Book> queryAll() {
        return getJdbcTemplate().query(
                "select * from Book",
                new BookRowMapper());
    }

    @SuppressWarnings("unchecked")
    public List<Book> queryByAuthor(String author) {
        return getJdbcTemplate().query(
                "select * from Book where author=?",
                new Object[] { author },
                new BookRowMapper());
    }

    public void create(Book book) {
        getJdbcTemplate().update(
                "insert into Book (id, name, author) values (?, ?, ?)",
                new Object[] {book.getId(), book.getName(), book.getAuthor()});
    }

    public void update(Book book) {
        getJdbcTemplate().update(
                "update Book set name=?, author=? where id=?",
                new Object[] {book.getName(), book.getAuthor(), book.getId()});
    }

    public void delete(String id) {
        getJdbcTemplate().update(
                "delete from Book where id=?",
                new Object[] {id});
    }

}



集成Hibernate
Hibernate管理Java类到数据库表的映射,提供了强大的基于对象的查询语句HQL,大幅减少数据库访问需要编写的代码的SQL语句,通过“方言”,最大限度降低了对特定数据库的依赖。
Hibernate还提供了系列复杂功能来简化数据库操作。
1.延迟加载,不一次取得所有相关联的对象,而是希望访问某个对象是再去数据库读取
2.主动抓取,允许在一个查询操作中就获得所有关联的对象,减少数据库连接次数
3.缓存
4.级联操作,外键关联的表,更新一个表时,需要同时更新其他表,级联删除 级联更新
<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	<property name="dataSource" ref="dataSource" />
	<property name="annotatedClasses">
		<list>
			<value>example.chapter5.Book</value>
		</list>
	</property>
	<property name="annotatedPackages">
		<list>
			<value>example.chapter5</value>
		</list>
	</property>
	<property name="hibernateProperties">
		<props>
			<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
			<prop key="hibernate.show_sql">true</prop>
			<prop key="hibernate.jdbc.fetch_size">10</prop>
			<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
		</props>
	</property>
	<property name="eventListeners">
		<map>
			<entry key="pre-update">
				<bean class="org.hibernate.validator.event.ValidatePreUpdateEventListener" />
			</entry>
			<entry key="pre-insert">
				<bean class="org.hibernate.validator.event.ValidatePreInsertEventListener" />
			</entry>
		</map>
	</property>
</bean>


@Entity(name="Book")
public class Book {
// @Entity 作为数据库表映射 @Id 主键  @Transient不需要持久化字段
    private String id;
    private String name;
    private String author;

    @Id
    @Pattern(regex="[a-z0-9\\-]{36}", message="ID只能由英文字母,数字和-构成,长度为36个字符")
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
}

public class HibernateBookDao extends HibernateDaoSupport implements BookDao {

    @SuppressWarnings("unchecked")
    public List<Book> queryAll() {
        return getHibernateTemplate().find("select b from Book as b");
    }

    @SuppressWarnings("unchecked")
    public List<Book> queryByAuthor(String author) {
        return getHibernateTemplate().find("select b from Book as b where b.author=?", author);
    }

    public void create(Book book) {
        getHibernateTemplate().save(book);
    }

    public void delete(String id) {
        Book book = (Book) getHibernateTemplate().load(Book.class, id);
        getHibernateTemplate().delete(book);
    }

    public void update(Book book) {
        getHibernateTemplate().update(book);
    }

}



集成Ibtais
<bean id="iBatisBookDao" class="example.chapter5.IBatisBookDao">
	<property name="sqlMapClient">
		<bean class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
			<property name="configLocation" value="ibatis-sql-map-config.xml" />
			<property name="dataSource" ref="dataSource" />
		</bean>
	</property>
</bean>


public class IBatisBookDao extends SqlMapClientDaoSupport implements BookDao {

    @SuppressWarnings("unchecked")
    public List<Book> queryAll() {
        return getSqlMapClientTemplate().queryForList("queryAll");
    }

    @SuppressWarnings("unchecked")
    public List<Book> queryByAuthor(String author) {
        return getSqlMapClientTemplate().queryForList("queryByAuthor", author);
    }

    public void create(Book book) {
        getSqlMapClientTemplate().insert("create", book);
    }

    public void delete(String id) {
        getSqlMapClientTemplate().delete("delete", id);
    }

    public void update(Book book) {
        getSqlMapClientTemplate().update("update", book);
    }
}


集成JPA
Spring对JPA采用Adapter模式,使JPA和其他持久化机制(Hibernate Toplink JDO)拥有一致的编程模型。

<!--  
  LocalEntityManagerFactoryBean 提供了标准的JPA初始化配置
  LocalContainerEntityManagerFactoryBean 更灵活,可以注入Spring管理的DataSource
-->
<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<!-- Adapter 选择实现JPA的具体框架 -->
	<property name="jpaVendorAdapter">
		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
			<property name="showSql" value="true" />
			<property name="generateDdl" value="false" />
		</bean>
	</property>
</bean> 

<bean id="jpaTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
	<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven transaction-manager="jpaTxManager" />


public class JpaBookDao extends JpaDaoSupport implements BookDao {

    @SuppressWarnings("unchecked")
    public List<Book> queryAll() {
        return getJpaTemplate().find("select b from Book b");
    }

    @SuppressWarnings("unchecked")
    public List<Book> queryByAuthor(String author) {
        return getJpaTemplate().find("select b from Book b where b.author=?", new Object[] { author });
    }

    public void create(Book book) {
        getJpaTemplate().persist(book);
    }

    public void delete(String id) {
        Book book = getJpaTemplate().find(Book.class, id);
        getJpaTemplate().remove(book);
    }

    public void update(Book book) {
        getJpaTemplate().merge(book);
    }
}
分享到:
评论

相关推荐

    Spring 2.0 开发参考手册

    12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO...

    Spring-Reference_zh_CN(Spring中文参考手册)

    12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 ...

    springMongodb参考文档中文版

    Spring数据扩展 7.8.1。Querydsl扩展 7.8.2。Web支持 7.8.3。存储库填充程序 7.8.4。传统网络支持 参考文档 8.介绍 8.1。文档结构 9. MongoDB支持 9.1。入门 9.2。示例存储库 9.3。用Spring连接到MongoDB 9.3.1。...

    Spring中文帮助文档

    12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring容器中创建 SessionFactory 12.2.3. The HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. ...

    spring chm文档

    12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO...

    Spring API

    12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring容器中创建 SessionFactory 12.2.3. The HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. ...

    高效Java数据访问组件Uncode-DAL全功能源码

    Uncode-DAL是一个功能全面的Java数据访问层组件,它深度整合了MyBatis、Spring JDBC以及Hibernate等主流ORM框架,致力于为开发者提供一套简便、高效的数据操作解决方案。该组件支持多数据源配置,能够实现读写分离、...

    Spring高级之注解驱动开发视频教程

    同时,在3.x版本之后,它开始之初Rest风格的请求URL,为开发者提供了开发基于Restful访问规则的项目提供了帮助。 SpringData是一组技术合集。里面包含了JDBC,Data JPA,Data Redis,Data Mongodb,Data Rabbit,...

    spring in action英文版

     5.3.2 声明一个简单的事务策略  5.4 通过方法名声明事务  5.4.1 使用NameMatchTransactionAttributeSource  5.4.2 名称匹配事务的捷径  5.5 用元数据声明事务  5.5.1 用元数据来书写事务属性  ...

    基于springboot的数据资产管理系统.zip

    数据访问控制模块提供了细粒度的权限管理功能,使企业能够控制和监控数据的访问和使用。数据备份与恢复功能确保数据的安全性和可恢复性,帮助企业应对数据丢失和灾难恢复。数据风险评估模块帮助企业发现和评估数据的...

    spring security 参考手册中文版

    第七部分 Spring数据集成 273 38. Spring Data&Spring安全配置 273 39. @Query中的安全表达式 273 第八部分 附录 274 40.安全数据库模式 274 40.1用户模式 274 40.1.1集团当局 274 40.2持久登录(记得我)架构 275 ...

    springCloud

    Spring Cloud简介 Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud0 CloudFoundry、Spring Cloud AWS、Spring Cloud ...

    spring中的基本设计模式

    数据访问对象模式(DAO) 工厂模式(factory) 模型视图控制器模式(MVC) 代理模式(proxy) 单例模式(singleton) 策略模式(strategy) 模板模式(template) 另外还有一个关于动态代理的小例子

    使用wx-java-miniapp-spring-boot-starter开发的微信小程序演示demo.zip

    其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始...

    spring boot + vue + element-ui + mongodb 实现网易buff爬虫数据可视化.zip

    其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始...

    如何使用Spring Cloud Gateway构建一个简单的微服务网关

    3.负载均衡:根据负载均衡策略将请求分发到不同的微服务实例,提高系统的吞吐量和可扩展性。 4.安全性和认证:通过集成认证和授权服务,实现对请求的安全验证和访问控制。 5.监控和统计:收集网关请求的指标数据,...

    Spring面试题

    Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。 IOC 和 AOP 控制反转模式(也称作...

    SpringBoot项目基于Spring Boot智能无人仓库管理.zip

    系统的架构设计注重性能、可用性和可维护性,以支持高并发的数据访问和动态的数据更新。其模块化的设计也便于未来根据物流和仓储技术的发展增加新功能或升级现有功能,确保软件的长期适用性和技术前瞻性。

    如何使用Spring Cloud Gateway构建一个简单的微服务网关(2)

    3.负载均衡:根据负载均衡策略将请求分发到不同的微服务实例,提高系统的吞吐量和可扩展性。 4.安全性和认证:通过集成认证和授权服务,实现对请求的安全验证和访问控制。 5.监控和统计:收集网关请求的指标数据,...

Global site tag (gtag.js) - Google Analytics