JDBC

一 JDBC概述

Java提供的一套用来操作数据库的接口

二 如何获取数据库的连接

1.获取数据库连接的必要条件

/*
1.保证mysql的服务是正常运行的
2.保证mysql的账号密码是对的
3.保证mysql的驱动版本是可以使用的
*/

2.方式一:Driver

     //多态
        Driver driver = new com.mysql.jdbc.Driver();
        /*
        connect(String url, Properties info)
        url : mysql数据的地址
            jdbc:mysql://localhost:3306/atguigu
            jdbc:mysql: 协议
            localhost :mysql所在服务器的地址(ip地址)
            3306 :端口号
            atguigu :库名
​
        info : 存储了用户名和密码的集合(Properties)
         */
        String url = "jdbc:mysql://localhost:3306/myemployees";
        Properties properties = new Properties();
        //注意:key的值是死的不能乱写
        properties.setProperty("user","root");//mysql账号
        properties.setProperty("password","123321");//mysql密码
​
        Connection connection = driver.connect(url,properties);
        System.out.println(connection);

3.方式二:DriverManager

      //1.创建Driver对象
        Driver driver = new com.mysql.jdbc.Driver();
        //2.注册Driver
        DriverManager.registerDriver(driver);
        //3.通过DriverManager获取连接对象
        /*
        getConnection(String url,String user, String password)
        url:mysql的连接地址
        user:mysql的账户
        password:mysql的密码
         */
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myemployees",
                "root", "123321");
​
        System.out.println(connection);
           //1.让com.mysql.jdbc.Driver类进行类加载
        Class.forName("com.mysql.jdbc.Driver");
        //2.通过DriverManager获取连接对象
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myemployees",
                "root", "123321");
        System.out.println(connection);

4.方式三:读取配置文件

配置文件:jdbc.properties

username=root
password=123321
url=jdbc:mysql://localhost:3306/myemployees
driverClass=com.mysql.jdbc.Driver  

代码

     String url = "";
        String username="";
        String password="";
        String driverClass="";
​
​
        //通过读取配置文件中的内容赋值
        //1.创建Properites对象
        Properties properties = new Properties();
        //2.创建流
        FileInputStream fis = new FileInputStream("jdbc.properties");
        //3.加载流
        properties.load(fis);
        //4.读取配置文件中的内容
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
        driverClass = properties.getProperty("driverClass");
        //5.关闭资源
        if (fis != null){
            fis.close();
        }
​
        Class.forName(driverClass);
        Connection connection = DriverManager.getConnection(url,
                username, password);
        System.out.println(connection);

5.Properites

/*
    Properties:
        说明:
            1.Properties的父类中Hashtable
            2.Properties的K,V类型是String
            3.可以通过Properties读取配置文件中的内容。
 */
public class PropertiesDemo {
    /*
        通过Properties读取配置文件中的内容
     */
    @Test
    public void test() throws IOException {
        //1.创建Properties的对象
        Properties properties = new Properties();
        //2.加载流
        FileInputStream fis = new FileInputStream("jdbc.properties");
        properties.load(fis);
        //3.读取配置文件中的内容
        String username = properties.getProperty("username");
        System.out.println("username=" + username);
        //4.关资源
        if (fis != null){
            fis.close();
        }
    }
}

三 对数据库增删改查操作

/*
    通过JDBC对数据进行增,删,改,查的操作
​
    CREATE TABLE stu(
        id INT,
        NAME VARCHAR(20)
    )
 */
public class CRUDDemo {
    /*
        查询
     */
    @Test
    public void test4() throws Exception {
        List<Stu> stu = getStu();
        for (Stu s : stu) {
            System.out.println(s);
        }
    }
    /*
        获取stu中所有的数据
     */
    public List<Stu> getStu() throws Exception {
        //1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        PreparedStatement ps = connection.prepareStatement("select id,name from stu where id=?");
​
        ps.setInt(1,1);
​
        //3.执行sql语句
        ResultSet resultSet = ps.executeQuery();//查询语句使用该方法返回一个结果集
​
        List<Stu> list = new ArrayList<Stu>();
​
        //4.遍历
        while(resultSet.next()){//resultSet.next() :是否有下一条数据。
            /*
                 getInt(int columnIndex) :根据字段的位置获取数据
                 getInt(String columnLabel) :根据字段的名字获取数据
             */
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            //一条数据就是一个对象
            Stu stu = new Stu(id, name);
            //将对象存放到集合中
            list.add(stu);
        }
        //5.关闭资源
        JDBCUtils.close(connection,ps,resultSet);
​
        //6.返回集合对象(集合中都是数据的对象)
        return list;
    }
    /*
        插入的操作
     */
    @Test
    public void test() throws SQLException {
        //1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        String sql = "insert into stu(id,name) values(?,?)"; // ?:占位符
        PreparedStatement ps = connection.prepareStatement(sql);
        //3.给占位符赋值
        /*
            setInt(int parameterIndex, int x)
            parameterIndex : 占位符的索引位置
            x : 赋值的数据
         */
        ps.setInt(1,1);
        ps.setString(2,"abc");
        //4.执行sql
        //该方法可以执行增,删,改三种sql语句。返回值:有几条数据受到影响
        int i = ps.executeUpdate();
        System.out.println("有" + i + "条数据受到影响");
        //5.关闭资源
        JDBCUtils.close(connection,ps);
    }
​
    /*
        修改的操作
     */
    @Test
    public void test2() throws SQLException {
        //1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        String sql = "update stu set name=? where id=?";
        PreparedStatement ps = connection.prepareStatement(sql);
        //3.给占位符赋值
        ps.setInt(2,1);
        ps.setString(1,"aaa");
        //4.执行sql
        int i = ps.executeUpdate();
        System.out.println("有" + i + "条数据受到影响");
        //5.关闭资源
        JDBCUtils.close(connection,ps);
    }
​
    /*
        删除数据
     */
    @Test
    public void test3() throws SQLException {
        //1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        PreparedStatement ps = connection.prepareStatement("delete from stu");
        //3.给占位符赋值
        //4.执行sql
        int i = ps.executeUpdate();
        System.out.println("有" + i + "条数据受到影响");
        //5.关闭资源
        JDBCUtils.close(connection,ps);
    }
}

