当前位置:   article > 正文

Day 14 JDBC

Day 14 JDBC


在这里插入图片描述

1、简单入门 Statement

步骤:
1、注册驱动
2、创建连接
3、创建 Statement对象
4、编写sql语句 并且发送sql语句获得结果集
5、解析结果集
6、释放资源
注意事项 都在写下面代码里了

import com.mysql.cj.jdbc.Driver;

import java.sql.*;
import java.util.Properties;

public class day1 {
    public static void main(String[] args) throws Exception {
        new test();
        new test();
        //注册驱动  不推荐 会注册两次 new Driver中有静态代码块
        //DriverManager.registerDriver(new Driver());
        //new Driver();//不推荐 不能显示出 是什么驱动 如果是8+ 则是com.mysql.cj.jdbc 如果是5+ 则是com.mysql.jdbc
        Class.forName("com.mysql.cj.jdbc.Driver");  //推荐 通过反射获得类加载
        //建立连接 3种方式 ①
//        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        // ②
        Properties properties=new Properties();
        properties.put("user","ckytest");
        properties.put("password","123456");
//        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test",properties);
        //③
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?user=ckytest&password=123456");
        //创建 mql
        Statement statement = ckytest.createStatement();
        //mql 并发送 获取结果集
        String mysql="select * from u_ser";
        //  statement.executeUpdate();  非DML


        ResultSet resultSet = statement.executeQuery(mysql);
        while(resultSet.next()){
            int anInt = resultSet.getInt(1);
//            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            System.out.println(anInt+"---"+name);
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2、preparedStatement

步骤:
1、注册驱动
2、创建连接
3、编写sql语句
4、创建preparedStatement 对象并且传入sql语句
5、占位符赋值
从左到右 索引从1开始
6、发送sql语句获得结果集
7、解析结果集
8、释放资源

import com.mysql.cj.jdbc.Driver;
import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class test {
    @Test
   public void testinsert() throws  Exception{
       Class.forName("com.mysql.cj.jdbc.Driver");
       Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
       String mysql="insert into u_ser(id,name) values(?,?);";
       PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
       preparedStatement.setObject(1,3);
       preparedStatement.setObject(2,"yue");
        int i = preparedStatement.executeUpdate();
        if (i>0)
           System.out.println("成功");
        preparedStatement.close();
        ckytest.close();
   }

    @Test
    public void testupdate() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="update u_ser set name=? where id=?;";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        preparedStatement.setObject(1,"cui");
        preparedStatement.setObject(2,3);
        int i = preparedStatement.executeUpdate();
        if (i>0)
            System.out.println("成功");
        preparedStatement.close();
        ckytest.close();
    }
    @Test
    public void testdelete() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="delete from u_ser where  id=?;";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        //preparedStatement.setObject(1,"cui");
        preparedStatement.setObject(1,3);
        int i = preparedStatement.executeUpdate();
        if (i>0)
            System.out.println("成功");
        preparedStatement.close();
        ckytest.close();
    }

    //查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value
    @Test
    public void testquery() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="select * from u_ser;";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        ResultSet resultSet = preparedStatement.executeQuery();
        //得到表信息
        ResultSetMetaData metaData = resultSet.getMetaData();
        //得到列数量
        int columnCount = metaData.getColumnCount();
        List<Map> list=new ArrayList<>();
        while(resultSet.next()) {
            Map map = new HashMap();
            for (int i = 1; i <= columnCount; i++) {
                //获得结果
                Object object = resultSet.getObject(i);
                //获得列名
                String columnLabel = metaData.getColumnLabel(i);
                map.put(columnLabel, object);

            }
            list.add(map);
        }
        System.out.println(list);
        resultSet.close();
        preparedStatement.close();
        ckytest.close();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

String columnLabel = metaData.getColumnLabel(i);
getColumnLabel 有别名可以获得别名而getColumnName 不能获取别名。
getColumnCount 获取列的数量
getMetaData 获取列的信息

3、主键回显

  /**
     * 
     * 得到自增长的主键
     * 在创建prepareStatement,告知它拿回自增长的主键
     * getGeneratedKeys 得到一个自增长主键的结果 首先通过next 移动光标
     * 之后通过getxx 获取结果,插入一行 肯定只获取一个结果 所以是一行一列 索引为1 即使回显的主键
     */
    @Test
    public void testinsertkey() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="insert into u_ser(name) values(?);";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS);
        preparedStatement.setObject(1,"yue1");
        int i = preparedStatement.executeUpdate();
        if (i>0)
            System.out.println("成功");
        ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
        generatedKeys.next();
        Object id = generatedKeys.getObject(1);
        System.out.println("回显主键:"+id);
        preparedStatement.close();
        ckytest.close();
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4、批量操作

在url中添上rewriteBatchedStatements=true,允许批量操作。
sql语句不要加分号
preparedStatement.addBatch();
preparedStatement.executeBatch();

    @Test
    public void testinsert1() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456");
        String mysql="insert into u_ser(name) values(?)";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1,"yue1"+i);
             preparedStatement.executeUpdate();

        }
        long end = System.currentTimeMillis();
        System.out.println("时间为:"+(end-start)/1000+"s"); //14s
        preparedStatement.close();
        ckytest.close();
    }
    @Test
    public void testabatchinsert() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456");
        String mysql="insert into u_ser(name) values(?)";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1,"yue"+i);
            preparedStatement.addBatch();
        }
        preparedStatement.executeBatch();
        long end = System.currentTimeMillis();
        System.out.println("时间为:"+(end-start)+"s");//0.77s
        preparedStatement.close();
        ckytest.close();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

