Spring【整合DAO与Hibernate】
一。Spring配置数据源
第一步:在根目录下配置jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3307/myhibernate?useUnicode=true&&characterEncoding=UTF8 jdbc.username=root jdbc.password=a617475430
第二步:在applicationContext.xml下配置数据源
<!-- 用来解析一个Property文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <!-- 去解析根目录(classpath)下的一个叫做jdbc.properties的文件 --> <value>classpath:jdbc.properties</value> </property> </bean> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password"></property> </bean>
【结论】:
这样子配置后,我们就可以在页面获取数据源了
public void testDataSource(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource dataSource=(DataSource) context.getBean("dataSource"); System.out.println(dataSource); }
在这里我们又一次加强了面向接口编程的概念,因为我们不仅可以配置dbcp数据源,也可以配置c3p0数据源。他们都实现了Sun公司提供的DataSource接口。
二。Spring整合JDBC
Spring整合JDBC,那么当然使用的是模板,什么是模板,就是动态参数+静态代码。动态参数当然就是连接数据库的一些信息,比如连接什么数据库,用户是什么,sql语句也是动态的。 静态代码是jdbc固定的语法规则,获取connection,创建Statement或者PrepareStatement,什么的。在使用Spring给我们提供的JDBC模板之前,我们先自定JDBC模板
2.1 自定义JDBC模板
第一步:创建核心模板类
仔细体会这里,这里就运用了面向接口编程
public class myJDBCTemplate { private DataSource dataSource; public myJDBCTemplate(){} //setter注入 public myJDBCTemplate(DataSource dataSource){ //构造函数注入 this.dataSource=dataSource; }
public void insert(String sql){ try { //具体的jdbc操作 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //重点 getter and setter... }
第二步:继承自定义模板,开始使用
public class PersonDao extends myJDBCTemplate{ public void savePerson(String sql){ this.insert(sql); } }
第三步:在Spring容器中配置
这里的形式有很多,先看第一种配置形式:
<!-- 上面了配置了数据源 --> <bean id="personDao" class="com.dao.PersonDao"> <!-- 因为我们继承了模板,自然继承了模板方法setter,所以我们才能进行下面的DI --> <property name="dataSource" ref="dataSource"></property> </bean>
第二种配置形式:把我们的自定义模板放入Spring容器中,进行DI。然后配置我们的dao时,添加parent属性即可
<bean id="module" class="com.jdbc.myJDBCTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="personDao" class="com.dao.PersonDao" parent="module"> </bean>
2.2 Spring提供的模板
先看下Springt提供的JDBC模板的类结构
通过类结构图,看出最终执行数据操作的是JdbcTemplate,因为最根本的注入就是注入到了JdbcTemplate。JdbcTemplate本身给我们提供了两种注入方式,构造器和setter方法。这就是Sprint提供的JDBC模板,用来操作数据库的框架,在这里提下,不论是JDBC还是Hibernate,Spring提供的操作数据库的模板都是这样的类结构。
Spring提供的Hibernate模板类结构
2.3 使用Spring提供JDBC模板
第一步:直接继承Spring提供给我们的模板就可以了
public class PersonDao extends JdbcDaoSupport{ public void savePerson(String sql){ this.getJdbcTemplate().execute(sql); } }
第二步:配置Spring容器
<!-- 上面了配置了数据源 --> <bean id="personDao" class="com.dao.PersonDao"> <property name="dataSource" ref="dataSource"></property> </bean>
三。Spring整合Hibernate
通过上面的类结构,我们知道了Spring给我们提供了Hibernate模板,我们所要关心的只是注入sessionFactory的问题,在以前,我们使用的是Hibernate实现的SessionFactory。但这个实现类没有提供任何注入数据源的方式。所以Spring给我们提供了另一个SessionFactory实现类-LocalSessionFactoryBean
第一步:Spring配置文件引入SessionFactory的两种方式
方式一:
<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value> </property> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean>
方式二:
使用这种方式就不需要hibernate.cfg.xml的配置文件了
<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 映射文件所在的路径 --> <property name="mappingDirectoryLocations"> <list> <!-- spring容器会去该包以及其子包下搜索所有的映射文件 --> <value>spring/domain</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean>
第二步:使用HibernateDaoSupport
public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao { @Override public void savePerson(Person person) { // TODO Auto-generated method stub this.getHibernateTemplate().save(person); } }
四。HibernateTemplate深入研究-回调
很明显,HibernateTemplate隐藏了Spring用session做具体动作的行为,我们只需要使用Spring提供给我们的HibernateTemplate模板就可以了。我们只需要给HibernateTemplate提供要操作的持久化对象与HQL语句即可。如果此时你需要Spring容器去执行你写的具体session操作,那我们就需要回调这个概念,Spring哦容器给我们提供下面这个类。
HibernateCallback是Spring为程序员提供的回调接口,其中session是操作所处于的当前session,我们给HibernateTemplate赋值的时候,HibernateTemplate在调用真正的数据操作方法时,给这个真正操作方法传入了一个HibernateCallback。然后由Spring容器的doExecute(HibernateCallback callback..)方法来执行数据操作,现在把HibernateCallback提供给我们,让我们可以指定Spring容器的具体操作。
public interface HibernateCallback { Object doInHibernate(Session session) throws HibernateException, SQLException; }