JDBC知识点

JDBC

JDBC驱动程序

数据库配置信息

url:连接数据库系统资源描述符 jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8

DriverClass:数据库系统驱动名称

UserName:数据库系统用户名称

PassWord:登录数据库系统用户密码

others:其他信息

## 数据库属性配置信息
## 连接数据库服务器URL
jdbc_url = jdbc:mysql://localhost:3306/ATMSYSTEM?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
## 连接数据库服务器驱动类
jdbc_driver = com.mysql.jdbc.Driver
## 访问数据库服务器用户名称
jdbc_UserName = root
## 访问数据库服务器用户密码
jdbc_PassWord = 123456

步骤

  1. 加载驱动 Class.forName(“com.mysql.jdbc.Driver”);
  2. 连接数据库 DriverManger.getConnection(); 返回Connection对象
  3. 执行SQL对象 调用createStatement() 返回Statement对象
  4. 调用executeQuery(sql) 执行sql语句
  try {
            Class.forName("com.mysql.cj.jdbc.Driver"); //加载驱动
            String url = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"; 
            Connection  connection = DriverManager.getConnection(url,"root","123456");
            Statement statement = connection.createStatement();
            String sql = "select  * from meet ";
            ResultSet execute = statement.executeQuery(sql);
            while (execute.next()){
                System.out.print(execute.getString(1)+"\t");
                System.out.print(execute.getString(2)+"\t");
                System.out.print(execute.getString(3)+"\t");
                System.out.println(execute.getString(4));
            }
            connection.close();
            statement.close();
            execute.close();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

具体步骤

  1. 创建dbconf.properties文件

    ## 数据库属性配置信息
    ## 连接数据库服务器URL
    jdbc_url = jdbc:mysql://localhost:3306/(要访问的数据库名)?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
    ## 连接数据库服务器驱动类
    jdbc_driver = com.mysql.jdbc.Driver
    ## 访问数据库服务器用户名称
    jdbc_UserName = root
    ## 访问数据库服务器用户密码
    jdbc_PassWord = 123456
    
  2. 创建Env获取dbconf.properties文件中的属性并设置为静态常量

  3. 创建数据库管理类,统一管理规范

    getConnection()

    执行sql语句

      Statement statement = connection.createStatement();
      String sql = "select  * from meet ";
      ResultSet execute = statement.executeQuery(sql);
    

查询结果集处理

java,sql.ResultSet 接口是jdbcAPI中唯一用来封装查询结果记录行的组件

遍历结果集中的数据

  1. boolean next() 方法 往往做为遍历循环的条件

  2. getXxx( int index); getXxx(String colum)

     ResultSet execute = statement.executeQuery(sql);
                while (execute.next()){
                    System.out.print(execute.getString(1)+"\t");
                    System.out.print(execute.getString(2)+"\t");
                    System.out.print(execute.getString(3)+"\t");
                     System.out.print(execute.getString("name")+"\t");
                    System.out.println(execute.getString(4));
                }
    
  3. 封装结果集(使用集合封装)

    List<Student>  students = new ArrayList();
    while (resultSet.next()){
        Student stu = new Stundent();
        String id = resultSet.getString("id");
        stu.setId(id);
        stu.setName(resultSet.getString("name"));
        students.add(stu);
    }
    

    使用map封装

    List<Student>  students = new ArrayList();
    while (resultSet.next()){
    	Map map =  new HashMap();
        Student stu = new Stundent();
        String id = resultSet.getString("id");
        stu.setId(id);
        stu.setName(resultSet.getString("name"));
        map.put("学生",stu);
        students.add(map);
    }
    

数据库连接池

  1. 添加jar包

  2. 设置 private static ComboPooledDataSource c3p0; //声明数据池对象

  3. 设置数据源相关属性

    private static ComboPooledDataSource c3p0;   //声明数据池对象
        /**
         * 创建组合池数据源
         */
        private static void createComboPooledDataSource() {
            //判断c3p0数据池是否为空   为空则创建
            if (c3p0 == null) {
                c3p0 = new ComboPooledDataSource();
                //为c3p0属性赋值
                try {
                    c3p0.setJdbcUrl(Configuration.JDBC_URL);
                    c3p0.setDriverClass(Configuration.JDBC_DRIVER);
                    c3p0.setUser(Configuration.JDBC_USENAME);
                    c3p0.setPassword(Configuration.JDBC_PASSWORD);
                    c3p0.setCheckoutTimeout(5000);
                } catch (PropertyVetoException e) {
                    e.printStackTrace();
                }
            }
        }
    
    /**
         * 获得连接
         *
         * @return {@link Connection}
         */
        public static Connection getConnection() {
            Connection connection = null;
            createComboPooledDataSource();   //创建数据源
            try {
                connection = c3p0.getConnection(); //由数据源获取一个打开的链接
    
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            return connection;
        }
    
    
    /**
         * 关闭数据库连接的重载方法
         */
        public static void close(Connection connection) {
            try {
                if (connection != null && !connection.isClosed()) {
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    
        public static void close(ResultSet resultSet) {
            try {
                if (resultSet != null && !resultSet.isClosed()) {
                    resultSet.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    
        public static void close(Statement statement) {
            try {
                if (statement != null && !statement.isClosed()) {
                    statement.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            Connection connection = getConnection();
            if (connection != null ){
                System.out.println("12345");
            }
        }
    }
    

PreparedStatement 是Statement接口的扩展

PreparedStatement 更高效

提供预编译功能,提高数据库访问效率

支持使用占位符设置sql语句参数

此接口对象由Connection调用相关方法创建

设置参数

  • setXxx(int index ,Object value)
 @Override
    public AccountInfo validateAccountInfo(String cardNumber) {
        String sql = "SELECT ID,ACCOUNT,ACCOUNT_TYPE,BALANCE,TODAY_OUT_MAX,"
                + "TODAY_TA_MAX,BANKID,FROZEN,LOCATION "
                + "FROM ACCOUNT_INFO WHERE ACCOUNT = ?";
        AccountInfo account = null;
        Connection connection = null;
        ResultSet resultSet = null;
        PreparedStatement ps = null;
        try {
            connection = DataSourcePool.getConnection();
            ps = connection.prepareStatement(sql);
            ps.setString(1, cardNumber);
            resultSet = ps.executeQuery();  //返回结果集
            while (resultSet.next()) {
                //String  date = new SimpleFormatter("yyyy-MM-dd").format(resultSet.getTime("CREATETIME"));
                account = new AccountInfo(); //创建新的AccountInfo对象  并给对象赋值
                account.setId(resultSet.getString("id"));
                account.setAccount(resultSet.getString("ACCOUNT"));
                account.setAccountType(resultSet.getInt("ACCOUNT_TYPE"));
                account.setBalance(resultSet.getBigDecimal("BALANCE"));
                account.setTodayOutMax(resultSet.getBigDecimal("TODAY_OUT_MAX"));
                account.setTodayTaMax(resultSet.getBigDecimal("TODAY_TA_MAX"));
                account.setBankId(resultSet.getString("BANKID"));
                account.setFrozen(resultSet.getInt("FROZEN"));
                account.setLocation(resultSet.getString("LOCATION"));
                //account.setCreateTime(resultSet.getTime("CREATETIME"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            DataSourcePool.close(ps);
            DataSourcePool.close(resultSet);
            DataSourcePool.close(connection);
        }
        return account;  //返回创建的对象
    }

查询分页

由于数据庞大,全部加载到内存比较耗时,效率低下

  1. sql语句实现分页

    1.limit用法
    	limit出现在查询语句最后,可以使用一个参数或两个参数来限制取出的数据,
    	 中第一个参数代表偏移量:offset(可选参数)
    	 第二个参数代表取出的数据条数:rows
    
    单参用法
    当指定一个参数时,默认省略了偏移量,及偏移量为0.从第一行开始取数据,一共取rows行
    /* 查询前五条数据 */
    select * from student limit 5;
    
    双参数用法
    当指定两个参数时,需要注意偏移量的取值是从0开始的,此时有两种写法
    	/* 查询第1-10条数据 */
    	select * from student limit 0,10;
    	/* 查询第11-20条数据 */
    	select * from student limit 10,0;
    	
    2. 分页公式
    总页数计算
    在进行计算之前,我们需要先根据数据总量来得出总页数,这需要用到count函数和向上取整函数ceil
    sql如下:
    /*  获取总条数 */
    select count(*) from student
    /* 假设每页显示10条,则直接进行除法运算,然后向上取整 */
    select ceil(count(*)) as pageTotal  from  student
    
    核心信息
    当前页:pageNumber
    每页数量:pageSize
    在实际操作中,我们能够得到的信息有当前所在也以及每页的数据量,同时要注意一下是否超出了最大页数,以每页10条为例,则前三页的数据应为:
    第一页:第1~10条, limit 0,10
    第二页:第11~20条, limit 10,10
    第三页:第21~30条,limit 20,10
    据此我们可以总结出,limit所需要的两个参数计算公式如下
    offset:(pageNumber-1)*pageSize
    rows:pageSize
    

    分页代码实现

    public Map findSalaryPaging(int pageNum, int pageSize){
        //计算符合查询条件的总记录数rowCount
        //计算分页总数pageSum
        //当前页记录行数rows
        //返回客户端需要的数据(rowCount,pageSum,rows)
    }
    使用map封装查询信息
    
    

JDBC调用存储过程

jdbc调用存储过程实现

优点:执行效率高,提高访问速度

缺点:更换数据库系统时存储过程不兼容

JDBC API 中CallableStatement 接口是唯一处理数据库系统存储过程的通用组件

CallableStatement 接口

方法名称作用说明
getXxxx(int index)以索引的方式获取参数值
getXxx(String pName)以参数名称的方式获取参数值
setXxx(int index,XXX o)将数据o按照参数索引位置设置成参数值
setXxx(String n,xxx o)将数据o按照参数名称设置成参数值
registerOutParameter(int i,Types)按照参数索引设置返回类型参数的类型
registerOutParameter(String n,Types)按照参数名称设置返回类型参数的类型
execute( )执行调用存储过程并返回boolean值
executeUpdate()执行调用存储过程并返回int值
//定义存储过程名及参数
String  proName ={call pro_hello(?)};

//注册一个输出类型
call.regidteroutParameter(1,Types.varchar);
    public String callProcedure(String name) {
        String procName = "{call pro_hello(?)}";   //定义调用的存储过程及参数
        Connection connection = DataSourceForPool.getConnection();
        CallableStatement callableStatement = null;
        try {
            callableStatement = connection.prepareCall(procName);//创建CallableStatement对象
            callableStatement.registerOutParameter(1, Types.VARCHAR);//注册一个输出类型
            callableStatement.setString(1, name);
            callableStatement.execute();//调用存储过程
            name = callableStatement.getString(1);
        } catch (Exception e) {
            e.getMessage();
        }

        return null;
    }

批处理

批处理是指一次连接访问数据中发送一组SQL操作语句,通常对数据库多条数据进行更新操作。

合理使用批处理能够在最少次访问数据库时执行多条SQL操作从而提高数据库的访问速度并提高数据库的应用效率

一般情况下批处理执行类似相近的操作,如批量修改,批量删除,批量插入等

Statement接口批处理方法

void addBatch(String sql) throws SQLException

int [] executeBatch() throws SQLException

void clearCatch() throws SQLException

void addBatch() throws SQLException

JDBC事务处理

Connection事务处理相关方法

void setAutommit(boolean autoCommit)  // 传入true则自动提交  false 关闭自动提交
    
void  commit(); //提交事务

void  rollback(); //撤销  出现异常 ,异常处理中回滚数据

SavepointsetSavepointString  name)  //保存点
    
void  setTransaction(int level);/设置事务与其他事务的隔离级别
    
void  rollback(Savepoint SavePoint

Timestamp time = new Times(new Date().getTime()); //获取系统时间

事务的隔离级别

  • TRANSACTION_NONE 不支持事务
  • TRANSACTION_READ_COMMITTED 禁止脏读和不可重复读,允许虚读(默认)
  • TRANSACTION_READ_UNCOMMITTED 允许脏读,不可重复读和虚读
  • TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读;允许虚读
  • TRANSACTION_SERIALIZABLE 禁止脏读,不可重复读和虚读
    public int withdrawMoney(String accountID, BigDecimal amount, double serviceCharge) {
        int res = 0;
        /**
         * 更新账户余额
         */
        String sql0 = " update account_info  set BALANCE = (BALANCE -?-?) where account = ?";
        /**
         * 添加交易记录
         */
        String sql2 = " insert into  BUSINESS (ID,ACCOUNTID,BUSID,AMOUNT ,"
                + "POUNDAGE,BUSINESS_TIME,DESCRIPTION) "
                + "VALUES(?,?,?,?,?,NOW(),?)";
        /**
         *  更新ATM余额SQL         */
        String sql3 = "UPDATE ATM SET TOTAL = TOTAL - ? WHERE ID = ?";

        Connection conn = null;
        PreparedStatement ps = null;
        PreparedStatement ps2 = null;
        PreparedStatement ps3 = null;
        try {
            conn = DataSourcePool.getConnection();

            //更新账户余额
            conn.setAutoCommit(false);// 关闭自动提交
            ps = conn.prepareStatement(sql0);
            ps.setBigDecimal(1, amount);
            ps.setDouble(2, serviceCharge);
            ps.setString(3, accountID);
            res += ps.executeUpdate();

            //添加交易记录
            ps2 = conn.prepareStatement(sql2);
            ps2.setString(1, UUID.randomUUID().toString());//生成唯一识别码
            ps2.setString(2, Application.atmSys.getAccount().getId());//插入AccountId
            ps2.setString(3, "001");//执行的什么操作 (取钱)
            ps2.setBigDecimal(4, amount);//交易金额
            ps2.setDouble(5, serviceCharge);//交易手续费用
            ps2.setString(6, "ATM 取款");
            res += ps2.executeUpdate();

            //更新ATM余额
            ps3 = conn.prepareStatement(sql3);
            ps3.setBigDecimal(1, amount);
            ps3.setString(2, Application.atmSys.getId());
            res += ps3.executeUpdate();
            conn.commit();// 提交事务

        } catch (Exception e) {
            try {
                System.out.println("撤销事务");
                conn.rollback(); // 撤销事务操作
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            DataSourcePool.close(ps);
            DataSourcePool.close(ps2);
            DataSourcePool.close(conn);
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小郑在努力ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值