目录:
1:JDBC部分
1.1:最基本的jdbc使用:
1 //要连接的数据库URL
2 String url = "jdbc:mysql://localhost:3306/database名";
3 //连接的数据库时使用的用户名
4 String username = "root";
5 //连接的数据库时使用的密码
6 String password = "root";
7
8 //1.加载驱动
9 Class.forName("com.mysql.jdbc.Driver");//推荐使用这种方式来加载驱动
10 //2.获取与数据库的链接
11 Connection conn = DriverManager.getConnection(url, username, password);
12 //3.获取用于向数据库发送sql语句的statement
13 Statement st = conn.createStatement();
14 String sql = "select id,name,password,email,birthday from users";
15 //4.向数据库发sql,并获取代表结果集的resultset
16 ResultSet rs = st.executeQuery(sql);
1.2:相关类:
* mysqlUrl的形式:jdbc:mysql://localhost:3306/[databaseName],使用3306端口时,简写为:jdbc:mysql:///[databaseName]
1.3:批处理:
(1)Statement批处理:statement.addBatch(sql1)….最后statement.executeBatch(),Statement.clearBatch();
(2)PreparedSatement批处理:只能处理语句相同单参数不同的sql语句,方法同上;
2、事务处理:
事务:逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功;
2.1:mysql中开启事务:start transaction;开启->crud->commit;(rollback;)提交或回滚;
2.2:jdbc中的事务:通过Connection设置:setAutoCommit(false)、commit()、rollback();
2.3:事务的四大特性:
* * 原子性:事务中的操作要么全部成功,要么全部失败
* 异质性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态
* 隔离性:多个并发事务之间要相互隔离(最麻烦)
* 持久性:事务一旦被提交,它对数据库中数据的改变就是永久性的
2.4:不考虑隔离性造成的问题:
* * 脏读:事务A读取事务B未提交的数据
* 不可重复读:事务A读取数据,多次结果不一样(因为期间事务B提交了事务);
* 虚读(幻读):事务A读取事务B插入的数据,造成A前后读取数据不一致。
2.5:隔离性设置:
* * Serializable(串行化):避免全部问题;
* Repeatable read(可重复读):避免脏读、不可重复读;
* Read committed(读已提交):避免脏读
* Read uncommitted(读未提交):最低级,无法避免任何问题;
2.6:mysql设置隔离性:
* * 默认级别:Repeatable read(可重复读);
* 查询当前级别:select @@tx_isolation;
* 设置级别:set transaction isolation level 隔离级别名;
3、数据库连接池:
Connection资源很珍贵,开销也大,连接池负责管理、分配、释放Connection,允许连接的重复使用;
3.1:jdbc的DataSource类:这不是连接池,该类只负责批量创建Connection,不负责管理;
DataSource ds=BasicDataSourceFactory.createDataSource(prop);//创建数据源,prop是load配置文件Properties
datasource.getConnection()获取Connection ;
3.2:DBCP开源连接池:使用方法同上,但是DBCP不能自动回收空连接;
3.3:C3P0开源链接池:Hibernate,Spring框架中常用,能自动回收空闲连接;
依赖jar包: c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar;我第一次写spring jdbc就少了后者,囧!
类目下需配置C3P0的配置文件c3p0-config.xml:jdbc的url,driver、用户名、密码、连接数等;
使用方式:
* * private static ComboPooledDataSource ds=new ComboPooledDataSource("MySQL")//使用C3P0的命名配置来创建数据源
* 也可以通过:ds = new ComboPooledDataSource(); ds.setDriverClass("com.mysql.jdbc.Driver"); ….等单独设置连接池大小和驱动,用户密码信息
* ds.getConection()
3.4:JNDI技术:Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需 通过名称检索即可
4、其他类与工具类:
4.1:通过Connection获取数据库的元数据:
DatabaseMetaData Connection.getDatabaseMetaData();//获取database的元数据对象。获取后:getUserName();getURL()获取database的信息;
ParameterMetaData PreparedStatement.getParameterMetaData() :获取PreparedStatement元数据的对象
ResultSetMetaData ResultSet. getMetaData() :ResultSet对象元数据的ResultSetMetaData对象
4.2:Apache 组织的开源 JDBC工具类库dbutils,很多不喜欢hibernate的公司用;
QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); 直接通过qr进行crud;
ResultSetHandler接口用于处理ResultSet接口;
搭配ThreadLocal县城本地变量使用;
**
1.1、JdbcTemplate简介
Spring对数据库的操作在jdbc上做了更深层次的封装,使用spring的注入功能,可以将DataSource注册到JdbcTemplate之中
JdbcTemplate的主要方法:
* 构造: public JdbcTemplate([DataSource dataSource],[boolean lazyInit]);接收一个DataSource源数据,因因此可以通过spring的配置文件,在管理JdbcTemplate的bean时注入一个DataSource,方便使用
1 <context:property-placeholder location="classpath:db.properties"/>
2 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
3 <property name="user" value="${jdbc.user}"></property>
4 <property name="password" value="${jdbc.password}"></property>
5 <property name="driverClass" value="${jdbc.driverClass}"></property>
6 <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
7 </bean>
8
9 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
10 <property name="dataSource" ref="dataSource"></property>
11 </bean>
方法: execute()、update方法及batchUpdate方法、query方法及queryForXXX方法、call方法 比如:
update: int count= jdbcTemplate.update(sql, new Object[]{"王小五",3});
batchUpdate:
1 String sql="insert into user (name,deptid) values (?,?)";
2
3 List
1.2:使用JdbcTemplate读取到实体对象
* 读取单个对象:
@Override
public User getById(Integer id) {
String sql="select \* from jdbc\_user where id=?";
return super.getJdbcTemplate().**queryForObject**(sql, new RowMapper<User>() {//内部类重写 mapRow方法
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User u=new User();
u.setId(resultSet.getInt("id"));
u.setName(resultSet.getString("name"));
return u;
}
}**,id**);//别丢
}
读取对个对象:
1 public List
2 String sql="select * from jdbc_user";
3 List
4 @Override//内部类写法同上,区别在与方法上
5 public User mapRow(ResultSet resultSet, int i) throws SQLException {
6 User u=new User();
7 u.setId(resultSet.getInt("id"));
8 u.setName(resultSet.getString("name"));
9 return u;
10 }
11 });
12 return list;
13 }
【这块我自己还没有完全理清楚,待完善】
3.1:JDBC中对事务隔离级别的设置: conn.setTransactionLevel 设置
* TRANSACTION_NONE JDBC 驱动不支持事务
TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读。
TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读。
TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,单运行幻读。
TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读
3.2:Spring事务管理:
spring并不直接管理事务,而是提供多种事务管理器,将事务管理委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现;
通过PlatformTransactionManager接口,Spring为各种平台(JDBC、Hibernate等)提供对应的事务管理器,其具体实现由具体平台负责。
3.2.1::spring 事务管理核心接口:PlatformTransactionManager :
通过其 getTransaction(TransactionDefinition definition)方法 根据其指定传播行为返回当前活动的事务或一个新事务。
3.2.2:TransactionDefinition接口:定义了它自己的传播行为和隔离级别 ,以下为定义的方法;
* 接口下的方法:
1 int getPropagationBehavior();//返回传播行为
2 int getIsolationLevel();//返回隔离级别
3 int getTimeout();//事务应在多少秒内完成
4 boolean isReadOnly();//事务是否只读;
5 String getName();//返回事务名称
7个传播属性:
1 int PROPAGATION_REQUIRED = 0;//支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是Spring默认的事务的传播
2 int PROPAGATION_SUPPORTS = 1;//支持当前事务,如果当前没有事务,就以非事务方式执行
3 int PROPAGATION_MANDATORY = 2;//支持当前事务,如果当前没有事务,就抛出异常。
4 int PROPAGATION_REQUIRES_NEW = 3;//新建事务,如果当前存在事务,把当前事务挂起。
5 int PROPAGATION_NOT_SUPPORTED = 4;//以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6 int PROPAGATION_NEVER = 5;//以非事务方式执行,如果当前存在事务,则抛出异常
7 int PROPAGATION_NESTED = 6;//如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作
spring事务的隔离级别:
1 int ISOLATION_DEFAULT = -1;//默认的隔离级别,使用数据库默认的事务隔离级别。
2 int ISOLATION_READ_UNCOMMITTED = 1;//最低的隔离级别
3 int ISOLATION_READ_COMMITTED = 2;//保证一个事务修改的数据提交后才能被另外一个事务读取
4 int ISOLATION_REPEATABLE_READ = 4;//防止脏读,不可重复读
5 int ISOLATION_SERIALIZABLE = 8;//事务被处理为顺序执行
3.2.3:各平台的事务管理器:
如上图:(ref:http://www.blogjava.net/robbie/archive/2009/04/05/264003.html)
* JDBC:使用c3p0生成dataSource数据源bean,使用DataSourceTransactionManager管理事务;
1 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
2 <property name="dataSource" ref="dataSource"></property>
3 </bean>
Hibernate:Hibernate使用sessionFactory生成session,类似于Connection 。通过HibernateTransactionManager管理实务
1
Java持久化API事务(JPA):使用spring的JpaTransactionManager处理事务;
1
Java原生API事务:使用JtaTransactionManager管理事务;
1
3.3:Spring事务管理的方式 :编程式和声明式(基于AOP)
区别参考自:CSDN-民谊玉超-事务声明声明式事务和编程式事务介绍
事务实例参考自:cnBlogs-六月的余晖-spring事务管理案例
实例代码使用idea(2017)编辑;
3.3.1:编程式事务管理:所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理。管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
3.3.2:声明式事务:管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
3.3.3:对比:显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。
声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。
3.3.4:实例:基于jdbc平台(对应的是DataSourceTransactionManager事务管理器)的银行账户aaa向bbb转钱,(aaa的减与bbb的加组成一个事务)
逻辑图(自己瞎画的,有点乱):
编码式:编码式的实现需要自己编写代码处理事务:此处通过spring提供的transactionTemplate类方便实现,将其注入AccountServiceImpl中,将dataSource注入transactionTemplate,借用其execute方法实现事务操作。需要与操作类进行耦合,不利于拓展。
声明式:声明式中dao类的bean管理和jdbc事务管理器的配置都是一样的:不同的主要在事务实现配置
1
2
3
4
10
11
14
15
16
19
20
21
* 2中的配置:
1 <!--声明式事务管理-->
2 <!--配置业务层代理-->
3 <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
4 <!-- 配置目标对象 -->
5 <property name="target" ref="accountService"></property>
6 <!-- 注入事务管理器 -->
7 <property name="transactionManager" ref="transactionManager"></property>
8 <!-- 注入事务的属性,可以定位到方法transfer,必须配置-->
9 <property name="transactionAttributes">
10 <props>
11 <prop key="transfer">PROPAGATION\_REQUIRED</prop>
12 </props>
13 </property>
14 </bean>
3中的配置:
1
2
7
8
9
4中的配置:
1
2
ref:http://www.blogjava.net/robbie/archive/2009/04/05/264003.html总结了五种常用声明式事务管理的配置,可做参考。
目前只理解到这里了~~~,后期再深入学习补充!
<-----------------------------------------------------Ok---------------------------------------------------->
手机扫一扫
移动阅读更方便
你可能感兴趣的文章