您的位置:首页 > 编程语言 > Java开发

Spring笔记整理——持久层的支持(jdbc,hibernate)

2013-04-18 13:21 543 查看
Spring强大的基于 JavaBeans 的采用控制反转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组件更加快捷简易。

是一个可用于从 applet 到 Java EE 等不同运行环境的核心 Bean 工厂。

使数据库事务的一般化抽象层,允许宣告式(Declarative)事务管理器,简化事务的划分使之与底层无关。

为JDBC 抽象层提供了有针对性的异常等级(不再从SQL异常中提取原始代码), 简化了错误处理, 大大减少了程序员的编码量。 再次利用JDBC时,你无需再写出另一个 '终止' (finally) 模块. 并且面向JDBC的异常与Spring 通用数据访问对象(Data
Access Object) 异常等级相一致.以资源容器,DAO 实现和事务策略等形式与 Hibernate,JDO 和 iBATIS SQL Maps 集成。利用众多的反转控制方便特性来全面支持, 解决了许多典型的Hibernate集成问题. 所有这些全部遵从Spring通用事务处理和通用数据访问对象异常等级规范。

下面是整理Spring对jdbc和Hibernate的支持。

Spring对于JDBC的支持

Spring对于JDBC的支持提供一个对象 org.springframework.jdbc.core.JdbcTemplate

主要方法:

update(String sql, Object[] args) update方法处理SQL的insert,update,delete语句

query(String sql, Object[] args, RowMapper<T> rowMapper) [查询多个对象]

queryForObject(String sql, Object[] args, RowMapper<T> rowMapper) [查询单个对象]

下面来看一个例子

beans.xml里面的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- 定义Dao层 -->
<bean id="userDao" class="com.spring.jdbc.dao.impl.UserDaoImpl">
<!-- 需要注入jdbcTemplate -->
<property name="template" ref="jdbcTemplate"></property>
</bean>

<!-- 通过Spring容器创建JdbcTemplate的实例 -->
<bean id='jdbcTemplate'
class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 为JdbcTemplate注入数据源DataSource,定义url,username ,password -->
<property name="dataSource" ref="ds"></property>
</bean>

<!-- 通过Spring容器创建DataSource :以dbcp方式创建数据源-->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="oracle.jdbc.OracleDriver">
</property>
<property name="url"
value="jdbc:oracle:thin:@localhost:1521:XE">
</property>
<property name="username" value="hr"></property>
<property name="password" value="111"></property>
</bean>
</beans>


下面是 org.springframework.jdbc.core.JdbcTemplate对象主要方法调用

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import com.spring.dao.UserDao;
import com.spring.pojo.User;

public class UserDaoImpl implements UserDao {
private JdbcTemplate template;// Impl层需要操作数据库,依赖JdbcTemplate的支持

@Override
public void delete(User u) {
String sql = "delete from t_user where t_id=?";
Object[] args = { u.getId() };
template.update(sql, args);// 通过template的update方法执行sql语句

}

@Override
public void insert(User u) {
String sql = "insert into t_user(t_id,t_name,t_age,t_birthday) values(user_seq.nextval,?,?,?)";
Object[] args = { u.getName(), u.getAge(), u.getBirthday() };
template.update(sql, args);
}

@Override
public void update(User u) {
String sql = "update t_user set t_name=?,t_age=?,t_birthday=? where t_id=?";

Object[] args = { u.getName(), u.getAge(), u.getBirthday(), u.getId() };

template.update(sql, args);

}

@SuppressWarnings("unchecked")
@Override
public List<User> findAll() {
String sql = "select t_id,t_name,t_age,t_birthday from t_user";
// 匿名内部内 new 接口(){} 实际开发中如果一个接口需要实现的方法少于三个
List<User> users = template.query(sql, new RowMapper() {
// ResultSet不是将整个结果集进行封装,是每一次封装一行数据
public Object mapRow(ResultSet rs, int rownum) throws SQLException {
User u = new User();
u.setAge(rs.getInt("t_age"));
u.setName(rs.getString("t_name"));
u.setBirthday(rs.getDate("t_birthday"));
u.setId(rs.getInt("t_id"));
return u;
}
});
return users;
}

@SuppressWarnings("unchecked")
@Override
public User findById(Integer id) {
String sql = "select t_id,t_name,t_age,t_birthday from t_user where t_id=?";
Object[] args = { id };
User user = (User) template.queryForObject(sql, args, new RowMapper() {
@Override
public Object mapRow(ResultSet rs, int rownum) throws SQLException {
User u = new User();
u.setAge(rs.getInt("t_age"));
u.setName(rs.getString("t_name"));
u.setBirthday(rs.getDate("t_birthday"));
u.setId(rs.getInt("t_id"));
return u;
}
});
return user;
}

public JdbcTemplate getTemplate() {
return template;
}

public void setTemplate(JdbcTemplate template) {
this.template = template;
}
}


