JDBCUtil工具类

JDBC:Java访问数据库的技术

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。

            DAO  Database  Access Object(数据库访问对象)   在工程中,从属于dao层。 respository(仓库)

            之前处理其他业务逻辑,与DB无关,成为service层,比如处理注册登录的业务功能。

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。

            DAO  Database  Access Object(数据库访问对象)   在工程中,从属于dao层。 respository(仓库)

            之前处理其他业务逻辑,与DB无关,成为service层,比如处理注册登录的业务功能。

 

 

一、向Eclipse工程中导入jar包(一般的封装类在项目中都放在一个单独的page包中util)

                    创建包的时候一般是需要后缀为dao。如:com.zhiyou.dao

 

1.首先需要导入一个jar包(第三方工具包):mysql-connector-java-8.0.17.jar

            (1)在网上下载:Connector/J中

            (2)在MySQL的安装包中找到:

                        MySQL5.8版本之后的MySQL在安装过程中也会把这个jar包下载下来。

                        位置在:C:\Program Files (x86)\MySQL\Connector J 8.0.17.jar

 

2.将jar包加入到工程中:目的是可以使用jar中的工具类,能让eclipse编译时可以识别

             (1)右键工程名字创建lib(资源库)文件夹(Floder)

             (2)将jar包拖拽到lib文件夹中,选择copy file

             (3)右键lib中的jar包,选择Build Path --->Add to Build Path

             (4)Add to Build Path之后会在lib文件夹上方出现Referenced Librarice(被使用的资源库),里面包含这个jar包(jar包的图标会变)

                  这个jar包里面放的都是工具包和工具类的编译类(xx.class)。关键:com.mysql.cj.jdbc.Driver.class

二、JDBC步骤分析

        步骤:

                1.加载驱动

                2.建立连接

                3.准备SQL

                4.执行SQL

                5.处理结果

                6.断开连接

 

(1)实现查询功能(Query)

1 加载驱动

             加载jar包中的驱动类Driver.class,用到的方式是反射

            使用Class.forName 这一反射方式加载Driver类的原因是因为 :倘若使用new Driver()方式,则会首先执行Driver类中的静态代

码块, 而静态代码块中又出现了一次new Driver(),如此 相当于new了两次Driver对象,不好!

 

           所以,使用Class.forName也会执行Driver类中的静态代码块,最终也就只执行了一次new对象。这种方式才是我们想要的。

           String----》find class ---》load---》static---》new Driver()

 

          1.Class.forName("com.mysql.cj.jdbc.Driver");     :使用Class类的forName方法来加载驱动

                需要解决异常(throws抛出或者try/catch解决)

2.建立连接    :    使用DriverManager类的connection方法返回一个Connection的实例

                (1)使用DriverManager中的getConnection(url,user,password)方法,返回值类型是Connection类型

                                        DriverManager.getConnection(url,username,password);

                给url赋值为:"jdbc:mysql://localhost:3306/student?serverTimezone=GMT%2B8",用户名及密码为安装数据库时设置的。

都是String类型

                        url的格式:协议//本机主机:端口号/数据库名?serverTimezone=GMT%2B8

                        url的格式中数据库后面的是mysql8版本必须指定的时区,需要在数据库后面加上配置信息(否则会出现时区异常)

                                        String url = "jdbc:mysql://localhost:3306/student?serverTimezone=GMT%2B8";

                                        String user = "root";

                                        String password = "1234";

 

                (2)因为在准备下一步的准备SQL中要使用DriverManage.getConnection(url,user,password)方法拿到的Connection对象

connection中的方法,所以需要创建对象并将方法返回值赋给Connection的对象connection

                                        Connection connection = null;

                                        2. connection = DriverManager.getConnection(url,user,password);

 

                (3)解决异常(throws抛出或者try/catch解决)

