当前位置: 首页 > news >正文

数据库的元数据及事务

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

元数据、事务及手动添加事务、利用缓存进行批处理数据、利用Connection的重载的prepareStatemen()方法获取表的某些字段的值。


package test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import org.junit.Test;
import dao.EmpDao;
import entity.Emp;
import util.DBUtil;
----------------------------------------------------------------------------------------
元数据(MetaData)
    - 元:根本、本质
    - 元数据:数据的本质,数据的描述/概述
    - 用来描述数据的数据叫元数据

结果集元数据(ResultSetMetaData)
    - 用来描述结果集的数据
    - 如:返回的结果有几列、列名是什么、列的类型是什么

public class Test {
    
    /**
     * ResultSetMetData(了解)
     */
    @Test
    public void test(){
        Connection con = null;
        try {
            con = DBUtil.getConnection();
            String sql = "SELECT * FROM emp ";
            PreparedStatement ps = con.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            /*
             * 获取结果集元数据。
             * 元数据中存储了描述该结果集的信息。
             */
            ResultSetMetaData md = rs.getMetaData();
            System.out.println(md.getColumnCount());//字段数
            System.out.println(md.getColumnName(1));//第一列的字段名
            System.out.println(md.getColumnClassName(1));//第一列的字段类型
            
        } catch (SQLException e) {
            
            e.printStackTrace();
            throw new RuntimeException("查询员工失败!",e);
        }finally{
            DBUtil.close(con);
        }
    }
}
-----------------------------------------------------------------------------------------
事务:

什么叫事务?
满足如下特征的数据库访问叫事务:1. 原子性:事务是完整的,要么都成功,要么都失败。
                2. 一致性:事务前后的数据要保持一致,即收支平衡。
                3. 隔离性:事务过程中的数据不能被别人访问,需要受隔离/保护。

                 4. 持久性:事务一旦达成,就永久有效。

JDBC自动管理事务,当调用executeUpdate()时,JDBC会自动提交事务。

如何手动管理事务?
    con.setAutoCommit(false);//改为手动提交事务
    con.commit(); //提交
    con.rollback(); //回滚



public class Test {    
    /**
     * 模拟转账
     * 1.验证收款方账户是否存在。
     * 2.验证付款方账户余额是否充足。
     * 3.付款方账户减N元
     * 4.收款方账户加N元。
     */
    @Test
    public void test1(){
        //假设用户在atm上输入了如下信息:
        int padId = 1;//付款方账户
        int recId = 2;//收款方账号
        double mny = 1000.0;//转账金额
        
        Connection con = null;
        try {
            con = DBUtil.getConnection();
            
            //1.验证收款方账户是否存在。            
            String sql = "SELECT * FROM accounts "
                       + "WHERE id=?";
            PreparedStatement ps = con.prepareStatement(sql);
            ps.setInt(1, recId);
            ResultSet rs = ps.executeQuery();
            if(!rs.next()){
                System.out.println("收款账号不存在!");
                throw new SQLException("收款账号不存在!");
            }
            double recMoney = rs.getDouble("money");//记录收款方余额,便于之后转

账计算余额
            
            //2.验证付款方账户余额是否充足。
            sql = "SELECT * FROM accounts "
                + "WHERE id=? ";
            ps = con.prepareStatement(sql);
            ps.setInt(1, padId);
            rs = ps.executeQuery();
            rs.next();
            double payMoney = rs.getDouble("money");
            if(payMoney<mny){
                System.out.println("余额不足!");
                throw new SQLException("余额不足!");
            }            
            
            //设置手动管理事务(取消自动提交事务)
            con.setAutoCommit(false);
            
            //3.付款方账户减N元
            sql = "UPDATE accounts "
                    + "SET money=?"
                    + "WHERE id=?";
            ps = con.prepareStatement(sql);
            ps.setDouble(1, payMoney-mny);
            ps.setInt(2, padId);
            ps.executeUpdate();
            
            //假设此处有个错误!
            //Integer.valueOf("abc");
            
            //4.收款方账户加N元。
            sql = "UPDATE accounts "
                    + "SET money=? "
                    + "WHERE id=?";
            ps = con.prepareStatement(sql);
            ps.setDouble(1, recMoney+mny);
            ps.setInt(2, recId);
            ps.executeUpdate();

            //当账户转账流程正常结束时统一提交事物!
            con.commit();
        } catch (Exception e) {
            //当转账过程发生异常时回滚事物!
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
                throw new RuntimeException("回滚失败!");
            }
            e.printStackTrace();
            throw new RuntimeException("转账失败!",e);
        }finally{
            DBUtil.close(con);
        }        
    }
