需要jar包
jdbc编程不变,主要是Connection对象的维护,即配置并使用数据源
1)
tcp
XE
thin
1521
briup
127.0.0.1
briup
注意:别忘了读取配置文件
2)
${driver}
${url}
${user}
${password}
80
20
3000
3)
${driver}
${url}
${user}
${password}
4)c3p0数据源
${driver}
${url}
${user}
${password}
5
30
10
60
5
60
30
1.实体类hus对象(数据库建表)
package com.briup.db;
public class Hus {
private long id;
private String name;
private int age;
public long getId() {
return id;
}
public Hus(long id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Hus() {
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.dao层接口
package com.briup.db;
public interface HusDao {
void updateHus(Hus hus);
}
3.jdbc需要提供实现类
package com.briup.db.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.briup.db.Hus;
import com.briup.db.HusDao;
public class HusDaoImpl implements HusDao{
private DataSource datasource;
@Override
public void updateHus(Hus hus) {
// TODO Auto-generated method stub
Connection conn=null;
try {
//从数据源中获取连接对象
conn=datasource.getConnection();
System.out.println("conn:"+conn);
/*
* 指向sql操作
*/
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(conn!=null)
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public DataSource getDatasource() {
return datasource;
}
public void setDatasource(DataSource datasource) {
this.datasource = datasource;
}
}
4.配置文件xml
${driver}
${url}
${username}
${passwd}
${driver}
${url}
${username}
${passwd}
5
30
10
60
5
60
30
5.db.properties文件
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@192.168.43.216:1521:XE
username=jd1812
passwd=briup
注意导入相关jar包:mybatis-spring-1.2.2.jar
使用Spring整合mybatis时,可以使用mybatis-config.xml文件,也可以不使用
true
或者:
最后还需要扫描mybatis中映射接口,以便spring为其生产对应的实现类
1.实体类,接口同上
2.mybatis不用构建接口实现类
构建配置文件
update hus set name=#{name},age=#{age}
where id=#{id}
3.构建mybatis配置文件xml
${driver}
${url}
${username}
${passwd}
true
4.测试类:
package com.briup.db.mybatis;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.db.Hus;
import com.briup.db.HusDao;
public class mybatisTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext cp=
new ClassPathXmlApplicationContext(
"com/briup/db/mybatis/mybatis.xml");
HusDao dao=(HusDao) cp.getBean("husDao");
dao.updateHus(new Hus(1, "jake", 100));
}
}
1)编程式事务管理(不常用)
所谓编程式事务指的是通过编码方式实现事务。
2)声明式事务管理(常用)
在Spring配置文件中声明式的处理事务来代替代码式的处理事务.
在spring中,声明式事务主要是通过【事务属性】来定义的,事务属性描述
了事务策略如何应用到方法上面
事务属性主要包含了以下5个方面:(文档的最后有统一的介绍)
传播行为 (propagation)
隔离级别 (isolation)
回滚规则 (rollback-for no-rollback-for)
事务超时 (timeout)
是否只读 (read-only)
声明式事务管理的配置方式通常以下几种:
注意:配置事务的方式都需要用到事务管理器(切面)和事务拦截器(advice),其实就是使用aop编程,把事务代码动态织入到需要使用的方法上
spring中实现aop的配置方式很多,在这里配置事务的时候推荐使用:
1.tx前缀的事务标签和aop前缀的标签结合,将切面(事务管理器)织入到切入点上
2.注解进行事务配置
了解事务属性包含的五个方面分别是什么:
1)事务传播行为
规定了如果有新的事务应该被启动还是被挂起,或者方法是否需要在事务中运行。
TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
2)事务隔离级别
事务以及事务所引发的问题
1.脏读 主要针对update操作。 一个事务A读到另一个事务B中
修改过但是还没有提交的数据
2.不可重复读 主要针对update操作。 一个事务A在第一次读数据和
第二次读数据之间,
有另一个事务B把这个数据更改并提交了,
所有就出现了事务A里面读一个数据俩次,
但是读到的结果是不同的。
3.幻读 主要针对的是insert/delete操作。
事务A第一次用where条件筛选出了10条数据,
事务A第二次用通样的where条件筛选出的却是11条数据,
因为事务B在事务A的第一次和第二次查询直接进行了插入操作,
并且插入的这个数据满足事务A的where筛选条件.
定义了一个事务可能受其他并发事务影响的程度。
隔离级别是指若干个并发的事务之间的隔离程度。
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,
通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。
该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。不提交也能读
TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。
该级别可以防止脏读,这也是大多数情况下的推荐值。 提交之后才能读 解决了脏读
TransactionDefinition.ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,
并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。
解决了脏读和不可重复读
TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,
也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
三个问题都解决了
注意:不同的数据库所能支持的事务隔离级别以及默认的事务隔离级别有可能是不同的
3)事务的只读属性
定义了一个事务中是否是只读操作,如果设置只读那么数据库内部就可以对该操作进行合适的优化措施,
只有传播行为是PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEW PROPAGATION_NESTED的时候只读设置才有意义
,因为只读优化是在事务开始的时候由数据库实施的,而在这三个传播行为下才有可能启动一个新事务
4)事务超时
为了使应用程序可以很好的运行,事务不能运行太长的时间,所以这个属性就控制着这个时间.只有传播行
为是PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEW PROPAGATION_NESTED的时候超时设置才有意义,
因为超时时钟会在事务开始的时候启动,而在这三个传播行为下才有可能启动一个新事务.注意事务超时后会自动回滚.(单位是 秒)
5)事务的回滚规则
定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务在遇到运行时异常的时候才会回滚,而遇到检查时异常时不会回滚
-Exception表示有Exception抛出时,事务回滚. -代表回滚+就代表提交
事务处理方式一:AOP标签库
1.定义接口(接口-dao层-service层)(以jdbc连接为模板)
package com.briup.tran;
import com.briup.db.Hus;
public interface HusDao1 {
void saveHus(Hus hus);
}
2.1.dao层实现类
package com.briup.tran.dao.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import com.briup.db.Hus;
import com.briup.tran.HusDao1;
public class jdbcHusDaoImpl implements HusDao1{
private DataSource datasource;
@Override
public void saveHus(Hus hus) {
/*把dataSource注入dao层来直接使用,则需要注意下面几个点
一定不要这样拿conn 因为我们要保证service开始事务
和提交事务用的conn和dao层用到的conn是同一个对象
Connection conn = datasource.getConnection();
一定要这样去拿conn,因为DataSourceUtils是spring提供的工具类
Connection conn = DataSourceUtils.getConnection(datasource);
*/
Connection conn =null;
PreparedStatement ps=null;
try {
conn= DataSourceUtils.getConnection(datasource);
String sql="insert into hus values(?,?,?)";
ps=conn.prepareStatement(sql);
ps.setLong(1, hus.getId());
ps.setString(2, hus.getName());
ps.setInt(3, hus.getAge());
ps.execute();
} catch (CannotGetJdbcConnectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public DataSource getDatasource() {
return datasource;
}
public void setDatasource(DataSource datasource) {
this.datasource = datasource;
}
}
2.2.配置文件xml配置数据源
${driver}
${url}
${username}
${passwd}
3.1.service层方法接口
package com.briup.tran.service;
import com.briup.db.Hus;
public interface HusService {
void saveHus(Hus hus) ;
}
3.2.实现类
package com.briup.tran.service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.briup.db.Hus;
import com.briup.tran.HusDao1;
//@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Throwable.class)
public class HusServiceImpl
implements HusService{
private HusDao1 dao;
@Override
public void saveHus(Hus hus) {
// TODO Auto-generated method stub
dao.saveHus(hus);
}
public HusDao1 getDao() {
return dao;
}
public void setDao(HusDao1 dao) {
this.dao = dao;
}
}
3.3配置service层对象与事务管理器
3.3.包含注释版(anno)
4.测试类
package com.briup.tran.Test.jdbc;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.db.Hus;
import com.briup.tran.service.HusService;
public class jdbcTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext cp=
new ClassPathXmlApplicationContext(
"com/briup/tran/dao/jdbc/jdbc.xml",
"com/briup/tran/service/jdbc/jdbc_service.xml");
HusService service=(HusService) cp.getBean("service");
service.saveHus(new Hus(3, "wangwu", 44));
}
}
4.包含注释版(anno)
package com.briup.tran.Test.jdbc;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.db.Hus;
import com.briup.tran.service.HusService;
public class jdbcTest_anno {
public static void main(String[] args) {
ClassPathXmlApplicationContext cp=
new ClassPathXmlApplicationContext(
"com/briup/tran/dao/jdbc/jdbc.xml",
"com/briup/tran/service/jdbc/jdbc_service_anno.xml");
HusService service=(HusService) cp.getBean("service");
service.saveHus(new Hus(4, "wangwu", 44));
}
}
Mybaties事务处理:
1.接口
package com.briup.tran;
import com.briup.db.Hus;
public interface HusDao1 {
void saveHus(Hus hus);
}
2.1.dao层 husDao.xml
insert into hus values(#{id},#{name},#{age})
2.2.配置mybatis
${driver}
${url}
${username}
${passwd}
true
3.1.
package com.briup.tran.service;
import com.briup.db.Hus;
public interface HusService {
void saveHus(Hus hus) ;
}
package com.briup.tran.service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.briup.db.Hus;
import com.briup.tran.HusDao1;
//@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Throwable.class)
public class HusServiceImpl
implements HusService{
private HusDao1 dao;
@Override
public void saveHus(Hus hus) {
// TODO Auto-generated method stub
dao.saveHus(hus);
}
public HusDao1 getDao() {
return dao;
}
public void setDao(HusDao1 dao) {
this.dao = dao;
}
}
不加注释
注释版
4.测试类
package com.briup.tran.Test.mybatis;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.db.Hus;
import com.briup.tran.service.HusService;
public class mybatisTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext cp=
new ClassPathXmlApplicationContext(
"com/briup/tran/dao/mybatis/mybatis.xml",
"com/briup/tran/service/mybatis/mybatis_service.xml");
HusService service=(HusService) cp.getBean("service");
service.saveHus(new Hus(5, "wangwu", 44));
}
}
注释版
package com.briup.tran.Test.mybatis;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.briup.db.Hus;
import com.briup.tran.service.HusService;
public class mybatisTest_anno {
public static void main(String[] args) {
ClassPathXmlApplicationContext cp=
new ClassPathXmlApplicationContext(
"com/briup/tran/dao/mybatis/mybatis.xml",
"com/briup/tran/service/mybatis/mybatis_service_anno.xml");
HusService service=(HusService) cp.getBean("service");
service.saveHus(new Hus(6, "wangwu", 44));
}
}