JDBC

JDBC(Java数据库连接)是Java语言访问数据库的标准接口,提供了统一的API用于执行SQL语句。它包括DriverManager、Connection、Statement和ResultSet等核心接口。通过JDBC,程序员可以跨数据库平台编写代码。使用JDBC时,需要添加数据库驱动jar包,并通过DriverManager.getConnection()获取连接,再通过Connection对象创建Statement或PreparedStatement执行SQL。JDBC的封装可以减少重复代码,提高效率。高级操作中涉及ORM映射、分层开发和防止SQL注入的PreparedStatement。分层开发将应用划分为界面层、业务逻辑层和数据访问层,ThreadLocal则有助于减少资源浪费。

第一节 JDBC(Java数据库连接)

一.什么是JDBC?

JDBC(Java Data Base Connectivity, Java数据库连接)
是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问
它由一组用Java语言编写的类和接口组成(由sun公司提供的)(这些类和接口是由数据库公司来实现的,谁来实现它,就连接谁的数据库)


2.有了JDBC,程序员只需用JDBC API写一个程序,就可访问所有数据库。

(使用JDBC是跨数据库平台)
3.Sun公司、数据库厂商、程序员三方关系:
◆ SUN公司是规范制定者,制定了规范JDBC(连接数据库规范) 一类三接口
①DriverManager类 作用:管理各种不同的JDBC驱动(不同数据库jar包归它管理)
②Connection接口 作用:(修路的,实际上还是TCP,一方是数据库服务器,javaApplication是客户端,如果进行通信的话,第一件事情就是建立连接。)
③Statement接口和PreparedStatement接口 作用:(就是用于发送sql语句的,也就是把sql语句发送带数据库服务器去执行。数据库执行完语句有结果吗?有,增、删、改的结果是int,查询的结果是表。)
④ResultSet接口 (结果集) 作用:(在增删改的时候用不到,只是在查询的时候能用到,因为查询的时候是结果集)
◆ 数据库厂商微软、甲骨文等分别提供实现JDBC接口的驱动jar包(数据库管理系统生产厂商把类和接口进行实现了,实现了之后,程序员得用,那么怎么把这些实现类给程序员呢?是以jar包的形式。例:Orical实现接口,提供jar包,用于连接Orical数据库)
◆ 程序员学习JDBC规范来应用这些jar包里的类。
常用的框架Hibernate、MyBatis底层都是JDBC,都是对JDBC的封装

二、JDBC怎么使用?

JDBC的操作步骤 :
    ① 加载一个Driver驱动
	②创建数据库连接(Connection)
	③创建SQL命令发送器Statement
	④通过Statement发送SQL命令并得到结果
    ⑤处理结果(insert ,update,delete的结果为int ,select的结果为ResultSet)
	⑥关闭数据库资源
		 ◆ResultSet
         ◆ Statement
		 ◆Connection

新建一个project命名为java502---->在这个项目下新建一个Model命名为day1_jdbc---->在这个模块下新建一个directory命名为lib,把jar包复制到这个文件夹下面,这个时候这个jar包是不能用的,需要做一件事儿:鼠标放在这个jar上–右键–单击Add as library ,然后会弹出来一个框,选择ok即可。如下图所示则jar可以用了。

"连接mysql数据库"

package com.bjsxt.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestInsert {
    public static void main(String[] args)throws  Exception {
        //(1)加载驱动,[找到jar才能知道连谁] --导入jar包
        Class.forName("com.mysql.jdbc.Driver"); //com.mysql.jdbc是包的名称 Driver是类的名称
        //(2)因为mysql 服务器上有可多数据库了,请问你连的是哪个?
        String url="jdbc:mysql://127.0.0.1:3306/myschool";//连的是服务器上的哪个数据库
        String userName="root";
        String pwd="root";
        //(3)获取连接对象
        Connection connection = DriverManager.getConnection(url, userName, pwd);
        //(4)准备sql语句
        String sql="insert into dept values (99,'test','上海')";
        //(5)使用sql语句发送器发送sql到数据库服务器执行,并带回结果
        Statement statement = connection.createStatement();
        int i = statement.executeUpdate(sql);
        System.out.println(i>0?"插入成功":"失败");
        //(6)关闭连接
        statement.close();
        connection.close();
    }
}