3.准备SQL    :   使用Connection中的prepareStatement方法,返回了一个PrepareStatement实例。将sql语句给数据库先编译

                (1)使用connection中的prepareStatement()方法,参数为数据库语言,如:sql,返回值类型为PreparedStatement对象

                                            connection.perpareStatement(sql);

 

                (2)因为在下一步的执行SQL中要使用PreparedStatement对象的方法,所以需要创建一个PreparedStatement对象,并将

方法中的返回值赋予对象

                                            PreparedStatement pStatement = null;

                                           3. pStatement = connection.prepareStatement(sql);

                    对于方法中的参数sql就是sql语句。属于字符串String类型。需要定义sql操作语句

                                            String sql = "select * from student";

 

                (3)解决异常(throws抛出或者try/catch解决)

 

4.执行SQL(查询为例  ) :使用PrepareStatement中的executeQuery方法,返回一个ResultSet实例

                 查询是用executeQuery()方法        增加删除修改都是用excuteUpdate()方法)使用Update时不需要第五步且第四步不同

                (1)使用PreparedStatement对象pStatement的executeQuery()方法,返回值类型为ResultSet

                                            pStatement.executeQuery();

 

                (2)因为在下一步的处理结果中需要使用ResultSet对象来拿值,所以需要创建ResultSet对象并将方法中的返回值赋予对象

                                            Result rSet = null;

                                          4.  rSet = pStatement.executeQuery();

 

 

5.处理结果 

        拿值并打印     使用getXxx拿值,类型由表中字段类型决定,其中参数选择int就使用列的索引值,选择String就使用列的字段名

                                            while(rSet.next()){            

                                                     int id = rSet.getInt(1);                                     第一种方法:列的索引值 默认是从1开始

                                                     String name = rSet.getString("name");              第二种方法:列的字段名 

                                                     int age = rSet.getInt("age");

                                                  System.out.println("从数据库中student表中取得的值为: "  +  id  +  ","  +  name  +  ","  +  age);

                                            }

 

6.断开连接

                释放资源

                从最下层的对象开始关闭,即先创建的最后关闭,最后创建的优先关闭

                (1)rSet.close()            pStatemen.close();            connection.close();

                (2)解决异常

 

 

