zoukankan      html  css  js  c++  java
  • 2020.1.7-jdbc事务

    JDBC事务控制
    1.什么是事务:一个包含多个步骤或者业务操作,如果业务或者多个业务被事务管理,则这么多个步骤要么同时成功,要么同时失败,这些步骤是一个整体不可分割.
    2.操作:
    开启事务:mysql----->start transaction
    提交事务:commit
    回滚事务:rollback
    3.使用Connection对象来管理事物
    开启事物:setAutoCommit(boolean autoCommit):-->指定该方法里面传入false值,表示开启事务,开启事务是 在所有sql语句执行之前
    提交事务:commit():--->当前面所有的sql语句执行完毕(不出错)的时候才能提交事务
    回滚事务:rollback():--->当执行事务中sql语句时候,如果失去了语句发生异常那么就会回滚事务,所以回滚事务的代码一般都是放在catch语句块中
    4.示例代码:
    // 含有事务的转账
    public static void transform02() {
    // 让张三给李四转账10000钱
    /*
    * 首先让张三的钱减少10000
    * 然后让李四的钱增加10000
    */
    //定义实现转账的两条sql语句
    double money = 10000;
    String username01 = "张三";
    String username02= "李四";

    	String sql01 = "update account set balance = balance-? where username = ?";
    	String sql02 = "update account set balance = balance+? where username = ?";
    	// 使用Connection对象手动开启事务 setAutoCommit(boolean autoCommit):
    	Connection con = DBUtil.getConnection();
    	try {
    		con.setAutoCommit(false);
    		// 通过con获取预处理对象 先让张三的钱减少10000
    		ps01 = con.prepareStatement(sql01);
    		ps01.setDouble(1, money);
    		ps01.setString(2, username01);
    		// 执行sql语句
    		int count = ps01.executeUpdate();
    		// 手动制造一个异常
    		int i = 1 / 0;
    		// 再让李四的钱增加10000
    		// 通过con获取预处理对象
    		ps02 = con.prepareStatement(sql02);
    		ps02.setDouble(1, money);
    		ps02.setString(2, username02);
    		// 执行sql语句
    		int coun02 = ps02.executeUpdate();
    		// 提交事务
    		con.commit();
    		System.out.println("转账成功!");
    	} catch (Exception e) {
    		// 事务回滚
    		try {
    			con.rollback();
    			System.out.println("转账失败!");
    		} catch (SQLException e1) {
    			e1.printStackTrace();
    		}
    		e.printStackTrace();
    	}finally {
    		// 把打开的各种连接对象释放掉
    		try {
    			ps02.close();
    			ps01.close();
    			con.close();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    连接池
    1.什么是连接池
    其实就是一个容器,在这个容器当中存放着多个连接对象
    当系统开始运行的时候,可以让系统提前创建多个连接对象,放到容器里面(连接池),当客户端需要连接对象时,看洋葱常量池里面申请一个连接,去访问数据库的时候,当该连接使用完毕的时候,不再释放归还给系统,而是把这个连接对象还给连接池.
    2.好处:
    可以大大节省系统的开销
    可以提高访问速度

    3.实现操作
    javax.sql
    JNDI--->java命名和目录接口
    使用JNDI降低程序和数据库耦合度,是你的程序更加方便配置和维护以及部署.
    是javaEE中规范中的重要规范之一.是EJB的相关知识.
    DateSource接口 他里面并不提供具体的实现么事由驱动程序供应商(数据库厂商提供)

    1.c3p0---->一套数据库连接池的技术
    2.druid--->也是一套数据库连接池技术,由阿里巴巴提供
    3.c3p0数据库连接池技术

    步骤:
    1.找到 c3p0-0.9.5.2.jar和mchange-commons-java-0.2.12.jar
    2.把两个jar包植入到工程的classpath类路径下(lib包下),不要忘记导入mysql驱动jar包,mysql-connector-java.jar
    3.在src下面,定义配置文件;c3p0.properties或者c3p0-config.xml
    4.获取DateSource对象:通过工厂方式来实现,DruidDateSourceFactory
    5.从连接池中获取连接对象,:getConnection()
    JDBCTemplate
    1.Spring框架挺可怜对JDBC操作的简单封装,使用JDBCTemplate对象来简化JDBC开发流程
    2.步骤
    1.从官网找到spring-jdbc相关的jar包导入工程路径下(lib文件夹)
    2.创建JDBCtemplate对象,依赖于DateSource连接池(数据源)
    3.使用HDBCTemplate对象中的api方法实现crud操作
    DML操作:update();
    DQL操作:查询不用select用query
    query();将查询的结果集服装为javaBean对象
    query()方法的参数:RowMapper
    手动装配:使用匿名内部类,自定义装配查询的每条记录
    自动装配:使用Spring提供的BeanPropertyRowMapper实现类,完成对数据的自动装配
    具体操作如下:new BeanPropertyRowMapper<类型>(类型.class)
    queryForMap():将查询结果封装成map集合,只能封装一条记录:键key是字段名,值value是字段 值,结果集记录数只能是1
    queryForList():将结果集服装为List集合,在list集合中含有多条记录,每天一条记录都是一个map集合,List<Map<Object,Object>> list:
    queryForObject();将结果封装成为一个对象,一般用于聚合函数,查询总记录数 int count()
    具体操作:
    // 增删改动作
    // 修改数据
    public static void modifyData() {

    	int count = jdbcTemplate.update("update account set username = ? where username = ?", "小五","王五");
    	System.out.println(count);
    }
    // 删除数据
    public static void deleteData() {
    	int count = jdbcTemplate.update("delete from account where username = ?", "小五");
    	System.out.println(count);
    }
    // 插入一条数据
    public static void insertDate() {
    	int count = jdbcTemplate.update("insert into account values(null,?,?)", "王五",5000);
    	System.out.println(count);
    }
    public static void test() {
    	// 查询张三的这条信息 封装到账户对象中
    	String username = "张三";
    	String sql = "select * from account where username = ?";	
    	Map<String, Object> map = jdbcTemplate.queryForMap(sql,username);
    	System.out.println(map);// {id=1, username=张三, balance=20000.0}
    }
    
    // 简化手动封装的方法
    public static void queryAll() {
    	String sql = "select * from account";
    	// Incorrect column count: expected 1, actual 3
    	List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
    	System.out.println(list);
    	
    }
    
    // 使用query方法优化queryBean方法
    public static void queryBean2() {
    	List<Account> list = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
    	System.out.println(list);
    	
    }
    
    // 将查询到结果集封装成JavaBean对象
    public static void queryBean() {
    	String sql = "select * from account where username = '张三'";
    	// RowMapper<T>
    	List<Account> list = jdbcTemplate.query(sql, new RowMapper<Account>() {
    		@Override
    		public Account mapRow(ResultSet set, int arg1) throws SQLException {
    			// 封装查询到每一条记录值
    			Account account = new Account();
    			int id = set.getInt(1);
    			String username = set.getString(2);
    			double balance = set.getDouble(3);
    			account.setId(id);
    			account.setUsername(username);
    			account.setBalance(balance);
    			return account;
    		}
    	});
    	
    	System.out.println(list);// [Account [id=1, username=张三, balance=20000.0]]
    }
    
    // 查询总记录   查询account表中的所有记录数
    public static void queryTotalNum() {
    	// queryFoObject()
    	Integer count = jdbcTemplate.queryForObject("select count(*) from account", Integer.class);
    	System.out.println(count);// 4
    }
  • 相关阅读:
    echarts的整理
    socket.io做一个简单的聊天案例
    WebSocket通信随笔
    接口返回的二维码图片,如何处理显示(axios处理后台返回图片流格式数据)
    小程序封装request请求
    一站式解决Vue插件开发,上传Github,Npm包发布
    微信公众号链接处理问题
    git常用命令
    vscode 常用配置
    项目中报错Cannot read property 'getAttribute' of undefined解决
  • 原文地址:https://www.cnblogs.com/tushao/p/14248706.html
Copyright © 2011-2022 走看看