Spring数据访问策略

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

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

[b]准备数据库环境[/b]

// 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>


[b]主键生成策略[/b]
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);
}



[b]JdbcTemplet[/b]

<!-- 注入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});
}

}



[b]集成Hibernate[/b]
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);
}

}



[b]集成Ibtais[/b]

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


[b]集成JPA[/b]
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);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值