(2)实现增删改功能(Update)

        前面三步与查询一样

    (第四步)1.添加固定值:

                      对于修改的返回结果是成功修改了几条记录,所以返回值为int

                                int record = pStatemen.executeUpdate();        

                因为修改记录不需要返回结果,所以省略第五步,且不会创建ResuleSet对象

 

                    2.调用方法添加不定值:

                                    public    static void main(String[] arg){

                                                    upDate(5,'zhangsan',20);

                                    }

                                    这些JDBC语句写在main方法之外的静态方法中

                                    public static void upDate(int i,String string,int age){

                                    String sql = "insert into user values(?,?,?)";            ?是占位符

                                  PreparedStatement pStatement = connection.prepareStatement(sql);

 

              //下面的这些set方法中的参数,第一个是索引值(默认从1开始),第二个是传进来的参数名。(与方法的参数一一对应)

                                  // pStatement.setInt(1, i);           

                                      pStatement.setObject(1, i);

 

                                  // pStatement.setString(2, string);

                                      pStatement.setObject(2, string);

 

                                      pStatement.setObject(3, j);      

                                       int record = pStatemen.executeUpdate();         

               

             (5)关闭连接

                                pStatement.close();            connection.close();

三、编写JDBC代码

 

1.使用 try/catch解决异常   实现查询数据库功能的代码           

public static void main(String[] args) {
        //1.加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("加载驱动成功");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("加载驱动失败");
        }
        //2.输入用户名密码建立连接
        String url = "jdbc:mysql://localhost:3306/student?serverTimezone=GMT%2B8";
        String user = "root";
        String password = "1234";
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, user, password);
            System.out.println("建立连接成功");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("建立连接失败");
        }
        //3.准备输入查询或者修改sql
        String sql = "select * from student";
        PreparedStatement pStatement = null;
        try {
            pStatement = connection.prepareStatement(sql);
            System.out.println("准备的sql语句正确");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("准备的sql语句错误");
        }
        //4.执行sql的查询或者修改语句
        ResultSet rSet = null;
        try {
            rSet = pStatement.executeQuery();
            System.out.println("查询成功");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("查询失败");
        }
        //5.处理结果(打印)
        try {
            while(rSet.next()) {
                int id = rSet.getInt(1);
                String name = rSet.getString("name");
                int age = rSet.getInt("age");
                System.out.println("id为" + id + " 的学生叫做:" + name + " 今年" + age + "岁");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //6.关闭连接,释放资源
        //rSet
        try {
            rSet.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //pStatement
        try {
            pStatement.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //connection
        try {
            connection.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
输出结果:
加载驱动成功
建立连接成功
准备的sql语句正确
查询成功
id为1 的学生叫做:张三 今年18岁

 

2.使用throws解决异常   实现向数据库添加固定值的功能的代码  

public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.建立连接
        String url = "jdbc:mysql://localhost:3306/student?serverTimezone=GMT%2B8";
        String user = "root";
        String password = "1234";
        Connection connection = null;
        connection = DriverManager.getConnection(url, user, password);
        //3.准备插入SQL
        String sql = "insert into student values(4,'麻子',21) ";
        PreparedStatement pStatement = null;
        pStatement = connection.prepareStatement(sql);                                                   
        //4.执行SQL
        int roeForExecution = pStatement.executeUpdate();
        System.out.println("插入操作执行成功");
        //5.关闭连接
        pStatement.close();
        connection.close();
} 
输出结果:插入操作执行成功

 

 3.使用throws解决异常    向数据库添加不固定数值

public class JDBCTestThree {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        upDate(5, "老张", 23);
    }
    public static void upDate(int i ,String j,int k) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/student?serverTimezone=GMT&2B8";
        String user = "root";
        String password = "1234";
        Connection connection = DriverManager.getConnection(url, user, password);
        String sql = "insert into student values(?,?,?)";
        PreparedStatement pStatement = connection.prepareStatement(sql);
//      pStatement.setObject(1, i); 使用Object类型传参数
        pStatement.setInt(1, i);    
        
//      pStatement.setString(2, j); 使用参数类型传参数
        pStatement.setObject(2, j);
        
//      pStatement.setObject(3, k);
        pStatement.setInt(3, k);
        int record = pStatement.executeUpdate();
        System.out.println("成功添加");
        pStatement.close();
        connection.close();
    }
}
输出结果:成功添加

 

 四、封装JDBC

 

1.封装的JDBC

public class DButil {
    //在工具类中,如果有一个以上的方法使用相同的变量,就把这个变量定义为属性
    private static Connection connection;
    private static PreparedStatement preparedStatement;
    private static ResultSet resultSet;
    
    //设计规则:死值都设为常量,这样在以后改变的时候在属性上面修改就可以
    private static final String URL_STRING = "jdbc:mysql://localhost:3306/student?serverTimezone=GMT%2B8";
    private static final String USER_STRING = "root";
    private static final String PASS_STRING = "1234";
    
    
    //1.加载驱动只需要执行一次即可。所以定义在静态代码块中
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
    
    public static ResultSet query(String sql,Object[] objects) {
        connection = getConnection();
        try {
            preparedStatement = connection.prepareStatement(sql);
            for(int i = 0;i < objects.length;i++) {
                //用于给sql语句的占位符赋值(参数?的绑定)sql语句中的?索引是从1开始的
                preparedStatement.setObject(i+1, objects[i]);
            }
            resultSet = preparedStatement.executeQuery();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //因为查询时候的表都不同,所以不能在此方法中处理结果集。要写在main方法中,需要修改查询结果格式的时候就在main方法中修改
        //所以此方法只需要返回resultSet即可
        return resultSet;
    }
    
    
    public static void update(String sql2, Object[] objects2) {
        int row;
        connection = getConnection();
        try {
            preparedStatement = connection.prepareStatement(sql2);
            //参数?的绑定(sql语句中的?索引是从1开始的)
            for(int i = 0;i < objects2.length;i++) {
                preparedStatement.setObject(i+1, objects2[i]);
            }
             row = preparedStatement.executeUpdate();
             System.out.println("row:" + row);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    private static Connection getConnection() {
        try {
            connection = DriverManager.getConnection(URL_STRING, USER_STRING, PASS_STRING);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return connection;
    }
    
    //关闭,释放资源:先创建后关闭,后创建的先关闭:先进后出
    public static void close() {
        if(resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

注意:在executeUpdate()和executeQuery()方法之前,通过for循环中的prepareStatement.setObject(i+1,i)方法来完成参数绑定,sql语句中的?索引是从1开始的

 

 

2.不使用model类的测试类

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        testQuery();
        testUpdate();
        
    }
    //添加
    private static void testUpdate() {
        // TODO Auto-generated method stub
        String sql2 = "insert into student values(?,?,?,?)";
        Object[] objects2 = {5,"小明",20,2};
        DButil.update(sql2,objects2);
        DButil.close();
    }
    //查询
    private static void testQuery() throws SQLException {
        String sql = "select * from student where s_id=?";
        //创建数组,在DButil中使用数组中的值为sql中的?占位符进行绑定
        Object[] objects = {2};
        ResultSet resultSet = DButil.query(sql,objects);
        while(resultSet.next()) {
            int id = resultSet.getInt(1);
            String name = resultSet.getString(2);
            int age = resultSet.getInt(3);
            System.out.println(id + name + age);
            DButil.close();
        }
    }
}
输出结果:
2李四21
row:1

 

3.使用model类的测试类(查询全部的学生信息):

                    按照封装的思想,一般为了java代码使用,所以从db的表中获得的一条记录,会转换成一个model类的对象。    

                    如果是多条记录,会转换成多个对象,并且存放在集合中。

 注意:使用User类来创建对象的时候,要导包

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        testQuery();
        testUpdate();
        
    }
    
    //查询                                                                                                           
    private static void testQuery() throws SQLException {
            String sql = "select * from student  ";
            //创建数组,在DButil中使用数组中的值为sql中的?占位符进行绑定
            Object[] objects = {};
            ResultSet resultSet = DButil.query(sql,objects);
            while(resultSet.next()) {
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                int age = resultSet.getInt(3);
                int c_id = resultSet.getInt(4);
                System.out.println(id + name + age + c_id);
                
                User user = new User(id, name, age, c_id);
                System.out.println(user);
                List list = new ArrayList();
                list.add(user);
                System.out.println(list);
                System.out.println();
            }
            DButil.close();
        }
    //添加
    private static void testUpdate() {
        // TODO Auto-generated method stub
        String sql2 = "insert into student values(?,?,?,?)";
        Object[] objects2 = {5,"小明",20,2};
        DButil.update(sql2,objects2);
        DButil.close();
    }
}
输出结果:
id:1 name:张三 age:30 c_id:1
User [id=1, name=张三, age=30, c_id=1]
[User [id=1, name=张三, age=30, c_id=1]]
id:2 name:李四 age:21 c_id:2
User [id=2, name=李四, age=21, c_id=2]
[User [id=2, name=李四, age=21, c_id=2]]
id:3 name:王五 age:23 c_id:1
User [id=3, name=王五, age=23, c_id=1]
[User [id=3, name=王五, age=23, c_id=1]]
id:4 name:麻子 age:20 c_id:3
User [id=4, name=麻子, age=20, c_id=3]
[User [id=4, name=麻子, age=20, c_id=3]]

 

你可能感兴趣的:(JDBCUtil工具类)