1.1 JdbcTemplate概述 :
它是spring框架中提供的一個(gè)對(duì)象,是對(duì)原始JdbcAPI對(duì)象的簡(jiǎn)單封裝.spring框架為我們提供了很多的操作模板類(lèi).
ORM持久化技術(shù) 模板類(lèi)
JDBC org.springframework.jdbc.core.JdbcTemplate.
Hibernate3.0 org.springframework.orm.hibernate3.HibernateTemplate.
IBatis(MyBatis) org.springframework.orm.ibatis.SqlMapClientTemplate.
JPA org.springframework.orm.jpa.JpaTemplate.
在導(dǎo)包的時(shí)候需要導(dǎo)入spring-jdbc-4.24.RELEASF.jar,還需要導(dǎo)入一個(gè)spring-tx-4.2.4.RELEASE.jar(它和事務(wù)有關(guān))
<!-- 配置數(shù)據(jù)源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:// /spring_day04"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
1.3.3.3配置spring內(nèi)置數(shù)據(jù)源
spring框架也提供了一個(gè)內(nèi)置數(shù)據(jù)源谐宙,我們也可以使用spring的內(nèi)置數(shù)據(jù)源奈揍,它就在spring-jdbc-4.2.4.REEASE.jar包中:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_day04"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
1.3.4將數(shù)據(jù)庫(kù)連接的信息配置到屬性文件中:
【定義屬性文件】
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_day02
jdbc.username=root
jdbc.password=123
【引入外部的屬性文件】
一種方式:
<!-- 引入外部屬性文件: -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
二種方式:
<context:property-placeholder location="classpath:jdbc.properties"/>
1.4JdbcTemplate的增刪改查操作
1.4.1前期準(zhǔn)備
創(chuàng)建數(shù)據(jù)庫(kù):
create database spring_day04;
use spring_day04;
創(chuàng)建表:
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
1.4.2在spring配置文件中配置JdbcTemplate
<?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.xsd">
<!-- 配置一個(gè)數(shù)據(jù)庫(kù)的操作模板:JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置數(shù)據(jù)源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_day04"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
</beans>
1.4.3最基本使用
public class JdbcTemplateDemo2 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
jt.execute("insert into account(name,money)values('eee',500)");
}
}
1.4.4保存操作
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
//保存
jt.update("insert into account(name,money)values(?,?)","fff",5000);
}
}
1.4.5更新操作
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
//修改
jt.update("update account set money = money-? where id = ?",300,6);
}
}
1.4.6刪除操作
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
//刪除
jt.update("delete from account where id = ?",6);
}
}
1.4.7查詢(xún)所有操作
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
//查詢(xún)所有
List<Account> accounts = jt.query("select * from account where money > ? ",
new AccountRowMapper(), 500);
for(Account o : accounts){
System.out.println(o);
}
}
}
public class AccountRowMapper implements RowMapper<Account>{
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account = new Account();
account.setId(rs.getInt("id"));
account.setName(rs.getString("name"));
account.setMoney(rs.getFloat("money"));
return account;
}
}
1.4.8查詢(xún)一個(gè)操作
使用RowMapper的方式:常用的方式
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
//查詢(xún)一個(gè)
List<Account> as = jt.query("select * from account where id = ? ",
new AccountRowMapper(), 55);
System.out.println(as.isEmpty()?"沒(méi)有結(jié)果":as.get(0));
}
}
1.4.9查詢(xún)返回一行一列操作
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
//1.獲取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據(jù)id獲取bean對(duì)象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
//3.執(zhí)行操作
//查詢(xún)返回一行一列:使用聚合函數(shù)领猾,在不使用group by字句時(shí),都是返回一行一列澡刹。最長(zhǎng)用的就是分頁(yè)中獲取總記錄條數(shù)
Integer total = jt.queryForObject("select count(*) from account where money > ? ",Integer.class,500);
System.out.println(total);
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 使用Spring管理連接池對(duì)象,Spring內(nèi)置的連接池對(duì)象 -->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_04"/>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean> -->
<!-- 配置數(shù)據(jù)源,使用Spring整合dbcp連接,沒(méi)有導(dǎo)入jar包 -->
<!-- <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_04"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 使用Spring整合c3p0的連接池,沒(méi)有采用屬性文件的方式 -->
<!--
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean> -->
<!-- 使用context:property-placeholder標(biāo)簽,讀取屬性文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 使用Spring整合c3p0的連接池,采用屬性文件的方式 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- spring管理JbdcTemplate模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
db.properties : 屬性文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_day04
jdbc.user=root
jdbc.password=root
Demo測(cè)試 :
package com.ithiema.demo1;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Spring整合JdbcTemplate的方式入門(mén)
* @author Administrator
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo11 {
@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;
/**
* 添加
*/
@Test
public void run1(){
jdbcTemplate.update("insert into account values (null,?,?)", "嘿嘿",10000);
}
/**
* 修改
*/
@Test
public void run2(){
jdbcTemplate.update("update account set name = ?,money = ? where id = ?", "嘻嘻",5000,6);
}
/**
* 刪除
*/
@Test
public void run3(){
jdbcTemplate.update("delete from account where id = ?", 6);
}
/**
* 查詢(xún)多條數(shù)據(jù)
*/
@Test
public void run4(){
// sql sql語(yǔ)句
// rowMapper 提供封裝數(shù)據(jù)的接口,自己提供實(shí)現(xiàn)類(lèi)(自己封裝數(shù)據(jù)的)
List<Account> list = jdbcTemplate.query("select * from account", new BeanMapper());
for (Account account : list) {
System.out.println(account);
}
}
}
/**
* 自己封裝的實(shí)現(xiàn)類(lèi)然想,封裝數(shù)據(jù)的
* @author Administrator
*/
class BeanMapper implements RowMapper<Account>{
/**
* 一行一行封裝數(shù)據(jù)的
*/
public Account mapRow(ResultSet rs, int index) throws SQLException {
// 創(chuàng)建Account對(duì)象哟沫,一個(gè)屬性一個(gè)屬性賦值,返回對(duì)象
Account ac = new Account();
ac.setId(rs.getInt("id"));
ac.setName(rs.getString("name"));
ac.setMoney(rs.getDouble("money"));
return ac;
}
}
2,1 Spring 事務(wù)控制我們要明確的
1: JavaEE體系進(jìn)行分層開(kāi)發(fā),事務(wù)處理位于業(yè)務(wù)層,Spring提供了分層設(shè)計(jì)業(yè)務(wù)層的事務(wù)處理解決方案.
2: Spring框架為我們提供就一組事務(wù)控制的接口.這組接口是在spring-tx-4.2.4RELEASE.jar中.
3: spring的事務(wù)都是基于AOP的,它既可以使用編程的方式實(shí)現(xiàn),也可以使用配置的方式實(shí)現(xiàn)
2.2Spring中事務(wù)控制的API介紹
2.2.1PlatformTransactionManager
此接口是spring的事務(wù)管理器巍耗,它里面提供了我們常用的操作事務(wù)的方法秋麸,如下圖:
我們?cè)陂_(kāi)發(fā)中都是使用它的實(shí)現(xiàn)類(lèi),如下圖:
真正管理事務(wù)的對(duì)象
org.springframework.jdbc.datasource.DataSourceTransactionManager 使用Spring JDBC或iBatis 進(jìn)行持久化數(shù)據(jù)時(shí)使用
org.springframework.orm.hibernate3.HibernateTransactionManager 使用Hibernate版本進(jìn)行持久化數(shù)據(jù)時(shí)使用
2.2.2TransactionDefinition
它是事務(wù)的定義信息對(duì)象炬太,里面有如下方法:
2.2.2.1事務(wù)的隔離級(jí)別
2.2.2.2事務(wù)的傳播行為
REQUIRED:如果當(dāng)前沒(méi)有事務(wù)灸蟆,就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中亲族,加入到這個(gè)事務(wù)中炒考。一般的選擇(默認(rèn)值)
SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù)霎迫,就以非事務(wù)方式執(zhí)行(沒(méi)有事務(wù))
MANDATORY:使用當(dāng)前的事務(wù)斋枢,如果當(dāng)前沒(méi)有事務(wù),就拋出異常
REQUERS_NEW:新建事務(wù)知给,如果當(dāng)前在事務(wù)中瓤帚,把當(dāng)前事務(wù)掛起。
NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作涩赢,如果當(dāng)前存在事務(wù)戈次,就把當(dāng)前事務(wù)掛起
NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù)筒扒,拋出異常
NESTED:如果當(dāng)前存在事務(wù)怯邪,則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒(méi)有事務(wù)花墩,則執(zhí)行REQUIRED類(lèi)似的操作悬秉。
2.2.2.3超時(shí)時(shí)間
默認(rèn)值是-1,沒(méi)有超時(shí)限制观游。如果有搂捧,以秒為單位進(jìn)行設(shè)置驮俗。
2.2.2.4是否是只讀事務(wù)
建議查詢(xún)時(shí)設(shè)置為只讀懂缕。
2.2.3TransactionStatus
此接口提供的是事務(wù)具體的運(yùn)行狀態(tài),方法介紹如下圖:
2.3基于XML的聲明式事務(wù)控制(配置方式)重點(diǎn)
2.3.1環(huán)境搭建
2.3.1.1第一步:拷貝必要的jar包到工程的lib目錄
2.3.1.2第二步:創(chuàng)建spring的配置文件并導(dǎo)入約束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
2.3.1.3第三步:準(zhǔn)備數(shù)據(jù)庫(kù)表和實(shí)體類(lèi)
創(chuàng)建數(shù)據(jù)庫(kù):
create database spring_day04;
use spring_day04;
創(chuàng)建表:
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
/**
* 賬戶(hù)的實(shí)體
*/
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getMoney() {
return money;
}
public void setMoney(Float money) {
this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
}
}
2.3.1.4第四步:編寫(xiě)業(yè)務(wù)層接口和實(shí)現(xiàn)類(lèi)
/**
* 賬戶(hù)的業(yè)務(wù)層接口
*/
public interface IAccountService {
/**
* 根據(jù)id查詢(xún)賬戶(hù)信息
* @param id
* @return
*/
Account findAccountById(Integer id);//查
/**
* 轉(zhuǎn)賬
* @param sourceName 轉(zhuǎn)出賬戶(hù)名稱(chēng)
* @param targeName 轉(zhuǎn)入賬戶(hù)名稱(chēng)
* @param money 轉(zhuǎn)賬金額
*/
void transfer(String sourceName,String targeName,Float money);//增刪改
}
/**
* 賬戶(hù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)
*/
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個(gè)賬戶(hù)的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
//3.更新兩個(gè)賬戶(hù)
accountDao.updateAccount(source);
int i=1/0;
accountDao.updateAccount(target);
}
}
2.3.1.5第五步:編寫(xiě)Dao接口和實(shí)現(xiàn)類(lèi)
/**
* 賬戶(hù)的持久層接口
*/
public interface IAccountDao {
/**
* 根據(jù)id查詢(xún)賬戶(hù)信息
* @param id
* @return
*/
Account findAccountById(Integer id);
/**
* 根據(jù)名稱(chēng)查詢(xún)賬戶(hù)信息
* @return
*/
Account findAccountByName(String name);
/**
* 更新賬戶(hù)信息
* @param account
*/
void updateAccount(Account account);
}
/**
* 賬戶(hù)的持久層實(shí)現(xiàn)類(lèi)
* 此版本dao王凑,只需要給它的父類(lèi)注入一個(gè)數(shù)據(jù)源
*/
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public Account findAccountById(Integer id) {
List<Account> list = getJdbcTemplate().query("select * from account where id = ? ",new AccountRowMapper(),id);
return list.isEmpty()?null:list.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> list = getJdbcTemplate().query("select * from account where name = ? ",new AccountRowMapper(),name);
if(list.isEmpty()){
return null;
}
if(list.size()>1){
throw new RuntimeException("結(jié)果集不唯一搪柑,不是只有一個(gè)賬戶(hù)對(duì)象");
}
return list.get(0);
}
@Override
public void updateAccount(Account account) {
getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
/**
* 賬戶(hù)的封裝類(lèi)RowMapper的實(shí)現(xiàn)類(lèi)
*/
public class AccountRowMapper implements RowMapper<Account>{
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account = new Account();
account.setId(rs.getInt("id"));
account.setName(rs.getString("name"));
account.setMoney(rs.getFloat("money"));
return account;
}
}
2.3.1.6第六步:在配置文件中配置業(yè)務(wù)層和持久層對(duì)
<!-- 配置service -->
<bean id="accountService" class="com.baidu.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<!-- 配置dao -->
<bean id="accountDao" class="com.baidu.dao.impl.AccountDaoImpl">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置數(shù)據(jù)源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_day04"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
2.3.2配置步驟
2.3.2.1第一步:配置事務(wù)管理器
<!-- 配置一個(gè)事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
2.3.2.2第二步:配置事務(wù)的通知引用事務(wù)管理器
<!-- 事務(wù)的配置 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
</tx:advice>
2.3.2.3第三步:配置事務(wù)的屬性
<!--在tx:advice標(biāo)簽內(nèi)部 配置事務(wù)的屬性 -->
<tx:attributes>
<!-- 指定方法名稱(chēng):是業(yè)務(wù)核心方法
read-only:是否是只讀事務(wù)聋丝。默認(rèn)false,不只讀工碾。
isolation:指定事務(wù)的隔離級(jí)別弱睦。默認(rèn)值是使用數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。
propagation:指定事務(wù)的傳播行為渊额。
timeout:指定超時(shí)時(shí)間况木。默認(rèn)值為:-1。永不超時(shí)旬迹。
rollback-for:用于指定一個(gè)異常火惊,當(dāng)執(zhí)行產(chǎn)生該異常時(shí),事務(wù)回滾奔垦。產(chǎn)生其他異常屹耐,事務(wù)不回滾。沒(méi)有默認(rèn)值椿猎,任何異常都回滾惶岭。
no-rollback-for:用于指定一個(gè)異常,當(dāng)產(chǎn)生該異常時(shí)犯眠,事務(wù)不回滾按灶,產(chǎn)生其他異常時(shí),事務(wù)回滾阔逼。沒(méi)有默認(rèn)值兆衅,任何異常都回滾。
-->
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
2.3.2.4第四步:配置AOP-切入點(diǎn)表達(dá)式
<!-- 配置aop -->
<aop:config>
<!-- 配置切入點(diǎn)表達(dá)式 -->
<aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/>
</aop:config>
2.3.2.5第五步:配置切入點(diǎn)表達(dá)式和事務(wù)通知的對(duì)應(yīng)關(guān)系
<!-- 在aop:config標(biāo)簽內(nèi)部:建立事務(wù)的通知和切入點(diǎn)表達(dá)式的關(guān)系 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
2.4基于XML和注解組合使用的整合方式
2.4.1環(huán)境搭建
2.4.1.1第一步:拷貝必備的jar包到工程的lib目錄
2.4.1.2第二步:創(chuàng)建spring的配置文件導(dǎo)入約束并配置掃描的包
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置spring要掃描的包 -->
<context:component-scan base-package="com.baidu"></context:component-scan>
</beans>
2.4.1.3第三步:創(chuàng)建數(shù)據(jù)庫(kù)表和實(shí)體類(lèi)
和基于xml的配置相同嗜浮。
2.4.1.4第四步:創(chuàng)建業(yè)務(wù)層接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
業(yè)務(wù)層接口和基于xml配置的時(shí)候相同羡亩。略
/**
* 賬戶(hù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)
*/
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個(gè)賬戶(hù)的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
//3.更新兩個(gè)賬戶(hù)
accountDao.updateAccount(source);
int i=1/0;
accountDao.updateAccount(target);
}
}
2.4.1.5第五步:創(chuàng)建Dao接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
Dao層接口和AccountRowMapper與基于xml配置的時(shí)候相同。略
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Account findAccountById(Integer id) {
List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
return list.isEmpty()?null:list.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> list = jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);
if(list.isEmpty()){
return null;
}
if(list.size()>1){
throw new RuntimeException("結(jié)果集不唯一危融,不是只有一個(gè)賬戶(hù)對(duì)象");
}
return list.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
2.4.2配置步驟
2.4.2.1第一步:配置數(shù)據(jù)源和JdbcTemplate
<!-- 配置數(shù)據(jù)源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_day04"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
2.4.2.2第二步:配置事務(wù)管理器并注入數(shù)據(jù)源
<!-- 配置JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
2.4.2.3第三步:在業(yè)務(wù)層使用@Transactional注解
@Service("accountService")
@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個(gè)賬戶(hù)的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
//3.更新兩個(gè)賬戶(hù)
accountDao.updateAccount(source);
//int i=1/0;
accountDao.updateAccount(target);
}
}
該注解的屬性和xml中的屬性含義一致畏铆。該注解可以出現(xiàn)在接口上,類(lèi)上和方法上吉殃。
出現(xiàn)接口上辞居,表示該接口的所有實(shí)現(xiàn)類(lèi)都有事務(wù)支持。
出現(xiàn)在類(lèi)上蛋勺,表示類(lèi)中所有方法有事務(wù)支持
出現(xiàn)在方法上瓦灶,表示方法有事務(wù)支持。
以上三個(gè)位置的優(yōu)先級(jí):方法>類(lèi)>接口
2.4.2.4第四步:在配置文件中開(kāi)啟spring對(duì)注解事務(wù)的支持
<!-- 開(kāi)啟spring對(duì)注解事務(wù)的支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
2.5基于純注解的聲明式事務(wù)控制(配置方式)重點(diǎn)
2.5.1環(huán)境搭建
2.5.1.1第一步:拷貝必備的jar包到工程的lib目錄
2.5.1.2第二步:創(chuàng)建一個(gè)類(lèi)用于加載spring的配置并指定要掃描的包
/**
* 用于初始化spring容器的配置類(lèi)
*/
@Configuration
@ComponentScan(basePackages="com.baidu")
public class SpringConfiguration {
}
2.5.1.3第三步:創(chuàng)建數(shù)據(jù)庫(kù)表和實(shí)體類(lèi)
和基于xml的配置相同抱完。略
2.5.1.4第四步:創(chuàng)建業(yè)務(wù)層接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
業(yè)務(wù)層接口和基于xml配置的時(shí)候相同贼陶。略
/**
* 賬戶(hù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)
*/
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個(gè)賬戶(hù)的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
//3.更新兩個(gè)賬戶(hù)
accountDao.updateAccount(source);
int i=1/0;
accountDao.updateAccount(target);
}
}
2.5.1.5第五步:創(chuàng)建Dao接口和實(shí)現(xiàn)類(lèi)并使用注解讓spring管理
Dao層接口和AccountRowMapper與基于xml配置的時(shí)候相同。略
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Account findAccountById(Integer id) {
List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
return list.isEmpty()?null:list.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> list = jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);
if(list.isEmpty()){
return null;
}
if(list.size()>1){
throw new RuntimeException("結(jié)果集不唯一,不是只有一個(gè)賬戶(hù)對(duì)象");
}
return list.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
2.5.2配置步驟
2.5.2.1第一步:使用@Bean注解配置數(shù)據(jù)源
@Bean(name = "dataSource")
public DataSource createDS() throws Exception {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUsername("root");
dataSource.setPassword("123");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring3_day04");
return dataSource;
}
2.5.2.2第二步:使用@Bean注解配置配置事務(wù)管理器
@Bean
public PlatformTransactionManager
createTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
2.5.2.3第三步:使用@Bean注解配置JdbcTemplate
@Bean
public JdbcTemplate createTemplate(@Qualifier("dataSource") DataSource dataSource)
{
return new JdbcTemplate(dataSource);
}
2.5.2.4第四步:在需要控制事務(wù)的業(yè)務(wù)層實(shí)現(xiàn)類(lèi)上使用@Transactional注解
@Service("accountService")
@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱(chēng)查詢(xún)兩個(gè)賬戶(hù)
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個(gè)賬戶(hù)的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶(hù)減錢(qián)
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶(hù)加錢(qián)
//3.更新兩個(gè)賬戶(hù)
accountDao.updateAccount(source);
//int i=1/0;
accountDao.updateAccount(target);
}
}
該注解的屬性和xml中的屬性含義一致碉怔。該注解可以出現(xiàn)在接口上烘贴,類(lèi)上和方法上。
出現(xiàn)接口上撮胧,表示該接口的所有實(shí)現(xiàn)類(lèi)都有事務(wù)支持桨踪。
出現(xiàn)在類(lèi)上,表示類(lèi)中所有方法有事務(wù)支持
出現(xiàn)在方法上芹啥,表示方法有事務(wù)支持锻离。
以上三個(gè)位置的優(yōu)先級(jí):方法>類(lèi)>接口。
2.5.2.5第五步:使用@EnableTransactionManagement開(kāi)啟spring對(duì)注解事務(wù)的的支持
@Configuration
@EnableTransactionManagement
public class SpringTxConfiguration {
//里面配置數(shù)據(jù)源墓怀,配置JdbcTemplate,配置事務(wù)管理器纳账。在之前的步驟已經(jīng)寫(xiě)過(guò)了。
}
在Spring中開(kāi)啟事務(wù)的案例
applicationContext3.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 使用Spring整合c3p0的連接池,沒(méi)有采用屬性文件的方式 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource ">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置平臺(tái)事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置通知: 是Spring框架提供通知,不是咋們自己編寫(xiě)的 -->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 給具體的業(yè)務(wù)層的方法進(jìn)行隔離級(jí)別,傳播行為的具體的配置 -->
<tx:method name="pay" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="save*" isolation="DEFAULT"></tx:method>
<tx:method name="find*" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 配置AOP的增強(qiáng) -->
<aop:config>
<!-- Spring框架制作的通知,必須要使用該標(biāo)簽,如果是自定義的切面,使用aop:aspect標(biāo)簽 -->
<aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.baidu.*.*ServiceImpl.*(..))"></aop:advisor>
</aop:config>
<!-- 可以注入連接池 -->
<bean id="accountDao" class="com.baidu.demo3.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 管理service -->
<bean id="accountService" class="com.baidu.demo3.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
</beans>
在dao層對(duì)代碼進(jìn)行了優(yōu)化,優(yōu)化了JdbcTemplate
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
/*
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}*/
//減錢(qián)
@Override
public void outMoney(String out, double money) {
//jdbcTemplate.update("update username set money = money - ? where name = ?",money,out);
this.getJdbcTemplate().update("update username set money = money - ? where name=?",money,out);
}
//加錢(qián)
@Override
public void inMoney(String in, double money) {
//jdbcTemplate.update("update username set money = money + ? where name = ?",money,in);
this.getJdbcTemplate().update("update username set money = money + ? where name=?",money,in);
}
}
Xml和注解一起進(jìn)行Spring的事務(wù)管理
applicationContext4.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 開(kāi)啟注解的掃描 -->
<context:component-scan base-package="com.baidu"/>
<!-- 使用Spring整合c3p0的連接池,沒(méi)有采用屬性文件的方式 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置JdbcTemplate模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置平臺(tái)事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 開(kāi)啟事務(wù)注解 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
Service層用注解 :
//實(shí)現(xiàn)類(lèi)
@Service("accountService")
@Transactional(isolation=Isolation.DEFAULT)
public class AccountServiceImpl implements AccountService {
@Resource(name="accountDao")
private AccountDao accountDao;
// public void setAccountDao(AccountDao accountDao) {
// this.accountDao = accountDao;
// }
//支付的方法
@Override
public void pay(String out, String in, double money) {
//模擬兩個(gè)操作
//減錢(qián)
accountDao.outMoney(out, money);
//模擬異常
//int i = 10/0;
accountDao.inMoney(in, money);
}
}
使用純注解的方式進(jìn)行Spring事務(wù)管理 :
/*
* 配置類(lèi),Spring聲明式事務(wù)管理,純注解的方式
*
*/
@Configuration
@ComponentScan(basePackages="com.baidu.demo5")
@EnableTransactionManagement //純注解的方式,開(kāi)啟事務(wù)注解
public class SpringConfig {
@Bean(name="dataSource")
public DataSource createDataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///spring_04");
dataSource.setUser("root");
dataSource.setPassword("root");
return dataSource;
}
//把dataSource注入進(jìn)來(lái)
@Bean(name="jdbcTemplate")
@Resource(name="dataSource")
public JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
//創(chuàng)建平臺(tái)事務(wù)管理器對(duì)象
@Bean(name="transactionManager")
@Resource(name="dataSource")
public PlatformTransactionManager createTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
1 : 傳播行為 : 解決業(yè)務(wù)層方法之間互相調(diào)用的問(wèn)題.
傳播行為的默認(rèn)值 : 保證save和update方法在同一個(gè)事務(wù)中.
2 : Spring事務(wù)管理 : (1) : XML配置文件 ; (2) : XML+注解配置文件 ; (3) : 純注解
Spring框架提供了接口和實(shí)現(xiàn)類(lèi),進(jìn)行事務(wù)管理的.
PlatformTransactionManager接口 : 平臺(tái)事務(wù)管理器,提供和回滾事務(wù)的.
HibernateTransactionManager : hibernate框架事務(wù)管理的實(shí)現(xiàn)類(lèi).
DataSourceTransactionManager : 使用JDBC或者M(jìn)yBattis框架
TransactionDefinition接口 : 事務(wù)的定義的信息.提供很多常量,分別表示隔離級(jí)別,傳播行為.
傳播行為 : 事務(wù)的傳播行為,解決service方法之間的調(diào)用的問(wèn)題.
Spring聲明式事務(wù)管理,使用AOP技術(shù)進(jìn)行事務(wù)管理.
通知/增強(qiáng) : 事務(wù)管理的方法,不用咋們自己編寫(xiě).需要配置.
連接池 DataSource ,存在Connection ,使用JDBC進(jìn)行事務(wù)管理 ,conn.commit()
|
|注入
平臺(tái)事務(wù)管理器(必須配置的),是Spring提供接口,提交和回滾事務(wù)
|
|注入
自己編寫(xiě)通知方法(事務(wù)管理),Spring提供通知,配置通知
|
|注入
配置AOP增強(qiáng) aop:config
SSH框架之Spring第四篇
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門(mén)惕蹄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚯涮,“玉大人,你說(shuō)我怎么就攤上這事卖陵≡舛ィ” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵泪蔫,是天一觀的道長(zhǎng)棒旗。 經(jīng)常有香客問(wèn)我,道長(zhǎng)撩荣,這世上最難降的妖魔是什么铣揉? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮餐曹,結(jié)果婚禮上逛拱,老公的妹妹穿的比我還像新娘。我一直安慰自己台猴,他們只是感情好朽合,可當(dāng)我...
- 文/花漫 我一把揭開(kāi)白布额湘。 她就那樣靜靜地躺著,像睡著了一般旁舰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗡官,一...
- 那天箭窜,我揣著相機(jī)與錄音,去河邊找鬼衍腥。 笑死磺樱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的婆咸。 我是一名探鬼主播竹捉,決...
- 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尚骄!你這毒婦竟也來(lái)了块差?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤倔丈,失蹤者是張志新(化名)和其女友劉穎憨闰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體需五,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹉动,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宏邮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泽示。...
- 正文 年R本政府宣布变姨,位于F島的核電站,受9級(jí)特大地震影響厌丑,放射性物質(zhì)發(fā)生泄漏定欧。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一怒竿、第九天 我趴在偏房一處隱蔽的房頂上張望砍鸠。 院中可真熱鬧,春花似錦耕驰、人聲如沸爷辱。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饭弓。三九已至双饥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弟断,已是汗流浹背咏花。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像刘急,于是被迫代替她去往敵國(guó)和親棚菊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 三大框架架構(gòu)整合原理 一.導(dǎo)包(41個(gè)包) 1. hibernate 2. struts2(javassist.j...
- 第一節(jié): Spring提供了很多持久層技術(shù)的模板類(lèi)簡(jiǎn)化編程 1.1 JDBC模板使用入門(mén) 創(chuàng)建項(xiàng)目引入jar包 創(chuàng)...