Spring对于Hibernate的支持

提供了HbiernateTemplate,HibernateTemplate提供了很多和session同名的方法

1.HibernateTemplate是线程安全的

2.HibernateTemplate方便执行HQL

3.HibernateTemplate内部控制事务

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

<!-- 使用c3p0创建数据源,效率比dbcp更好 -->
<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置数据库连接的相关数据 -->
<property name="driverClass" value="oracle.jdbc.OracleDriver"></property>
<property name="jdbcUrl"
value="jdbc:oracle:thin:@localhost:1521:XE">
</property>
<property name="user" value="hr"></property>
<property name="password" value="111"></property>
<!-- 配置与连接池相关的数据 -->
<!-- 配置数据库连接池的最大连接数 -->
<property name="maxPoolSize" value="10"></property>
<!-- 指定数据库连接的最小连接数 -->
<property name="minPoolSize" value="1"></property>
<!-- 指定初始化连接池时创建的连接数 -->
<property name="initialPoolSize" value="1"></property>
<!-- 指定数据库连接池连接的最大空闲时间 -->
<property name="maxIdleTime" value="20"></property>
</bean>
<!-- HibernateTemplate封装了Session,Session对象由SessionFacotry提供,先定义SessionFacotry实例 -->
<bean id="sf"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 获得数据库的连接信息,有DataSource提供 -->
<property name="dataSource" ref="ds"></property>
<!-- 设定Hibernate自身相关的属性,类型为Properties-->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9iDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<!-- 对于线程安全的session可以省略 currect_session_context_class -->
</props>
</property>
<!-- 映射文件的注册 -->
<property name="mappingResources">
<list>
<value>com/spring/pojo/User.hbm.xml</value>
</list>
</property>
</bean>
<!-- Spring容器创建HibernateTemplate实例 -->
<bean id="template"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sf"></property>
</bean>

<bean id="ormDao" class="com.spring.orm.dao.impl.UserDaoImpl">
<property name="template" ref="template"></property>
</bean>

</beans>


对于Hibernate配置加载也可以直接引用一个已经存在的hibernate.cfg.xml配置

下面是部分代码

<bean id="sf"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 装载hibernate的配置文件 hibernate.cfg.xml -->
<property name="configLocation" value="hibernate.cfg.xml"></property>
</bean>

<!-- Spring容器创建HibernateTemplate实例 -->
<bean id="template"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sf"></property>
</bean>

<bean id="ormDao" class="com.spring.orm.dao.impl.UserDaoImpl">
<property name="template" ref="template"></property>
</bean>


org.springframework.orm.hibernate3.HibernateTemplate的常用方法地调用

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.spring.dao.UserDao;
import com.spring.pojo.User;

/*对于Hibernate的支持*/
public class UserDaoImpl implements UserDao {
private HibernateTemplate template;

@Override
public void delete(User u) {
template.delete(u);// 删除用户

}

@Override
public void insert(User u) {
template.save(u);
}

@Override
public void update(User u) {
template.update(u);
}

@Override
public List<User> findAll() {

return template.find("from User");
}

@Override
public User findByName(final String name) {
/*
* String hql = "from User as u where u.name=?"; Object[] args = { name };
* List<User> users = template.find(hql, args); User u = null; if
* (users != null) { u = users.get(0); }
*/
User u = (User) template.execute(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query = session
.createQuery("from User as u where u.name=?");
query.setString(0, name);

return query.uniqueResult();
}
});
return u;
}

@Override
public User findById(Integer id) {

return template.get(User.class, id);// get方法必须是依赖于主键
}

public HibernateTemplate getTemplate() {
return template;
}

public void setTemplate(HibernateTemplate template) {
this.template = template;
}

@Override
// 分页查询
public List<User> findByPage(final int first, final int size) {
List<User> users = (List<User>) template
.execute(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query = session.createQuery("from User");
query.setFirstResult(first);
query.setMaxResults(size);
return query.list();
}
});
return users;
}

}


Spring的分层架构,对一些优秀框架提供了很好的支持,对于jdbc、hibernate的集成,不仅简化了代码量,使程序结构更加清晰,也降低了程序之间的耦合度加强了子程序的独立性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Spring Hibernate JDBC HQL