四 SQL注入

     Scanner scan = new Scanner(System.in);
        System.out.print("用户名:");
        String userName = scan.nextLine();
        System.out.print("密 码:");
        String password = scan.nextLine();
​
        //SELECT id,name FROM emp WHERE id='12332' OR 1='1' AND name='123321' OR 1='1'
        String sql = "select id,name from emp where id = '"
                + userName + "' and name = '" + password + "'";
​
        System.out.println(sql);
​
        Connection connection = JDBCUtils.getConnection();
        Statement statement = connection.createStatement();
        //执行sql语句
        ResultSet rs = statement.executeQuery(sql);
        while(rs.next()){
            System.out.println(rs.getString("id"));
            System.out.println(rs.getString("name"));
        }
        //关闭资源
        rs.close();
        connection.close();

五 批处理

1.注意

1.mysql驱动包的版本必须是5.1.3x 才支持批处理
2.mysql的连接:
            jdbc:mysql://localhost:3306/库名?rewriteBatchedStatements=true

2.调用方法

//将数据添加到批处理中
addBatch()
//执行批处理操作
executeBatch()
//清理批处理
cleanBatch()

3.代码

 //1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        //2.预编译
        String sql = "insert into account(balance,name) values(?,?)";
        PreparedStatement ps = connection.prepareStatement(sql);
        //3.赋值
        for (int i = 1; i <= 100000 ; i++) {
            ps.setInt(1,i);
            ps.setString(2,"aa" + i);
            //将数据添加到批处理中
            ps.addBatch();
​
            if (i % 1000 ==0) {
                //4.执行sql
                ps.executeBatch();
                //5.清空批处理
                ps.clearBatch();
            }
        }
        //6.关闭资源
        JDBCUtils.close(connection,ps);

六 事务

1.事务的案例

 aa给bb转账1000

aa -= 1000
System.out.println(1/0);
bb += 1000

注意:上面的操作可能会导致有的成功有的失败。

2.事务代码

