事务,连接池,分包分层(MVC设计模式)
-事务的作用
保证一个业务要么全部执行成功要么全部执行失败
-事务的四大原则
A:事务的原子性: 每一个都事务最小的原子单位 不能进行分割==>要么同时都执行成功要么同时执行失败
C: 事务的一致性 :要么是在执行前的状态要么执行后的状态,执行后系统状态是一致的
D: 事务的隔离性 : 并发执行的事务彼此无法看到对方的中间状态
L: 持久性 : 只要commit后 永久包存到数据库了
-操作事务
1.使用mysql数据库操作事务
2.使用Java来操作事务
-事务的隔离级别
事务隔离级别 |
脏读 |
不可重复读 |
幻读 |
数据库默认级别 |
未提交读(Read uncommitted) |
可能 |
可能 |
可能 |
|
已提交读(Read committed) |
不可能 |
可能 |
可能 |
Oracle/SQL Server |
重复(Repeatable read) |
不可能 |
不可能 |
可能 |
MySQL |
可串行化(SERIAUZABLE) |
不可能 |
不可能 |
不可能 |
一般使用少 |
1. 什么是脏读:
A事务读取B事务尚未提交的数据并在此基础上操作,而B事务执行回滚,那么A读取到的数据就是脏读。
2. 什么是不可重复度:
事务A读取前面读取过的数据,发现该数据已经被另一个已提交的事务B修改过了。
3. 什么是幻读:
事务A重新执行一个查询,返回一系列符合查询条件的行,发现其中插入了被事务B提交的行。
4. 第一类丢失更新:
事务A撤销时,把已经提交的事务B的更新数据覆盖了
5. 第二类丢失更新:
事务A覆盖了事务B已经提交的数据,造成事务B所做的操作丢失。
-什么是事务的回滚?
案例:假如一个部门有很多员工,分别在员工表与部门表中,在删除部门表时假设默认删除对应的员工,执行中会出现先删部门再删员工,部门删除了,员工未删除,此时如果删除员工的时候失败了,那么之前的删除的部门也应该删除失败,这就是事务的回滚。
-JDBC中如何进行事务的处理?
Connection提供了事务处理的方法,通过调用setAutoConnection(false)可以设置手动提交事务,当事务完成commit()显示提交事务,如果事务提交过程中发现了异常则进行事务回滚。从JDBC3.0中还引入了Savepoint(保存点)的概念,允许通过代码设置保存点并让事务回滚到指定的保存点。
-连接池
1. 概念
连接池的厂商会一次性创建多个连接,我们只需要去连接池获取连接,当操作完之后归还给连接池即可,连接池会把连接设置为最初的状态(并不是销毁)下一个用户又可以来获取这个连接。
2. 作用
反复来创建连接和销毁连接,提高我们操作数据库的效率,减轻服务器的压力。
3. 常用的连接池
dbcp
特点:
1. 效率非常高 效率最高
2.可能会丢包(丢失数据) socket的 udp: 效率高 丢失数据
3.dbcp 一秒创建1000连接
4.dbcp是tomcat(服务器)的内置连接池
使用步骤:
1. 导包(2个):commons-dbcp-1.4.jar commons-pool-1.6.jar
2. 在类的目录下加入配置信息(加载配置文件)
3. 需要把配置文件的信息,加载到properties里面
4. 获取连接池对象
c3p0
特点:
1. 安全性高 不会丢失数据 效率低
2. spring 全家桶 才用的连接池 都是使用c3p0 springmvc springboot springdata
使用步骤:
导包两个:c3p0-0.9.2-pre5.jar mchange-commons-java-0.2.3.jar
druip(阿里的)
特点:
1. 数据吞吐量大
2. 支持流式数据摄入和实时
3. 查询灵活且快速
Druid是一个分布式数据分析平台,也是一个时序数据库
-自定义连接池
1 import java.sql.Connection; 2 import java.util.ArrayList; 3 import java.util.List; 4 5 public class MyConnectionUtils { 6 //获取连接 7 private static BaseDao baseDao = new BaseDao(); 8 9 //容器来存连接 10 private static List<Connection> list = new ArrayList<Connection>(); 11 12 13 //来初始化连接 14 15 static { 16 for (int i =1;i<=5;i++){ 17 list.add(baseDao.getConnection()); 18 19 } 20 21 System.out.println("当前有"+list.size()+"个连接可以使用"); 22 23 } 24 25 //获取连接的方法 26 27 public static Connection getConn(){ 28 //获取了一个连接 29 Connection conn = list.get(0); 30 //当前连接正在使用 请使用其它的连接 31 list.remove(0); 32 System.out.println("当前有"+list.size()+"当前正在使用的连接是"+conn); 33 return conn; 34 } 35 36 //释放连接 37 38 public static void close(Connection con){ 39 if(con !=null){ 40 //释放 41 list.add(con); 42 } 43 44 System.out.println("现在的连接数是"+list.size()); 45 46 } 47 48 49 public static void main(String[] args) { 50 Connection con = MyConnectionUtils.getConn(); 51 // System.out.println(con); 52 53 //释放连接 54 MyConnectionUtils.close(con); 55 } 56 57 58 59 }
-Dbutils框架
dbutils框架 与 hibernate 和 mybatis 框架都是用来操作数据库的。对JDBC的封装,简化开发的步骤,提供了一些类和接口,其中核心的类 QueryRunner()
使用步骤:
1. 导包
2. 得到其核心对象 QueryRunner qr = new QueryRunner(“参数是连接池的对象”)
代码(增删改查操作)
1 import com.mchange.v2.c3p0.ComboPooledDataSource; 2 import org.apache.commons.dbutils.QueryRunner; 3 import org.apache.commons.dbutils.handlers.*; 4 import org.junit.Test; 5 6 import java.sql.SQLException; 7 import java.util.Arrays; 8 import java.util.List; 9 import java.util.Map; 10 11 public class Test3 { 12 private ComboPooledDataSource dataSource = new ComboPooledDataSource(); 13 private QueryRunner qr = new QueryRunner(dataSource); 14 //增加 15 @Test 16 public void add(){ 17 String sql = "insert into account(aname,amoney)values(?,?)"; 18 Object[] objects={"阿力",3000}; 19 int num = 0; 20 try { 21 num = qr.update(sql,objects); 22 } catch (SQLException e) { 23 e.printStackTrace(); 24 } 25 System.out.println(num); 26 27 } 28 //修改 29 @Test 30 public void update(){ 31 String sql = "update account set aname=?,amoney=? where aid=?"; 32 Object[] objects={"赵四",10000,3}; 33 int num = 0; 34 try { 35 num = qr.update(sql,objects); 36 } catch (SQLException e) { 37 e.printStackTrace(); 38 } 39 System.out.println(num); 40 41 } 42 //删除 43 @Test 44 public void delete(){ 45 String sql = "delete from account where aid=?" ; 46 47 int num = 0; 48 try { 49 num = qr.update(sql,3); 50 } catch (SQLException e) { 51 e.printStackTrace(); 52 } 53 System.out.println(num); 54 55 } 56 57 //根据id查询 58 @Test 59 public void seleteById(){ 60 try { 61 String sql = "select * from account where aid=?" ; 62 Account account = qr.query(sql,new BeanHandler<Account>(Account.class),1); 63 System.out.println(account); 64 } catch (SQLException e) { 65 e.printStackTrace(); 66 } 67 68 69 } 70 71 //查询所有封装到集合中 72 @Test 73 public void selectAll(){ 74 try { 75 String sql = "select * from account" ; 76 List<Account> list = qr.query(sql,new BeanListHandler<Account>(Account.class)); 77 for (Account a:list) { 78 System.out.println(a); 79 } 80 } catch (SQLException e) { 81 e.printStackTrace(); 82 } 83 84 85 } 86 //查询对象封装到数组中 87 @Test 88 public void seleteByObject(){ 89 try { 90 String sql = "select * from account where aid=?" ; 91 Object[] objects = qr.query(sql,new ArrayHandler(),1); 92 for(Object obj :objects){ 93 System.out.println(obj); 94 } 95 96 } catch (SQLException e) { 97 e.printStackTrace(); 98 } 99 100 101 } 102 103 //查询所有封装到集合数组中 104 @Test 105 public void seleteByAll(){ 106 try { 107 String sql = "select * from account" ; 108 List<Object[]> list = qr.query(sql,new ArrayListHandler()); 109 for(Object[] objects :list){ 110 System.out.println(Arrays.toString(objects)); 111 } 112 113 /* for(Object obj :objects){ 114 System.out.println(obj); 115 } 116 */ 117 } catch (SQLException e) { 118 e.printStackTrace(); 119 } 120 121 122 } 123 124 125 //查询所有封装到map集合中 126 @Test 127 public void seleteByMap(){ 128 String sql ="select * from account where aid=?"; 129 try { 130 Map<String,Object> map = qr.query(sql,new MapHandler(),1); 131 for(String s:map.keySet()){ 132 System.out.println(s+"\t"+map.get(s)); 133 } 134 } catch (SQLException e) { 135 e.printStackTrace(); 136 } 137 138 139 } 140 141 142 @Test 143 public void seleteByAllMap(){ 144 String sql ="select * from account "; 145 try { 146 List<Map<String,Object>> list = qr.query(sql,new MapListHandler()); 147 for(Map<String,Object> map : list){ 148 for(String s : map.keySet()){ 149 System.out.println(s+"\t"+map.get(s)); 150 } 151 } 152 /*for(String s:map.keySet()){ 153 System.out.println(s+"\t"+map.get(s)); 154 }*/ 155 } catch (SQLException e) { 156 e.printStackTrace(); 157 } 158 159 160 } 161 162 //查询总计数 163 @Test 164 public void selectCount(){ 165 try { 166 String sql ="select count(1) from account "; 167 Long count = (Long) qr.query(sql,new ScalarHandler()); 168 System.out.println(count); 169 } catch (SQLException e) { 170 e.printStackTrace(); 171 } 172 173 174 } 175 176 177 }
-分层分包(MVC设计模式)
com.offcn.entity ==>实体包 com.offcn.dao ==>操作数据库 定义一些方法 都是接口 com.offcn.dao.impl ==>实现类 com.offcn service ==>逻辑处理 定义一些方法 com.offcn.service.impl 实现层 com.offcn.test ==>定义测试类 |