说明: //(2)因为mysql 服务器上有可多数据库了,请问你连的是哪个?
java程序是数据库的客户端,既然是服务器的客户端,那么在socket编程中必须给IP、端口,找到服务器后,服务器中数据库那么多还得告诉我连哪一个数据库,所以url=“jdbc:mysql://127.0.0.1:3306/myschool”.

总结:
1)DriverManager 这个类中有一个静态方法 getConnection(String url,String user,String pwd) 用于获取连接对象
2)Connection接口有一个方法 createStatement() 用于获取SQL语句发送器对象
3)Statement接口有一两个方法 executeUpdate(String sql)用于执行insert ,update,delete的sql语句,返回值为int类型
executeQuery(String sql)用于执行select语句的,返回结果为ResultSet

连oracle数据库

package com.bjsxt.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestInsert2 {
    public static void main(String[] args)throws  Exception {
        //(1)加载驱动,[找到jar才能知道连谁] --导入jar包
        Class.forName("oracle.jdbc.driver.OracleDriver");
        //(2)因为mysql 服务器上有可多数据库了,请问你连的是哪个?
        String url="jdbc:oracle:thin:@192.168.151.241:1521:xe";//连的是服务器上的哪个数据库
        String userName="scott";
        String pwd="tiger";
        //(3)获取连接对象
        Connection connection = DriverManager.getConnection(url, userName, pwd);
        //(4)准备sql语句
        String sql="insert into dept values (79,'test','上海')";
        //(5)使用sql语句发送器发送sql到数据库服务器执行,并带回结果
        Statement statement = connection.createStatement();
        int i = statement.executeUpdate(sql);
        System.out.println(i>0?"插入成功":"失败");
        //(6)关闭连接
        statement.close();
        connection.close();
    }
}

说明:
◆Oracle: 永远要关心一个名叫“监听”的事儿 ,监听能决定你今天能连上数据库,明天不好说。
◆MySQL :永远要关心的是中文“乱码”
jdbc:mysql://localhost:3306/MySchool?useUnicode=true&characterEncoding=utf8

三、JDBC的封装

1.实现修改和删除
因为发现修改,删除和新增,除了sql语句不同,剩下操作步骤完全相同,所以需要提取DBUtil

(1)提取获取连接的方法
(2)提取增,删,改的通用方法
(3)提取关闭全部的方法

