JDBC操作

JDBC概念

什么是jdbc
(1)Java Database Connectivity,java数据库连接
(2)java里面针对操作数据库,提供一套规范,好比是一些接口,比如操作mysql数据库,mysql提供这些接口实现类
(3)jdbc是java操作数据库一套规范(接口),由具体数据库提供这些规范实现,以jar包形式提供
在这里插入图片描述
在这里插入图片描述

基础操作 增删改查和连接

public class JDBCDemo1 {
    @Test
    //遍历数据库中的数据
    public void testSelect(){
        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
         connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");
        String sql="select id,name from worker";
             statement=connection.createStatement();
             resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                int id=resultSet.getInt("id");
                String name = resultSet.getString("name");
                System.out.println(id+"   "+name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
        @Test
        //添加数据进入数据库
    public void testadd(){
            try {
                Class.forName("com.mysql.jdbc.Driver");
                Connection conn=DriverManager.getConnection("jdbc:mysql:///db1","root","root");
                String sql="INSERT INTO worker VALUES(NULL,'梁昕','女',500,NULL,3)";
                Statement statement=conn.createStatement();
                int i = statement.executeUpdate(sql);
                System.out.println(i);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
            @Test
            //删除数据库中的数据
            public void testdelete(){
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    Connection conn=DriverManager.getConnection("jdbc:mysql:///db1","root","root");
                    Statement statement = conn.createStatement();
                    String sql="delete from worker where name='达到'";
                    int i = statement.executeUpdate(sql);
                    System.out.println(i);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Test
            //修改数据库中的数据
            public void testupdate(){
            //其实反射来进行驱动,也可以不进行,因为在connection里面的静态代码块中 会有初始化
                try {
                    Connection connection=DriverManager.getConnection("jdbc:mysql:///db1","root","root");
                    Statement statement = connection.createStatement();
                    String sql="update worker set id=6 where name='刘嘉明'";//UPDATE worker SET id=7 WHERE NAME='刘嘉明'
                    int i = statement.executeUpdate(sql);
                    System.out.println(i);
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
}

Statement对象

Statement对象主要作用执行sql语句的

Statement对象缺点

  1. sql语句拼接
 String dname = "安保部";
        String sql1 = "select * from dept where dname='安保部'";
        String sql = "select * from dept where dname='"+dname+"'";
  1. sql注入问题:把输入值作为sql语句关键字执行了
  2. 不能处理Blob类型数据:Blob类型是二进制类型,使用Statement不能操作二进制类型数据

preparedstatement

为了解决上面statement的缺点,然后引入了preparedstatement

 @Test //验证是否有这条信息的存在,并输出
    public void test1(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn= DriverManager.getConnection("jdbc:mysql:///db1","root","root");
            String sql="select *from worker where id=? and name=?";
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            preparedStatement.setInt(1,2);
            preparedStatement.setString(2,"杨帆");
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                int id=resultSet.getInt("id");
                String name=resultSet.getString("name");
                System.out.println(id+"         "+name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 String sql = "insert into dept values(?,?)";
        //创建预编译对象
        preparedStatement = conn.prepareStatement(sql);
        //设置值
        preparedStatement.setInt(1,100);
        preparedStatement.setString(2,"互动部");
        //执行sql
        int row = preparedStatement.executeUpdate();

PreparedStatement获取自动增长的值

创建表,表id是主键,自动增长

//获取自动增长id值
 @Test
 public void test01() {
     Connection conn = null;
     PreparedStatement preparedStatement = null;
     try {
         Class.forName("com.mysql.jdbc.Driver");
         conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");

         //编写sql语句
         String sql = "insert into book values(null,?,?)";
         //创建预编译对象
         preparedStatement = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
         //设置值
         preparedStatement.setString(1,"上下五千年");
         preparedStatement.setString(2,"无名氏");
         //执行
         preparedStatement.executeUpdate();

         //获取添加之后自动增长id值
         ResultSet rs = preparedStatement.getGeneratedKeys();
         while(rs.next()) {
             Object id = rs.getObject(1);
             System.out.println(id);
         }
     } catch (Exception e) {
         e.printStackTrace();
     } finally {
         try {
             preparedStatement.close();
             conn.close();
         } catch (SQLException e) {
             e.printStackTrace();
         }
     }
 }

批处理操作

//批处理向表添加10条记录
@Test
public void test03() {
    Connection conn = null;
    PreparedStatement preparedStatement = null;
    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");

        //编写sql语句
        String sql = "insert into book values(null,?,?)";
        //创建预编译对象
        preparedStatement = conn.prepareStatement(sql);

        //循环10次
        for (int i = 1; i <=10; i++) {
            preparedStatement.setString(1,"上下五千年2"+i);
            preparedStatement.setString(2,"无名氏2"+i);

            //把每次添加数据放到批处理对象
            preparedStatement.addBatch();
        }

        //把批处理数据执行添加
        preparedStatement.executeBatch();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            preparedStatement.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

事务操作

//事务操作
@Test
public void test04() {
    Connection conn = null;
    PreparedStatement preparedStatement = null;
    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");

        //1 开启事务(让事务不是自动提交)
        conn.setAutoCommit(false);

        //2 具体操作 
        //编写sql语句
        String sql = "insert into book values(null,?,?)";
        //创建预编译对象
        preparedStatement = conn.prepareStatement(sql);
        preparedStatement.setString(1,"世界旅游");
        preparedStatement.setString(2,"无名氏");
        preparedStatement.executeUpdate();
        
        //3 事务结束 回滚和提交
        conn.commit();
    } catch (Exception e) {
        e.printStackTrace();
        //事务回滚
        try {
            conn.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
    } finally {
        try {
            preparedStatement.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

数据库连接池

在这里插入图片描述
使用连接池,可以自己创建连接池,实现DataSource接口就可以了,但是实际操作中,一般不去自己实现,使用开源连接池进行使用,常用开源连接池:DBCP、C3P0、Druid(德鲁伊)

Druid连接池配置

将压缩包导入lib文件夹后,创建properties类型配置文件,设置数据库连接池信息

url=jdbc:mysql://localhost:3306/db2
username=root
password=root
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=20

    public static void main(String[] args) throws Exception {
        Properties properties=new Properties();
       // 通过类加载器读取路径内容
        properties.load(DruidDemo1.class.getClassLoader().getResourceAsStream("db.properties"));
        DataSource dataSource= DruidDataSourceFactory.createDataSource(properties);
        Connection connection=dataSource.getConnection();
        System.out.println(connection);
    }

ThreadLocal

JDK 1.2的版本中提供java.lang.ThreadLocal,为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。
ThreadLocal用于保存某个线程共享变量,原因是在Java中,每一个线程对象中都有一个ThreadLocalMap<ThreadLocal, Object>,其key就是一个ThreadLocal,而Object即为该线程的共享变量。而这个map是通过ThreadLocal的set和get方法操作的。对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。

数据库连接池工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtils {
    //定义成员变量
    private static DataSource dataSource;
    private static ThreadLocal<Connection> threadLocal;

    //静态代码块
    static {
        try {
            Properties properties=new Properties();
            properties.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);
            //初始化threadLocal对象
            threadLocal=new ThreadLocal<>();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取数据库连接池连接
    public static Connection getConneciton(){
        Connection connection =threadLocal.get();
        if(connection==null){
            try {
                connection=dataSource.getConnection();
                threadLocal.set(connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return connection;
    }


    public static void closeResource(){
        Connection connection=threadLocal.get();
        if(connection!=null){
            try {
                connection.close();
                threadLocal.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

使用封装工具类

public class TestUtils {

    public static void main(String[] args) {
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try {
            //获取数据库连接
            Connection connection = JdbcUtils.getConnection();

            String sql = "select * from dept";
            preparedStatement = connection.prepareStatement(sql);
            rs = preparedStatement.executeQuery();
            while(rs.next()) {
                System.out.println(rs.getString("dname"));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
                preparedStatement.close();
                JdbcUtils.closeResource();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

DBUtils使用

Apache-DBUtils是针对jdbc封装的工具类,使用DBUtils简化jdbc开发代码,没有改变jdbc效率
导入DBUtils的jar包
在这里插入图片描述
增加、修改和删除

//删除操作
@Test
public void test03() throws Exception {
    //创建QueryRunner对象
    QueryRunner queryRunner = new QueryRunner();
    // 编写sql语句
    String sql = "delete from dept where did=?";
    //调用方法执行sql
    queryRunner.update(JdbcUtils.getConnection(),sql,200);
    //释放资源
    JdbcUtils.closeResource();
}

//修改操作
@Test
public void test02() throws Exception {
    //创建QueryRunner对象
    QueryRunner queryRunner = new QueryRunner();
    // 编写sql语句
    String sql = "update dept set dname=? where did=?";
    //调用方法执行sql
    queryRunner.update(JdbcUtils.getConnection(),sql,"研发测试部",200);
    //释放资源
    JdbcUtils.closeResource();
}

//添加操作
@Test
public void test01() throws Exception {
    //创建QueryRunner对象
    QueryRunner queryRunner = new QueryRunner();
    // 编写sql语句
    String sql = "insert into dept values(?,?)";
    //调用方法执行sql
    queryRunner.update(JdbcUtils.getConnection(),sql,200,"测试部");
    //释放资源
    JdbcUtils.closeResource();
}

查询操作

/查询操作-返回一条记录
@Test
public void test01() throws Exception {
    //创建QueryRunner对象
    QueryRunner runner = new QueryRunner();
    //编写sql
    String sql = "select * from dept where did=?";
    //调用方法执行sql语句
    Dept dept =
            runner.query(JdbcUtils.getConnection(),sql,new BeanHandler<Dept>(Dept.class),1);
    System.out.println(dept);
    //释放资源
    JdbcUtils.closeResource();
}

//查询操作-返回多条记录
@Test
public void test02() throws Exception {
    QueryRunner runner = new QueryRunner();
    String sql = "select * from dept";
    List<Dept> list =
            runner.query(JdbcUtils.getConnection(), sql, new BeanListHandler<Dept>(Dept.class));
    System.out.println(list);
    JdbcUtils.closeResource();
}

版权声明:本文为qq_43016111原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。