• 事务&数据库连接池&DBUtils


    事务的特性

    • 原子性

    指的是 事务中包含的逻辑,不可分割。

    • 一致性

    指的是 事务执行前后。数据完整性

    • 隔离性

    指的是 事务在执行期间不应该受到其他事务的影响

    • 持久性

    指的是 事务执行成功,那么数据应该持久保存到磁盘上。

    事务的安全隐患

    不考虑隔离级别设置,那么会出现以下问题。

    脏读 不可重读读 幻读.

    * 脏读
    
    > 一个事务读到另外一个事务还未提交的数据
    
    * 不可重复读 
    
    > 一个事务读到了另外一个事务提交的数据 ,造成了前后两次查询结果不一致。
    

    可串行化

    如果有一个连接的隔离级别设置为了串行化 ,那么谁先打开了事务, 谁就有了先执行的权利, 谁后打开事务,谁就只能得着,等前面的那个事务,提交或者回滚后,才能执行。 但是这种隔离级别一般比较少用。 容易造成性能上的问题。 效率比较低。

    • 按效率划分,从高到低

    读未提交 > 读已提交 > 可重复读 > 可串行化

    • 按拦截程度 ,从高到底

    可串行化 > 可重复读 > 读已提交 > 读未提交

    事务总结

    需要掌握的

    1. 在代码里面会使用事务

       conn.setAutoCommit(false);
      
      
       conn.commit();
      
       conn.rollback();
      
    2. 事务只是针对连接连接对象,如果再开一个连接对象,那么那是默认的提交。

    3. 事务是会自动提交的。

    需要了解的

    安全隐患

    读
    	脏读
    		一个事务读到了另一个事务未提交的数据
    	不可重复读
    		一个事务读到了另一个事务已提交的数据,造成前后两次查询结果不一致
    	幻读
    		一个事务读到了另一个事务insert的数据 ,造成前后查询结果不一致 。
    
    写
    
    	丢失更新。
    

    隔离级别

    读未提交

    引发问题: 脏读

    读已提交

    解决: 脏读 , 引发: 不可重复读

    可重复读

    解决: 脏读 、 不可重复读 , 未解决: 幻读

    可串行化

    解决: 脏读、 不可重复读 、 幻读。

    mySql 默认的隔离级别是 可重复读

    Oracle 默认的隔离级别是 读已提交

    数据库连接池

    1. 数据库的连接对象创建工作,比较消耗性能。

    2.一开始现在内存中开辟一块空间(集合) , 一开先往池子里面放置 多个连接对象。 后面需要连接的话,直接从池子里面去。不要去自己创建连接了。 使用完毕, 要记得归还连接。确保连接对象能循环利用。

    开源连接池

    DBCP

    1. 导入jar文件

    2. 不使用配置文件:

    		public void testDBCP01(){
    
    
    ​			
    			Connection conn = null;
    			PreparedStatement ps = null;
    			try {
    				
    				//1. 构建数据源对象
    				BasicDataSource dataSource = new BasicDataSource();
    				//连的是什么类型的数据库, 访问的是哪个数据库 , 用户名, 密码。。
    				//jdbc:mysql://localhost/bank 主协议:子协议 ://本地/数据库
    				dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    				dataSource.setUrl("jdbc:mysql://localhost/bank");
    				dataSource.setUsername("root");
    				dataSource.setPassword("root");
    
    
    ​				
    				//2. 得到连接对象
    				conn = dataSource.getConnection();
    				String sql = "insert into account values(null , ? , ?)";
    				ps = conn.prepareStatement(sql);
    				ps.setString(1, "admin");
    				ps.setInt(2, 1000);
    				
    				ps.executeUpdate();
    				
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}finally {
    				JDBCUtil.release(conn, ps);
    			}
    			
    		}
    
    1. 使用配置文件方式:
    		Connection conn = null;
    		PreparedStatement ps = null;
    		try {
    			BasicDataSourceFactory factory = new BasicDataSourceFactory();
    			Properties properties = new Properties();
    			InputStream is = new FileInputStream("src//dbcpconfig.properties");
    			properties.load(is);
    			DataSource dataSource = factory.createDataSource(properties);
    			
    			//2. 得到连接对象
    			conn = dataSource.getConnection();
    			String sql = "insert into account values(null , ? , ?)";
    			ps = conn.prepareStatement(sql);
    			ps.setString(1, "liangchaowei");
    			ps.setInt(2, 100);
    			
    			ps.executeUpdate();
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally {
    			JDBCUtil.release(conn, ps);
    		}
    
    
    
    • C3P0

    拷贝jar文件 到 lib目录

    不使用配置文件方式

    		Connection conn = null;
    		PreparedStatement ps = null;
    		try {
    			//1. 创建datasource
    			ComboPooledDataSource dataSource = new ComboPooledDataSource();
    			//2. 设置连接数据的信息
    			dataSource.setDriverClass("com.mysql.jdbc.Driver");
    			
    			//忘记了---> 去以前的代码 ---> jdbc的文档
    			dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
    			dataSource.setUser("root");
    			dataSource.setPassword("root");
    			
    			//2. 得到连接对象
    			conn = dataSource.getConnection();
    			String sql = "insert into account values(null , ? , ?)";
    			ps = conn.prepareStatement(sql);
    			ps.setString(1, "admi234n");
    			ps.setInt(2, 103200);
    			
    			ps.executeUpdate();
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally {
    			JDBCUtil.release(conn, ps);
    		}
    
    

    使用配置文件方式

    			//默认会找 xml 中的 default-config 分支。 
    			ComboPooledDataSource dataSource = new ComboPooledDataSource();
    			//2. 设置连接数据的信息
    			dataSource.setDriverClass("com.mysql.jdbc.Driver");
    
    
    			//忘记了---> 去以前的代码 ---> jdbc的文档
    			dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
    			dataSource.setUser("root");
    			dataSource.setPassword("root");
    			
    			//2. 得到连接对象
    			conn = dataSource.getConnection();
    			String sql = "insert into account values(null , ? , ?)";
    			ps = conn.prepareStatement(sql);
    			ps.setString(1, "admi234n");
    			ps.setInt(2, 103200);
    

    DBUtils

    增删改

    
    				//dbutils 只是帮我们简化了CRUD 的代码, 但是连接的创建以及获取工作。 不在他的考虑范围
    		QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    
    
    ​		
    		//增加
    		//queryRunner.update("insert into account values (null , ? , ? )", "aa" ,1000);
    		
    		//删除
    		//queryRunner.update("delete from account where id = ?", 5);
    		
    		//更新
    		//queryRunner.update("update account set money = ? where id = ?", 10000000 , 6);
    

    查询

    1. 直接new接口的匿名实现类
    		QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    
    
    		Account  account =  queryRunner.query("select * from account where id = ?", new ResultSetHandler<Account>(){
    	
    			@Override
    			public Account handle(ResultSet rs) throws SQLException {
    				Account account  =  new Account();
    				while(rs.next()){
    					String name = rs.getString("name");
    					int money = rs.getInt("money");
    					
    					account.setName(name);
    					account.setMoney(money);
    				}
    				return account;
    			}
    			 
    		 }, 6);
    		
    		System.out.println(account.toString());
    
    1. 直接使用框架已经写好的实现类。

      • 查询单个对象
    		QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    		//查询单个对象
    		Account account = queryRunner.query("select * from account where id = ?", 
    				new BeanHandler<Account>(Account.class), 8);
    
    


    * 查询多个对象

    		QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
    		List<Account> list = queryRunner.query("select * from account ",
    				new BeanListHandler<Account>(Account.class));
    

    ResultSetHandler 常用的实现类

    以下两个是使用频率最高的

    BeanHandler,  查询到的单个数据封装成一个对象
    BeanListHandler, 查询到的多个数据封装 成一个List<对象>
    

    ArrayHandler,  查询到的单个数据封装成一个数组
    ArrayListHandler,  查询到的多个数据封装成一个集合 ,集合里面的元素是数组。 
    



    MapHandler, 查询到的单个数据封装成一个map
    MapListHandler,查询到的多个数据封装成一个集合 ,集合里面的元素是map。

    ColumnListHandler
    KeyedHandler
    ScalarHandler

  • 相关阅读:
    使用NetworkX进行社交分析
    文本情感分析
    使用NLTK进行基础的NLP处理
    使用pandas对文本数据进行处理
    文本处理
    分类器可视化
    无监督学习
    监督学习2
    模型验证
    Netty学习摘记 —— 预置SSL / HTTP / WebSocket编解码器
  • 原文地址:https://www.cnblogs.com/superfly123/p/10530354.html
Copyright © 2020-2023  润新知