213438_OkA7_2708082.png 
    /**
     * 批量添加员工
     */
    @Test
    public void test2(){
        Connection con = null;
        try {
            con = DBUtil.getConnection();
            con.setAutoCommit(false);//取消自动提交事务
            
            //批量发送数据的前提是他们的SQL一样
            String sql = "INSERT INTO emp "
                    + "VALUES (seq_emp.nextval,?,?,?,?,?,?,?)";
            PreparedStatement ps = con.prepareStatement(sql);
            for(int i=1;i<=108;i++){
                ps.setString(1, "好汉"+i);
                ps.setString(2, "打劫");
                ps.setInt(3, 0);
                ps.setDate(4, null);
                ps.setDouble(5, 1000.0);
                ps.setDouble(6, 8000);
                ps.setInt(7, 3);
                
                //将本条数据暂存到ps内
                ps.addBatch();
                
                //每个n次批量发送一次数据
                if(i%30==0){
                    ps.executeBatch();
                    
                    //清除缓存的数据,便于下次发送
                    ps.clearBatch();
                }
            }
            //余下的数据单独发送一次
            ps.executeBatch();
            
            con.commit();
        } catch (SQLException e) {
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
                throw new RuntimeException("回滚失败!");
            }
            e.printStackTrace();
            throw new RuntimeException("批量添加员工失败!",e);
        }finally{
            DBUtil.close(con);
        }
    }
    
    /**
     * 添加部门,然后向此部门内添加员工
     */
    @Test
    public void test3(){
        //假设要添加的部门信息如下
        String dname = "财务";
        String loc = "北京";
        
        //假设要添加的员工数据如下
        String ename = "张三";
        String job = "经理";
        double sal = 6000;
        double comm = 546;
        
        String ename2 = "李四";
        String job2= "职员";
        double sal2 = 4000;
        double comm2 = 1546;
        
        Connection con = null;        
        try {
            con = DBUtil.getConnection();
            con.setAutoCommit(false);
            
            //先添加部门
            String sql = "INSERT INTO depts "
                    + "VALUES (seq_depts.nextval,?,?)";
            //参数2是一个数组,存的是希望被ps记住的字段的名称。
            PreparedStatement ps = con.prepareStatement(sql,new String[]
{"deptno","loc"});
            ps.setString(1, dname);
            ps.setString(2, loc);
            ps.executeUpdate();
            /*
             * 从ps中获取它之前记录的字段的值
             * 返回的结果集中只有一条数据,存的就是记录的那些字段的值
             * rs.getXXX(参数);中的参数代表你在数组中所填的第几个参数。
             */
            ResultSet rs = ps.getGeneratedKeys();
            rs.next();
            int deptno = rs.getInt(1);
            String dname3 = rs.getString(2);
            System.out.println(deptno);
            System.out.println(dname3);
            
            //添加员工1
            sql = "INSERT INTO emp "
                    + "VALUES (seq_emp.nextval,?,?,?,?,?,?,?)";
            ps = con.prepareStatement(sql);
            ps.setString(1, ename);
            ps.setString(2, job);
            ps.setInt(3, 0);
            ps.setDate(4, null);
            ps.setDouble(5,sal);
            ps.setDouble(6,comm);
            ps.setInt(7,deptno);
            ps.executeUpdate();
            //添加员工2
            sql = "INSERT INTO emp "
                    + "VALUES (seq_emp.nextval,?,?,?,?,?,?,?)";
            ps = con.prepareStatement(sql);
            ps.setString(1, ename2);
            ps.setString(2, job2);
            ps.setInt(3, 0);
            ps.setDate(4, null);
            ps.setDouble(5,sal2);
            ps.setDouble(6,comm2);
            ps.setInt(7,deptno);
            ps.executeUpdate();
                    
            con.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("添加部门员工信息失败!",e);
        }finally{
            DBUtil.close(con);
        }                
    }

转载于:https://my.oschina.net/langgege/blog/667824

相关文章:

  • WinForm输入网址打开源码
  • vector,map 注意事项
  • Atiti. Php Laravel 5.1 环境搭建以及  error 排除
  • tomcat配置文件server.xml详解
  • Nodejs和JavaWeb协助开发
  • JAVA 位操作学习
  • idea演示
  • F5 实现pool池转发
  • ie7下a/a标签不反应
  • MapReduce编程实例
  • iOS开发数据库篇—SQLite简单介绍
  • iOS开发拓展篇—音效的播放
  • 基于COOKIE的点击流数据仓库构建思路(一)
  • Tomcat热部署和虚拟目录配置
  • 被遗忘的Logrotate
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • FastReport在线报表设计器工作原理
  • Koa2 之文件上传下载
  • node和express搭建代理服务器(源码)
  • passportjs 源码分析
  • spring + angular 实现导出excel
  • vue2.0项目引入element-ui
  • XML已死 ?
  • 爱情 北京女病人
  • 安装python包到指定虚拟环境
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 前端攻城师
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 与 ConTeXt MkIV 官方文档的接驳
  • 阿里云服务器如何修改远程端口?
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • "无招胜有招"nbsp;史上最全的互…
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (4)logging(日志模块)
  • (C语言)逆序输出字符串
  • (Ruby)Ubuntu12.04安装Rails环境
  • (独孤九剑)--文件系统
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (汇总)os模块以及shutil模块对文件的操作
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .NET 8.0 中有哪些新的变化?
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .net 发送邮件
  • .NET 反射的使用
  • .NET的数据绑定
  • .Net小白的大学四年,内含面经
  • @Query中countQuery的介绍
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?