package com.bjsxt.util;
import java.sql.*;
public class DBUtil {
    private static final String DRIVER="com.mysql.jdbc.Driver";
    private static final String URL="jdbc:mysql://127.0.0.1:3306/myschool";
    private static final String USERNAME="root";
    private static final String PWD="root";
    //获取连接对象
    public static Connection getConn(){
        Connection connection = null;
        try {
            Class.forName(DRIVER);
            connection = DriverManager.getConnection(URL, USERNAME, PWD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
    //增,删,改除了sql语句不同,剩下都一样,提取增,删,改的通用方法,可变的做参数,不变的作方法体
    public static int executeDML(String sql){
        //(1)获取连接对象
        Connection conn = getConn();
        Statement statement=null;
        int result=0;
        //(2)创建sql语句发送器,发送sql语句
        try {
             statement = conn.createStatement();
           result= statement.executeUpdate(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭
            closeAll(null,statement,conn);
        }
        return  result;
    }
    //封装关闭全部的方法
    public static void closeAll(ResultSet resultSet,Statement statement,Connection connection){
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

测试

package com.bjsxt.test;
import com.bjsxt.util.DBUtil;
public class Test {
    public static void main(String[] args) {
        //测试新增
        //insert();
       // update();
        delete();
    }
    public static  void insert(){
        String sql="insert into dept values (11,'abc','cc')";
        int i = DBUtil.executeDML(sql);
        System.out.println(i>0?"新增成功":"新增失败");
    }
    public static  void update(){
        String sql="update dept set dname='公安部',loc='北京' where deptno=91";
        System.out.println(DBUtil.executeDML(sql)>0?"修改成功":"对不起没有找到要修改的数据");
    }
    public static  void delete(){
        String sql="delete from dept where deptno=91";
        System.out.println(DBUtil.executeDML(sql)>0?"删除成功":"对不起没有找到要删除的数据");
    }
}

2.查询
查询需要使用到ResultSet 接口
该接口中有如下方法
(1)boolean next() ;判断 是否有数据行,如果结果集中有数据行,返回值为true,否则为false
(2)getXXX(int columnIndex) 获取各种类型的数据 ,列的索引从1开始
getInt(…) -->获取的是数据行中int类型的数据
getString(…) -->获取varchar类型的数据
getDouble(…) -->获取double类型的 数据
getDate(…); -->获取Date类型的数据

(3)重载的方法 getXXX(String columnLabel) columnLabel是查询结果的列名
如果查询使用的是"*" ,则columnLabel为 字段名称
如果查询时使用到的别名 ,则columnLabel为别名

package com.bjsxt.jdbc;
import com.bjsxt.util.DBUtil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestQuery {
    public static void main(String[] args) throws  Exception {
        //(1)获取连接对象
        Connection conn = DBUtil.getConn();
        //(2)创建SQL语句发送器
        Statement statement = conn.createStatement();
        //(3)准备sql语句
        String sql="select deptno as 部门编号,dname as name,loc  from dept";
        //(4)使用SQL语句发送器,发送SqL到数据库执行
        ResultSet resultSet = statement.executeQuery(sql);
        //(5)处理结果
       /* while (resultSet.next()){ //true ,说明结果集中有数据行,每循环一次,获取一行数据
            int deptNo = resultSet.getInt(1);
            String dname = resultSet.getString(2);
            String loc = resultSet.getString(3);
            System.out.println(deptNo+"\t"+dname+"\t"+loc);
        }*/
        while (resultSet.next()){
            int deptNo = resultSet.getInt("部门编号");
            String name = resultSet.getString("name");
            String loc = resultSet.getString("loc");
            System.out.println(deptNo+"\t"+name+"\t"+loc);
        }
        //(6)关闭
        DBUtil.closeAll(resultSet,statement,conn);
    }
}

第二节 JDBC的高级操作

(1)、数据库的表的设计 ORM 对象关系映射
◆一张表对应一个Java实体类
◆一个字段对应类的一个属性
◆表中的一行记录对应Java一个实体类的对象

数据库部分

create table t_user(
  uid int(4) primary key auto_increment,
  uname varchar(20) not null,
  pwd varchar(20) not null
);
-- 测试数据
insert into t_user values (default,'bjsxt','123');
insert into t_user values (default,'sxt','456');
select * from t_user;

实体类 JavaBean
什么样的类被称为javaBean
a)类是公共的 b)属性是私有的 c)提供get/set d)提供无参构造

(2)后台程序

package com.bjsxt.entity;
public class User {
    private int uid;
    private String uname;
    private String pwd;
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public User(int uid, String uname, String pwd) {
        this.uid = uid;
        this.uname = uname;
        this.pwd = pwd;
    }
    public User() {
    }
    public User(String uname, String pwd) {
        this.uname = uname;
        this.pwd = pwd;
    }
    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", uname='" + uname + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

接口
DAO(Data Access Object)数据访问对象是一个面向对象的数据库接口。

package com.bjsxt.dao;
public interface UserDao {
    public boolean queryByUser(String uname,String pwd);
}

接口的实现类

package com.bjsxt.dao.impl;
import com.bjsxt.dao.UserDao;
import com.bjsxt.util.DBUtil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class UserDaoImpl implements UserDao {
    @Override
    public boolean queryByUser(String uname, String pwd) {
        //连接数据库,查询得到结果
        //(1)获取连接
        Connection conn = DBUtil.getConn();
        Statement statement=null;
        ResultSet resultSet=null;
        //(2)创建sql语句发送器
        try {
             statement = conn.createStatement();
             //(3)准备sql语句
             String sql ="select * from t_user where uname='"+uname+"' and pwd='"+pwd+"'";
            System.out.println(sql);
             //(4)开始到数据库中执行
             resultSet = statement.executeQuery(sql);
             //(5)处理结果
            if(resultSet.next()){
                return  true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.closeAll(resultSet,statement,conn);
        }
        return false;
    }
}

(3)编写前台程序

package com.bjsxt.test;
import com.bjsxt.dao.UserDao;
import com.bjsxt.dao.impl.UserDaoImpl;
import java.util.Scanner;
public class Client {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String uname=input.next();
        System.out.println("请输入密码:");
        String pwd= input.next();
        //创建接口的实现类对象
        UserDao userDao=new UserDaoImpl();
        boolean b = userDao.queryByUser(uname, pwd);
        System.out.println(b?"登录成功":"对不起,账号或密码不正确");
    }
}

1.0版的登录,容易出现SQL注入

精心设计一个sql语句,无论用户名用密码输入什么内容,都能登录成功

问题出现在sql语句的字符串的拼接上

String sql =“select * from t_user where uname=’”+uname+"’ and pwd=’"+pwd+"’";

(说明:等号的右侧有变量参与运算?有,username和pwd是变量,所以等号右侧有变量参与运算,它将在堆中开辟内存空间,创建的是StringBuilder的对象,然后再通过append()方法进行字符串的追加,所以浪费内存空间,因此字符串的拼接不是很好)
(1)字符串的拼接,将造成内存的浪费 【字符串的接会产生对象】
(2)容易sql注入

解决方案:
使用Statement的子接口PreparedStatement 预编译的SQL语句

PreparedStatement里面有很多set方法用来给占位符设置值。

修改后台代码

package com.bjsxt.dao.impl;
import com.bjsxt.dao.UserDao;
import com.bjsxt.util.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDaoImpl2  implements UserDao{
    @Override
    public boolean queryByUser(String uname, String pwd) {
        //(1)获取连接
        Connection conn = DBUtil.getConn();
        //(2)预编译的sql语句发送器
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            String sql="select * from t_user where uname=? and pwd=?";
            statement=conn.prepareStatement(sql);
            //(3)给占位符赋值
            statement.setString(1,uname); //1表示第一个?
            statement.setString(2,pwd);
            System.out.println(sql);
            //(4)到数据库中执行
             resultSet = statement.executeQuery();
            if(resultSet.next()){
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.closeAll(resultSet,statement,conn);
        }
        return false;
    }
}

相应的前台测试程序

package com.bjsxt.test;
import com.bjsxt.dao.UserDao;
import com.bjsxt.dao.impl.UserDaoImpl;
import com.bjsxt.dao.impl.UserDaoImpl2;
import java.util.Scanner;
public class Client2 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String uname=input.nextLine();
        System.out.println("请输入密码:");
        String pwd= input.next();
        //创建接口的实现类对象
        UserDao userDao=new UserDaoImpl2();
        boolean b = userDao.queryByUser(uname, pwd);
        System.out.println(b?"登录成功":"对不起,账号或密码不正确");
    }
}

第三节 分层开发

分层开发:
三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。

界面层 :通常是html+css 【用于获取用户的数据,并显示响应结果】
目前咱们使用到的就是Scanner ,获取用户的输入…。

在当前的项目中,这个界面如上所示 ,该类Client2需在编写在com.bjsxt.test包中
业务逻辑层 : 用于处理业务逻辑需要求,比如说分页查询,前台界页传入页数,业务逻辑层需要根据页数计算需要显示数据的范围 【从第几条到第几条】
在当前的项目中,没有业务层
数据访问层:用于跟数据库打交道,需要访问数据库,进行增,删,改,查的操作
1)实体类 -->跟表对应
2)接口 —>编写的项目的功能 比如说,登录(查询) …
3)实现类 —> 真正实现功能的代码写在实现类中 (连数据库,sql语句,获取结果,处理结果)