//1.获取连接对象
        Connection connection = JDBCUtils.getConnection();
        try {
            //禁止自动提交
            connection.setAutoCommit(false);
​
            //2.预编译
            String sql = "update account set balance=? where name=?";
            PreparedStatement ps = connection.prepareStatement(sql);
            //3.给占位符赋值
            ps.setInt(1,1000);
            ps.setString(2,"aa");
            //4.执行sql
            ps.executeUpdate();
​
            //System.out.println(1/0);
//5.给占位符赋值
            ps.setInt(1,3000);
            ps.setString(2,"bb");
            //6.执行sql
            ps.executeUpdate();
​
            //事务提交
            connection.commit();
        }catch (Exception e){
            e.printStackTrace();
            //事务回滚
            try {
                connection.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }finally {
            //允许自动提交
            try {
                connection.setAutoCommit(true);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

七 连接池

1、什么是数据库连池

连接对象的缓冲区。负责申请,分配管理,释放连接的操作。

2、为什么要使用数据库连接池

通过DriverManager获取新连接,用完直接抛弃断开,连接的利用率太低,太浪费。
对于数据库服务器来说,压力太大。

3、阿里的德鲁伊连接池技术

3.1在代码中配置

//创建DruidDataSource类的对象
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/myemployees");//设置mysql连接的地址
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");//设置Driver类的全类名
        dataSource.setUsername("root");//设置登录mysql的账号
        dataSource.setPassword("123321");//设置登录mysql的密码
//获取连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);

3.2通过配置置文件进行配置

/*
url=jdbc:mysql://localhost:3306/myemployees
username=root
password=123321
driverClassName=com.mysql.jdbc.Driver
*/
​
        Properties properties = new Properties();
        properties.load(this.getClass().getClassLoader().
                getResourceAsStream("druid.properties"));
        //通过Druid工厂类创建DataSource对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        //获取连接
        System.out.println(dataSource.getConnection());

八 JDBCUtils

1.配置文件内容

username=root
password=123321
url=jdbc:mysql://localhost:3306/myemployees?rewriteBatchedStatements=true
driverClass=com.mysql.jdbc.Driver

2.代码

public class JDBCUtils {
    //1.获取数据库连接对象
    private static String url;
    private static String username;
    private static String password;
    private static String driverClass;
​
    static {
        FileInputStream fis = null;
        try {
            //通过读取配置文件中的内容赋值
            //1.创建Properites对象
            Properties properties = new Properties();
            //2.创建流
            fis = new FileInputStream("jdbc.properties");
            //3.加载流
            properties.load(fis);
            //4.读取配置文件中的内容
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            driverClass = properties.getProperty("driverClass");
        }catch (Exception e){
            e.printStackTrace();
            //将编译时译常转换为运行时异常
            throw new RuntimeException("XXXXXXX");
        }finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
​
    /*
        获取连接对象
     */
    public static Connection getConnection(){
        try {
            Class.forName(driverClass);
            Connection connection = DriverManager.getConnection(url,
                    username, password);
            return connection;
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("获取连接失败");
        }
    }
​
    /*
        关闭资源
     */
    public static void close(Connection connection, PreparedStatement ps) {
        if (connection != null){
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
​
        if (ps != null){
            try {
                ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
​
    public static void close(Connection connection, PreparedStatement ps, ResultSet resultSet) {
        close(connection,ps);
        if (resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

九 DBUtils

 /*
    通过DBUtils工具类去实现增,删,改,查的功能
 */
public class DBUitlsDemo {
    /*
        查询数据
     */
    @Test
    public void test4() throws SQLException {
        QueryRunner qr = new QueryRunner();
        /*
        query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
        conn :连接对象
        sql : sql语句
        rsh :ResultSetHandler接口的实现类
            BeanHandler:把结果集转为一个 Bean
            BeanListHandler:把结果集转为一个 Bean 的集合
        params :给占位符赋值的数据
         */
//        Stu stu = qr.query(JDBCUtils.getConnection(), "select id,name from stu where id=?",
//                new BeanHandler<Stu>(Stu.class), 1);
        //如果JavaBean中的属性名和表中的字段名不一样可以采用别名的方式解决该问题。
        List<Stu> list = qr.query(JDBCUtils.getConnection(), "select id sid,name from stu",
                new BeanListHandler<Stu>(Stu.class));
​
        for (Stu s : list) {
            System.out.println(s);
        }
    }
​
    /*
        添加
     */
    @Test
    public void test() throws SQLException {
        //1.创建QueryRunner的对象
        QueryRunner qr = new QueryRunner();
        /*
            update(Connection conn, String sql, Object... params)
            conn : 连接对象
            sql : sql语句
            params : 给占位符赋值的内容
         */
        String sql = "insert into stu(id,name) values(?,?)";
        int i = qr.update(JDBCUtils.getConnection(), sql, 4, "kk");
        System.out.println("有" + i + "条数据受到影响");
    }
​
    /*
        修改
     */
    @Test
    public void test2() throws SQLException {
        //1.创建QueryRunner的对象
        QueryRunner qr = new QueryRunner();
        String sql = "update stu set name=? where id=?";
        int i = qr.update(JDBCUtils.getConnection(), sql, "jj", 4);
        System.out.println("有" + i + "条数据受到影响");
    }
    /*
        删除
     */
    @Test
    public void test3() throws SQLException {
        //1.创建QueryRunner的对象
        QueryRunner qr = new QueryRunner();
        String sql = "delete from stu where id=?";
        int i = qr.update(JDBCUtils.getConnection(), sql, 4);
        System.out.println("有" + i + "条数据受到影响");
    }
}

十 BasicDAO

/*
    对DBUtils中的方法进行二次封装
 */
public class BasicDAO<T> {
​
    public List<T> query(Connection connection,String sql,Class clazz,Object...params){
        try {
            QueryRunner qr = new QueryRunner();
            List<T> list = qr.query(connection, sql,
                    new BeanListHandler<T>(clazz),params);
            return list;
        }catch (Exception e){
            throw new RuntimeException("xxxxx");
        }
    }
​
    public void update(Connection connection,String sql,Object...params){
        try {
            //1.创建QueryRunner的对象
            QueryRunner qr = new QueryRunner();
            int i = qr.update(JDBCUtils.getConnection(), sql, params);
            System.out.println("有" + i + "条数据受到影响");
        }catch (Exception e){
            throw new RuntimeException("xxxx");
        }
    }
​
}
原文地址:https://www.cnblogs.com/LzMingYueShanPao/p/14598210.html