5、事务

原子性 一致性 隔离性 持久性
事务的发生 必须是在同一个连接中。
对于事务,我们应该在业务层进行开启和关闭。mysql是自动提交业务,我们可以手动开启或者关闭。
比如转账业务,我们可以在业务层获取一个连接,之后将该连接传入加钱和转钱方法,这样可以确保是一个连接。
事务,我们一般使用try,catch,如果成功就提交,捕捉到错误就回滚。

6、Druid

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class DruidTest {
    public void druid1() throws  Exception{
        //创建连接池对象
        DruidDataSource druidDataSource=new DruidDataSource();
        //一些必要和不必要的选项 url,name,pwd,driver都是必须的 连接池数量这些不是必须的
        druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
        druidDataSource.setPassword("123456");
        druidDataSource.setUsername("ckytest");
        druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        druidDataSource.setInitialSize(5);
        druidDataSource.setMaxActive(10);
        //获得一个连接。
        DruidPooledConnection connection = druidDataSource.getConnection();
        //回收
        connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。
    }
    public void druid2() throws  Exception{

        //读取配置文件
        Properties properties=new Properties();
        //只要在src下 就可以使用类加载器
        InputStream resourceAsStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
        properties.load(resourceAsStream);//加载到properties中
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        //获得一个连接。
        Connection connection = dataSource.getConnection();
        //回收
        connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
Url=jdbc:mysql://127.0.0.1:3306/test
Password=123456
Username=ckytest
DriverClassName=com.mysql.cj.jdbc.Driver
  • 1
  • 2
  • 3
  • 4

6.1 工具类V1

每次都去初始化连接池太麻烦了,我们封装一个工具类,对外提供一个获取连接和回收连接的方法。

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/*
*   工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法
*  创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次
 */
public class DruidUtils {
    //连接池
    private static DataSource dataSource=null;
    static {
        Properties properties=new Properties();
        InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            properties.load(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    public void closeConnection(Connection connection){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

6.2 工具类V2

我们的工具类V1,只是单例模式了连接池,但是每次获取连接都是新的连接。
如果我们在Serve层获得一个连接,这个连接还需要传给Dao层来获取,能不能让同一个线程,Serve层和Dao层获取的都是同一个连接,而不用使用参数传递呢?可以使用线程局部变量。只要一个线程里边的属性就是通用的。

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/*
*   工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法
*  创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次
 */
public class DruidUtils {
    //连接池
    private static DataSource dataSource=null;
    private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();
    static {
        Properties properties=new Properties();
        InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            properties.load(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    public Connection getConnection() throws SQLException {
        Connection connection=threadLocal.get();
        if (connection==null){
            connection = dataSource.getConnection();
            threadLocal.set(connection);
        }
        return connection;
    }
    public void closeConnection() throws Exception{
        Connection connection = threadLocal.get();
        if (connection!=null){
            threadLocal.remove();
            connection.setAutoCommit(true);
            connection.close();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

6.3

对于Dao层的封装,写一个基础BaseDao,对语句进行封装,可以分为DQL和非DQl两种。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class A {

    public static int  executUpdate(String sql,Object ... args) throws Exception{
        Connection connection = DruidUtils.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i <args.length ; i++) {
            preparedStatement.setObject(i+1,args[i]);
        }
        int i = preparedStatement.executeUpdate();
        if (connection.getAutoCommit()){
            //没有开启事务
            DruidUtils.closeConnection();
        }
        return i;
    }
    public static  <T>  List<T> executQuery(Class<T> tClass,String sql, Object ... args) throws Exception{
        Connection connection = DruidUtils.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        if(args!=null&&args.length>0)
        {
            for (int i = 0; i <args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }
        }
        ResultSet resultSet = preparedStatement.executeQuery();
        //得到表信息
        ResultSetMetaData metaData = resultSet.getMetaData();
        //得到列数量
        int columnCount = metaData.getColumnCount();
        List<T> list=new ArrayList<>();
        while(resultSet.next()) {
            Constructor<T> constructor = tClass.getConstructor();
            T t = constructor.newInstance();
            for (int i = 1; i <= columnCount; i++) {
                //获得结果
                Object object = resultSet.getObject(i);
                //获得列名
                String columnLabel = metaData.getColumnLabel(i);
                Field declaredField = tClass.getDeclaredField(columnLabel);
                declaredField.set(t,object);
            }
            list.add(t);
        }
        if (connection.getAutoCommit()){
            //没有开启事务
            DruidUtils.closeConnection();
        }
        return list;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

数据库每个表都对应java中的一个实体类,查询时我们返回的是一个装有实体类的集合。

封装过工具类之后的增删改查 简化了很多。

import com.mysql.cj.jdbc.Driver;
import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class test {
    @Test
   public void testinsert() throws  Exception{

       String mysql="insert into u_ser(id,name) values(?,?);";
        int a = A.executUpdate(mysql, 50001, "a");
        System.out.println(a);
   }

    @Test
    public void testupdate() throws  Exception{

        String mysql="update u_ser set name=? where id=?;";
        int a = A.executUpdate(mysql, "cui", 1);
        System.out.println(a);
    }
    @Test
    public void testdelete() throws  Exception{

        String mysql="delete from u_ser where  id=?;";
        int a = A.executUpdate(mysql, 1);
        System.out.println(a);
    }

    //查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value
    @Test
    public void testquery() throws  Exception{
        String mysql="select * from u_ser;";
        List<User> users = A.executQuery(User.class, mysql);
        System.out.println(users);
    }


  
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/333843
推荐阅读
相关标签
  

闽ICP备14008679号