实体类–>com.bjsxt.entity 包中 User
接口–> com.bjsxt.dao 包中 UserDao
实现类 -->com.bjsxt.dao.impl UserDaoImpl
连接数据库的工具类 -->com.bjsxt.util包中

第四节 ThreadLocal

(1)不使用ThreadLocal实现一个批量删除
一次请求内的三次删除,将创建三个Connection对象,浪费内存空间(因为创建对象和销毁对象都需要时间)
在这里插入图片描述

连接数据库的工具类

//这个看看就行,主要是为了引出下面的代码
import java.sql.*;

public class DBUtil {
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost:3306/syl1105";
    private static final String USERNAME = "root";
    private static final String PWD = "root";

    //获取连接对象
    public static Connection getConn(){
        Connection connection=null;
        try {
            Class.forName(DRIVER);
            connection= DriverManager.getConnection(URL,USERNAME,PWD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  connection;
    }

    //增,删,改除了sql语句不同,剩下都一样,提取增,删,改的通用方法,可变的做参数,不变的作方法体
    public static int executeDML(String sql){
        //获取连接对象
        Connection connection=getConn();
        System.out.println(connection);//批量删除的时候删除的是3条语句,创建了几个connection对象???
        Statement statement=null;
        int result=0;
        //创建sql语句发送器,发送sql语句
        try {
            statement=connection.createStatement();
            result=statement.executeUpdate(sql);

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭
            closeAll(null,statement,connection);
        }
        return result;
    }

    //封装关闭全部的方法
    public static void closeAll(ResultSet resultSet,Statement statement,Connection connection){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        //
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        //
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}

界面层

import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;

/**
 *界面层
 */
public class TestDeleteMore { //测试类 界面层-->业务逻辑层
    public static void main(String[] args) {
        //这里界面层一共做了两件事:【1】获取用户数据
        int[] arr={4,5,6};//4,5,6是需要删除的uid
        UserService userService=new UserServiceImpl();
        //【2】展示结果
        int i = userService.deleteMore(arr);
        System.out.println(i>0?"批量删除成功":"失败");


    }
}

业务逻辑层

**
 *业务层接口
 */
public interface UserService {
    //当前的业务是要处理批量删除
    public int deleteMore(int[] arr);
}
import com.bjsxt.dao.Impl.UserDaoImpl2;
import com.bjsxt.dao.UserDao;
import com.bjsxt.service.UserService;

/**
 * 业务层的实现类
 */
public class UserServiceImpl implements UserService{
    //业务逻辑层-->调用数据访问层
    public int deleteMore(int[] arr) {
        //调用数据访问层
        UserDao userDao=new UserDaoImpl2();
        int result=0;
        //调用删除的方法
        for (int i = 0; i <arr.length ; i++) {
             result = userDao.delete(arr[i]);
            System.out.println(result);
        }
        return result;
    }
}

数据访问层

/**
 * 数据访问层接口
 */
public interface UserDao {
    public boolean queryByUser(String uname,String pwd);
    public int delete(int uid);
}
import com.bjsxt.dao.UserDao;
import com.bjsxt.util.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 *数据访问层实现类
 */
public class UserDaoImpl2 implements UserDao{
    @Override
    public int delete(int uid) {
        //调用DBUtil中删除的公共的方法就可以了
        String sql="delete from t_user where uid="+uid;
        return  DBUtil.executeDML(sql);
    }
    @Override
    public boolean queryByUser(String uname, String pwd) {
        //获取连接
        Connection conn= DBUtil.getConn();
        //预编译的sql语句发送器
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            String sql="select * from t_user where uname=? and pwd=?";
            statement= conn.prepareStatement(sql);
            //给占位符赋值
            statement.setString(1,uname);
            statement.setString(2,pwd);
            System.out.println(sql);
            //到数据库中执行
            resultSet=statement.executeQuery();
            if(resultSet.next()){
                return  true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.closeAll(resultSet,statement,conn);
        }
        return  false;
    }
}

创建了3个connection对象,那么创建了几个请求???

使用ThreadLocal,它有两个这样的方法,都是对局部标量的副本进行操作,这样的话就可以实现共享了。如图所示:

以下是批量删除的业务逻辑层

/**
 *业务层接口
 */
public interface UserService {
    //当前的业务是要处理批量删除
    public int deleteMore(int[] arr);
}

import com.bjsxt.dao.Impl.UserDaoImpl2;
import com.bjsxt.dao.UserDao;
import com.bjsxt.service.UserService;
import com.bjsxt.util.DBUtil;

/**
 * 业务层的实现类
 */
public class UserServiceImpl implements UserService{
    //业务逻辑层-->调用数据访问层
    public int deleteMore(int[] arr) {
        //调用数据访问层
        UserDao userDao=new UserDaoImpl2();
        int result=0;
        //调用删除的方法
        for (int i = 0; i <arr.length ; i++) {
             result = userDao.delete(arr[i]);
            System.out.println(result);
        }
        //实际开发中放到这里是不合适的(以为三层开发的话,只有数据访问层去掉DBUtil),但是目前只能用这个了。
        DBUtil.closeConn();
        System.out.println("连接被关闭");
        return result;
    }
}

数据库工具类

import java.sql.*;

public class DBUtil {
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost:3306/syl1105";
    private static final String USERNAME = "root";
    private static final String PWD = "root";
    //共享对象是Connection对象
    private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();
    //静态成员变量
    private static Connection connection;
    //静态代码块为类的静态变量赋值
    static{
        //从本地线程ThreLocal中获取连接对象
        connection=threadLocal.get();
        if(connection==null){//类加载的时候获取
            connection=getConn();//调用本类中的静态方法,获取连接对象
            threadLocal.set(connection);//放到本地线程中进行共享
        }

    }

    //获取连接对象
    public static Connection getConn(){
        Connection connection=null;
        try {
            Class.forName(DRIVER);
            connection= DriverManager.getConnection(URL,USERNAME,PWD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  connection;
    }

    //增,删,改除了sql语句不同,剩下都一样,提取增,删,改的通用方法,可变的做参数,不变的作方法体
    public static int executeDML(String sql){
        //获取连接对象
        //Connection connection=getConn();
        System.out.println(connection);//批量删除的时候删除的是3条语句,创建了几个connection对象???
        Statement statement=null;
        int result=0;
        //创建sql语句发送器,发送sql语句
        try {
            statement=connection.createStatement();
            result=statement.executeUpdate(sql);

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭
            closeAll(null,statement);
        }
        return result;
    }

    //关闭连接
    public static  void closeConn(){
        if(connection!=null){
            try {
                connection.close();
                //清空本地线程
                threadLocal.set(null);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    //封装全部关闭的方法
    public static void closeAll(ResultSet resultSet,Statement statement){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    //封装关闭全部的方法
    public static void closeAll(ResultSet resultSet,Statement statement,Connection connection){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}

测试类

package com.bjsxt.test;
import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;
public class TestDeleteMore { //测试类,属于界面层 -->业务逻辑层
    public static void main(String[] args) {
        int [] arr={12,13,14};//4,5,6是需要删除数据的uid号
        //
        UserService userService=new UserServiceImpl();
        int i = userService.deleteMore(arr);
        System.out.println("i="+i);
        System.out.println(i>0?"删除成功":"失败");
    }
}

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值