Spring与数据库

Spring与jdbc

引入dataSource

黑马-Spring与数据库-LMLPHP

在客户端

黑马-Spring与数据库-LMLPHP

模板编程

类的结构图, 真正干活的是JdbcTemplate(底层实现,操作 excute方法)

JdbcTemplate   构造函数 有DataSource参数    继承JdbcAccessor抽象类 抽象类有方法setDataSource(DataSource)

黑马-Spring与数据库-LMLPHP

JdbcDaoSupport 抽象类 (不能被实例化 只能用来继承)  有setDataSource ,setDataSource创建了JdbcTemplate对象,DataSource最终赋值给了 JdbcTemplate

                        有setTemplate方法

黑马-Spring与数据库-LMLPHP黑马-Spring与数据库-LMLPHP

JdbcAccessor抽象类 方法setDataSource(DataSource)

黑马-Spring与数据库-LMLPHP

黑马-Spring与数据库-LMLPHP

方案一

继承JdbcDaoSupport  两种选择 1.注入DataSource    2.注入JdbcTemplate

1.注入DataSource(setDataSource),   执行 利用JdbcDaoSupport    getJdbcTemplate  执行JdbcTemplate的excute方法

黑马-Spring与数据库-LMLPHP

黑马-Spring与数据库-LMLPHP

2注入JdbcTemplate(JdbcSupport有setDatasource方法)    建立jdbcTemplate bean,注入DataSource(继承自JdbcAccesor的setDataSource方法)

黑马-Spring与数据库-LMLPHP

黑马-Spring与数据库-LMLPHP

方案二

继承Jdbctemplate  注入(1.JdbcTemplate继承JdbcAccessor 的 setDataSourc  2.利用JdbcTemplate本身构造器)  , 执行利用 JdbcTemplate excute方法

1.

2.

黑马-Spring与数据库-LMLPHP

黑马-Spring与数据库-LMLPHP

方案三

私有属性 JdbcTemplate ,提供set方法   注入,执行 this.jdbTemplate.excute

黑马-Spring与数据库-LMLPHP

spring与jdbc的查询

原Jdbc查询操作

黑马-Spring与数据库-LMLPHP

黑马-Spring与数据库-LMLPHP

<?xml version="1.0" encoding="UTF-8"?>
<beans 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-2.5.xsd">
<!--
按照指定的路径加载配置文件
-->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<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 name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean> <bean id="studentDao1_1" class="com.itheima09.spring.jdbc.dao.StudentDao1">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="studentDao1_2" class="com.itheima09.spring.jdbc.dao.StudentDao1">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
<bean id="studentDao2_1" class="com.itheima09.spring.jdbc.dao.StudentDao2">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="studentDao2_2" class="com.itheima09.spring.jdbc.dao.StudentDao2">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
<bean id="studentDao3" class="com.itheima09.spring.jdbc.dao.StudentDao3">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
</beans>

jdbc-xml

@Test
public void testStuent() throws Exception{
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-jdbc.xml");
StudentDao3 studentDao3=(StudentDao3)context.getBean("studentDao3");
studentDao3.queryStudent();
}

test

Spring的声明式事务处理

概念

程序员不再负责处理事务,事务处理交给spring容器来做。

具体的详解

程序员负责两个内容:

1、  对表的crud操作:目标类的目标方法

2、  告诉spring容器什么样的目标方法采用什么样的事务策略

Spring容器负责:(切面)

负责事务的处理

实现原理

采用了aop技术来实现的。

事务的架构

黑马-Spring与数据库-LMLPHP

PlatFormTransactionManager 顶级接口

AbstractPlatformTransactionManager  抽象接口 实现commit 和rollback方法    getTransaction

DataSourceTransactionManager  继承AbstractPlatformTransactionManager  实现doGetTransaction 方法

黑马-Spring与数据库-LMLPHP

事务的定义

黑马-Spring与数据库-LMLPHP

事务的状态

说明:通过spring的事务处理架构,再通过配置文件具体的实现事务的类,就可以让spring容器知道是什么样的技术来操作数据库,通过对事务状态的判断,通过事务的定义就可以知道具体的目标方法采用什么样的事务策略来处理了。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!--
引入dataSource
把dao层和service层的类导入进来
-->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<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 name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="studentDao" class="com.itheima09.spring.jdbc.transaction.dao.StudentDaoImpl">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="studentService" class="com.itheima09.spring.jdbc.transaction.service.StudentServiceImpl">
<property name="studentDao">
<ref bean="studentDao"/>
</property>
</bean>
<!--
事务管理器
告诉spring容器要采用什么样的技术处理事务
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--
配置声明的事务策略
id 唯一标示
transaction-manager 事务管理器
-->
<tx:advice id="tx" transaction-manager="transactionManager">
<tx:attributes>
<!--
以save开头的方法,采用的传播属性是默认值,隔离机制是默认值,是读写事务
-->
<tx:method
name="save*"
propagation="REQUIRED"
isolation="DEFAULT"
read-only="false"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut
expression="execution(* com.itheima09.spring.jdbc.transaction.service.*.*(..))"
id="perform"/>
<aop:advisor advice-ref="tx" pointcut-ref="perform"/>
</aop:config>
</beans>

applicationContext.xml

Spring与hibernate

组成

1、  hibernate的配置文件

2、  持久化类和映射文件

3、  Dao层和service层所有的类

4、  Spring的配置文件

5、  客户端

Spring的配置文件

黑马-Spring与数据库-LMLPHP

seessionFactory 产生session 进行crud操作      同时,hibernate   需要sessionFactory   通过session  开启事务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 引入dataSource 把dao层和service层的类导入进来 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<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 name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> <bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<!-- 导入映射文件所在的路径 -->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:com/itheima09/spring/hibernate/transaction/domain
</value>
</list>
</property>
<!-- 其他配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<bean id="personDao"
class="com.itheima09.spring.hibernate.transaction.dao.PersonDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="personService"
class="com.itheima09.spring.hibernate.transaction.service.PersonServiceImpl">
<property name="personDao">
<ref bean="personDao" />
</property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<tx:advice id="tx" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*"
isolation="DEFAULT"
propagation="REQUIRED"
read-only="false"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut
expression="execution(* com.itheima09.spring.hibernate.transaction.service.*.*(..))"
id="perform" />
<aop:advisor advice-ref="tx" pointcut-ref="perform" />
</aop:config>
</beans>

applicationContext.xml

关于session

从上图可以看出,程序员使用sessionFactory产生session,从而进行crud的操作

Spring容器利用sessionFactory产生session,进行事务的操作,所以spring容器产生

的session和程序员用的session肯定是同一个session,所以在spring声明式事务处理的

时候,session必须由当前线程产生

hibernate 回调函数

package com.heima.spring.hibernate.callback;

import org.hibernate.Session;

public interface HibernateCallback {
public Object doInHibernate(Session session);
}

HibernateCallback

package com.heima.spring.hibernate.callback;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction; public class SpringHibernateCore {
private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Object doExecute(HibernateCallback action){
Object obj=null;
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
obj=action.doInHibernate(session);
transaction.commit();
return obj;
} public List find(final String hql){
return (List)this.doExecute(new
HibernateCallback() {
public Object doInHibernate(Session session)
{
return session.createQuery(hql).list();
}
});
} }

SpringHibernateCore

package com.heima.spring.hibernate.callback;

import java.util.List;

import com.heima.spring.hibernate.transaction.domain.Person;

public class PersonDaoCallback extends SpringHibernateCore{
public void querPerson(){
List<Person> pList=this.find("from Person");
System.out.println(pList.size());
}
}

PersonDaoCallback

04-20 12:22