zoukankan      html  css  js  c++  java
  • MySQL--06

    一、PreparedStatement和Statement的区别

    1、PreparedStatement使用?占位符代替参数

    String sql  = "update users set name = ? where id = ?";

    预编译sql,然后设置结果

     public static void main(String[] args) {
    login("' or ' 1=1","123456");
    }

    public static void login(String username,String password){
    Connection conn = null;
    PreparedStatement stat = null;
    ResultSet rs = null;
    try {
    conn = utils.getConn();

    String sql = "select * from users where `name`=? and psw=?";
    stat = conn.prepareStatement(sql);
    stat.setString(1,username);
    stat.setString(2,password);
    rs = stat.executeQuery();
    if (rs.next()) {
    System.out.println("rs:" + rs.getObject("id")+" "+rs.getObject("name")+" "+rs.getObject("psw"));
    }

    } catch (SQLException e) {
    e.printStackTrace();
    }finally{
    utils.relax(conn,stat,null);
    }
    }
    }

    //此时就不会再出现sql注入问题,PreparedStatement把传递进来的参数当作字符,假设传递的参数中有转译字符就直接忽略
    //''会被直接转义

    PreparedStatement.set(1,"licunzhi");//意思就是第一个?设置值为“liucnzhi”

    PreparedStatement.set(2,"why");//第二个?设置值为why....以此类推

    二、使用JDBC执行事务

    package com.baidu.JDBC;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class TestUpdate {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement stat = null;
            ResultSet rs = null;
            try {
                conn = utils.getConn();
                //关闭自动提交  这里直接开启一个事务 不需要像数据库一样操作
                conn.setAutoCommit(false);
    
    
                String sql1 = "update account set money=money-100 where id=1";
                stat = conn.prepareStatement(sql1);
                stat.executeUpdate();
    
                String sql2 = "update account set money=money+100 where id=2";
                stat = conn.prepareStatement(sql2);
                stat.executeUpdate();
    
                //业务完毕 提交事务
                conn.commit();
                System.out.println("转账成功");
    
            } catch (SQLException e) {
                try {
                    //失败则回滚数据,不写也会自动回滚
                    conn.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }finally{
                utils.relax(conn,stat,null);
            }
        }
    }

    代码实现:

    1、开启事务

    2、一组业务执行完毕,提交事务

    3、可以再catch语句中i希纳是的定义回滚数据,但默认失败就会回滚

    三、数据库连接池

    常见的数据库连接池:

    DBCP C3P0  【Druid(德鲁伊)  阿里巴巴】

    池化技术:准备一些预先的资源,直接连接预先准备好的资源

    连接池可以自己手写,实现接口DataSource

    使用数据库连接池之后我们就不需要编写连接数据库的代码了

    1、dbcp

    首先将两个jar包导入程序中,add librarys

    接下来配置文件百度一个

    #连接设置
    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
    username=root
    password=space999
    
    #<!-- 初始化连接 -->
    initialSize=10
    
    #最大连接数量
    maxActive=50
    
    #<!-- 最大空闲连接 -->
    maxIdle=20
    
    #<!-- 最小空闲连接 -->
    minIdle=5
    
    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000
    
    #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
    #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
    connectionProperties=useUnicode=true;characterEncoding=gbk
    
    #指定由连接池所创建的连接的自动提交(auto-commit)状态。
    defaultAutoCommit=true
    
    #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
    #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_UNCOMMITTED

    接下来工具类,省去了读取配置文件每个字段的步骤

    package space.bilibili.com;
    
    import org.apache.commons.dbcp.BasicDataSource;
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;
    
    public class Jdbc_Utils {
        private static Connection conn = null;
        private static DataSource dataSource = null;
        static{
            try{
                //将配置文件放入流中
                InputStream in = Jdbc_Utils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
                //加载读取配置文件的类
                Properties properties = new Properties();
                //加载流中的配置文件
                properties.load(in);
    
                dataSource = BasicDataSourceFactory.createDataSource(properties);
                conn = dataSource.getConnection();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //获取连接
        public static Connection getConn() throws SQLException {
            return dataSource.getConnection();
        }
        //释放资源
        public static void release(Connection conn,Statement stat,ResultSet rs){
            if(rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(stat!=null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    接下来就是测试插入代码:

    package space.bilibili.com;
    
    import space.urbeautiful.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    public class TestInsert {
    
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement stat = null;
            ResultSet rs = null;
            try {
                conn = Jdbc_Utils.getConn();
                String sql = "insert into account(id,`name`,money) values(5,'why',20000)";
                stat = conn.prepareStatement(sql);
                int i = stat.executeUpdate();
                if(i>0){
                    System.out.println("插入成功");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                JdbcUtils.release(conn,stat,rs);
            }
        }
    }

    2、C3P0

  • 相关阅读:
    如何基于日志,同步实现数据的一致性和实时抽取?
    实例解说AngularJS在自动化测试中的应用
    漏洞管理平台『洞察』部署指南
    UAVStack的慢SQL数据库监控功能及其实现
    淡说Linux 的发展史
    一张图告诉你E-R图怎么画
    一张图告诉你UML图怎么画❀
    最简单,最明了,看了就会的VScode和C++的配置!(Visual Studio Code)
    用Eclipse开发项目,你不能不知道的快捷键
    什么年代了,你还不会用油猴刷网课!
  • 原文地址:https://www.cnblogs.com/jzspace/p/13055149.html
Copyright © 2011-2022 走看看