JDBC的封装

导读:本篇文章讲解 JDBC的封装,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

JDBC封装的步骤:

1、在src里面创建一个文件,命名为:database.properties

2、定义实体类:实体类的表名与数据库的表名一致,表中大每一列为实体类的属性

3、将用户对象的所有操作抽取成接口

4、由不同数据库的实现类分别实现接口;实现类实现接口并继承数据库工具类

5、将通用的操作(如打开、关闭连接等)封装到工具类数据库工具类

6、在测试类进行测试

 7、单例模式



在编写JDBC时存在一些问题:

1、可读性差

2、不利于后期维护和修改

3、不利于代码复用

采用面向接口编程,可以降低代码间的耦合性

JDBC封装:

1、隔离业务逻辑代码和数据访问代码

2、隔离不同数据库的实现

JDBC封装的步骤:

1、定义实体类传输数据

2、将所有增删改查操作抽取

3、由不同数据库的实现类分别实现接口

4、将通用的操作(打开,关闭连接,增删改查等)封装到数据库工具类BaseDao的通用方法中

具体实现:

1、在src里面创建一个文件,命名为:database.properties

然后在里面添加一下数据

# 加载驱动
driver = com.mysql.jdbc.Driver
# 数据库地址
url = jdbc:mysql://127.0.0.1:3306/myschool
#用户名
username = root
#密码
password = root

2、定义实体类:实体类的表名与数据库的表名一致,表中大每一列为实体类的属性

//创建一个年纪类
public class Grade {
    /**
     * 年纪编号
     */
    private int gradeId;
    /**
     * 年假名称
     */
    private String gradeName;

    public Grade() {
    }

    public Grade(int gradeId, String gradeName) {
        this.gradeId = gradeId;
        this.gradeName = gradeName;
    }

    /**
     * 获取
     * @return gradeId
     */
    public int getGradeId() {
        return gradeId;
    }

    /**
     * 设置
     * @param gradeId
     */
    public void setGradeId(int gradeId) {
        this.gradeId = gradeId;
    }

    /**
     * 获取
     * @return gradeName
     */
    public String getGradeName() {
        return gradeName;
    }

    /**
     * 设置
     * @param gradeName
     */
    public void setGradeName(String gradeName) {
        this.gradeName = gradeName;
    }
    @Override
    public String toString() {
        return "Grade{gradeId = " + gradeId + ", gradeName = " + gradeName + "}";
    }
}

数据库如下图:

JDBC的封装

3、将用户对象的所有操作抽取成接口

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author 
 * @date 2022-09-12 21:35:49
 * @version 1.0.0
 * @description 将年纪对象的所有操作抽取成接口
 * 实现对数据库的增删改查
 */

public interface GradeDao {
    /**
     * @description 查询班级信息
     * key为空查询所有班级信息
     * key有值,根据key值进行模糊查询
     * @author
     * @date 2022-09-09 11:41:14
     * @param key 进行模糊查询的关键字
     * @return {@link List< Grade>}
     */
     List<Grade> getALL(String key);
     /**
      * @description 添加数据
      * @author
      * @date 2022-09-09 11:41:18
      * @param grade 年纪对象
      * @return {@link int}
      */
     int insertGrade(Grade grade);
     /**
      * @description 修改数据
      * @author
      * @date 2022-09-09 11:41:23
      * @param grade 年纪对象
      * @return {@link int}
      */
     int updateGrade(Grade grade);
     /**
      * @description 删除数据
      * @author
      * @date 2022-09-09 11:41:26
      * @param gradeId 年纪ID
      * @return {@link int}
      */
     int deleteGrade(int gradeId);
}

4、由不同数据库的实现类分别实现接口实现类实现接口并继承数据库工具类

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author 齐孟伟
 * @date 2022-09-12 21:58:38
 * @version 1.0.0
 * @description 数据库的实现类分别实现接口
 */

public class GradeDaoImpl extends BaseDao implements GradeDao {
    /**
     * @description 查询班级信息
     * key为空查询所有班级信息
     * key有值,根据key值进行模糊查询
     * @author
     * @date 2022-09-09 11:41:14
     * @param key 进行模糊查询的关键字
     * @return {@link List< Grade>}
     */
    @Override
    public List<Grade> getALL(String key) {
        //sql语句
        String sql = "SELECT * FROM GRADE WHERE GRADENAME LIKE CONCAT('%',?,'%')";
        //将获取的key放进数组
        Object [] obj = {key};
        //处理返回结果
        ResultSet resultSet = this.select(sql,obj);
        //创建年纪对象
        Grade grade = null;
        //创建数组用来存储年纪对象
        List<Grade> gradeList = new ArrayList<>();
        try{
            //resultSet.next():判断返回结果是否有值
            while (resultSet.next()){
                grade = new Grade();
                //获取数据库表的内容,这里的1可以是获取到表的列名,1表示第一列,2,表是第二列要有顺序
                grade.setGradeId(resultSet.getInt(1));
                grade.setGradeName(resultSet.getString(2));

                gradeList.add(grade);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭资源
            this.close(resultSet);
        }
        return gradeList;
    }
    /**
     * @description 添加数据
     * @author
     * @date 2022-09-09 11:41:18
     * @param grade 年纪对象
     * @return {@link int}
     */
    @Override
    public int insertGrade(Grade grade) {
        //sql语句
        String sql = "INSERT INTO GRADE(GRADEID, GRADENAME) VALUES (?,?)";
        //将对象的属性值添加到 数组中
        Object [] obj = {grade.getGradeId(),grade.getGradeName()};
        //调用 添加数据的方法
        return this.update(sql,obj);
    }
    /**
     * @description 修改数据
     * @author
     * @date 2022-09-09 11:41:23
     * @param grade 年纪对象
     * @return {@link int}
     */
    @Override
    public int updateGrade(Grade grade) {
        //sql语句
        String sql = "UPDATE GRADE SET GRADENAME = ? WHERE GRADEID = ?";
        //将对象的属性值添加到 数组中
        Object [] obj = {grade.getGradeName(),grade.getGradeId()};
        //调用 添加数据的方法
        return this.update(sql,obj);
    }
    /**
     * @description 删除数据
     * @author
     * @date 2022-09-09 11:41:26
     * @param gradeId 年纪ID
     * @return {@link int}
     */
    @Override
    public int deleteGrade(int gradeId) {
        //sql语句
        String sql = "DELETE FROM GRADE WHERE GRADEID = ?";
        //将对象的属性值添加到 数组中
        Object [] obj = {gradeId};
        //调用 添加数据的方法
        return this.update(sql,obj);
    }
}

5、将通用的操作(如打开、关闭连接等)封装到工具类数据库工具类

        对BaseDao:增、删、改的通用方法

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author
 * @date 2022-09-12 22:01:34
 * @version 1.0.0
 * @description 将通用的操作(如打开、关闭连接等)封装到工具类
 */

public class BaseDao {
    /**
     * 获取驱动
     */
    Connection connection = null;
    /**
     * 连接数据库并进行操作
     */
    PreparedStatement preparedStatement = null;
    /**
     * 处理返回结果
     */
    ResultSet resultSet = null;
    /**
     * @description 获取驱动
     * @author
     * @date 2022-09-09 11:50:58
     * @param
     * @return {@link Connection}
     */
    public Connection getConnection(){
        //根据指定的键获取对应的值
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        // 获取驱动
        String driver = dataSourceConfig.getProperty("driver");
        // 获取数据库地址
        String url = dataSourceConfig.getProperty("url");
        // 获取用户名
        String username = dataSourceConfig.getProperty("username");
        // 获取密码
        String password = dataSourceConfig.getProperty("password");

        try {
            //加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url,username,password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return connection;
    }
    /**
     * @description 查询班级信息
     *      key为空查询所有班级信息
     *      key有值,根据key值进行模糊查询
     * @author
     * @date 2022-09-09 11:54:58
     * @param sql sql语句
     * @param obj key值
     * @return {@link ResultSet}
     */
    public ResultSet select(String sql, Object[] obj){
        this.getConnection();
        try {
            preparedStatement = connection.prepareStatement(sql);
            //若传过来obj不为空,则解析参数集合
            if (obj != null && obj.length > 0){
                for (int i = 0; i < obj.length; i++) {
                    //对问号传参
                    preparedStatement.setObject((i + 1),obj[i]);
                }
            }
            resultSet = preparedStatement.executeQuery();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return resultSet;
    }
    /**
     * @description 对数据进行添加修改删除
     * @author
     * @date 2022-09-09 11:57:54
     * @param sql sql语句
     * @param obj key值
     * @return {@link int}
     */
    public int update(String sql, Object[] obj){
        //
        this.getConnection();
        int count = 0;
        try {
            preparedStatement = connection.prepareStatement(sql);
            if (obj != null && obj.length > 0){
                for (int i = 0; i < obj.length; i++) {
                    preparedStatement.setObject((i + 1),obj [i]);
                }
            }
            count = preparedStatement.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            close(resultSet);
        }
        return count;
    }
    /**
     * @description 关闭资源
     * @author
     * @date 2022-09-12 22:00:57
     * @param res 
     * @return
     */
    public void close(ResultSet res){
        try {
            if (res != null){
                res.close();
            }
            if (resultSet != null){
                resultSet.close();
            }
            if (preparedStatement != null){
                preparedStatement.close();
            }
            if (connection != null){
                connection.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

6、在测试类进行测试

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author 齐孟伟
 * @date 2022-09-12 22:20:56
 * @version 1.0.0
 * @description 测试类
 */

public class SchoolSystemApplication {
    public static void main(String[] args) {
        GradeDao gradeDao = new GradeDaoImpl();
        /**
         * 查询
         */
        select("",gradeDao);
        /**
         * 添加数据
         */
        Grade grade = new Grade(6,"第六阶段");
        gradeDao.insertGrade(grade);
        select("",gradeDao);
        /**
         * 修改数据
         */
        // 获取所有的对象
        List<Grade> gradeList = gradeDao.getALL("");
        // 遍历数组
        for (int i = 0; i < gradeList.size(); i++) {
            if (gradeList.get(i).getGradeId() == 6){
                int gradeId = gradeList.get(i).getGradeId();
                String gradeName = "高三";
                Grade grade1 = new Grade(gradeId,gradeName);
                gradeDao.updateGrade(grade1);
            }
        }
        select("",gradeDao);
        /**
         * 删除数据
         */
        gradeDao.deleteGrade(6);
        select("",gradeDao);
    }
    /**
     * @description 遍历集合里的信息
     * @author
     * @date 2022-09-12 22:21:10
     * @param key key值
     * @param gradeDao
     * @return
     */
    public static void select(String key,GradeDao gradeDao){
        List<Grade> gradeList = gradeDao.getALL(key);
        for (int i = 0; i < gradeList.size(); i++) {
            System.out.println(gradeList.get(i).toString());
        }
        System.out.println("______________________");
    }
}

 7、单例模式

 Java中提供了Properties类来读取配置文件

方法名 说明

void load(InputStream inStream)

通过输入流对指定文件进行装载,获取该文件中所有键值对。

String getProperty(String key)

用指定的键在此属性列表中搜索属性。通过参数key得到其所对应的值。

读取配置文件,单独放在一个utils包里

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author
 * @date 2022-09-10 10:47:31
 * @version 1.0.0
 * @description 数据库配置类---读取数据库连接配置
 */

public class DataSourceConfig {
    /**
     * 以类名声明的此类对象
     */
    private static DataSourceConfig dataSourceConfig = null;
    
    Properties properties = null;
    /**
     * @description
     * @author
     * @date 2022-09-10 10:48:02
     * @param
     * @return {@link null}
     */
    public DataSourceConfig(){
        properties = new Properties();
        //配置文件路径
        String configFile = "database.properties";
        //加载配置文件到输入流
        InputStream inputStream = DataSourceConfig.class.getClassLoader().getResourceAsStream(configFile);
        try {
            //从输入流中读取属性列表
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * @description DataSourceConfig判定是否已经被创建
     * 如果创建过,直接返回
     * 如果没有,创建后返回
     * @author
     * @date 2022-09-10 10:45:49
     * @param
     * @return {@link DataSourceConfig}
     */
    public synchronized static DataSourceConfig getInstance(){
        if (dataSourceConfig == null){
            dataSourceConfig = new DataSourceConfig();
        }
        return dataSourceConfig;
    }
    /**
     * @description Properties对象根据传递的key值返回对应的value值
     * @author
     * @date 2022-09-10 10:45:55
     * @param key
     * @return {@link String}
     */
    public String getProperty(String key){

        String value = properties.getProperty(key);
        return value;
    }
}

读取配置文件,把获取驱动部分改为以下代码即可

/**
     * @description 获取驱动
     * @author 
     * @date 2022-09-10 10:52:34
     * @param
     * @return {@link Connection}
     */
    public Connection getConnection(){
        //根据指定的键获取对应的值
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        String driver = dataSourceConfig.getProperty("driver");
        String url = dataSourceConfig.getProperty("url");
        String username = dataSourceConfig.getProperty("username");
        String password = dataSourceConfig.getProperty("password");

        try {
            //加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url,username,password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return connection;
    }

此模式称为单例模式:系统运行期间,有且仅有一个实例

1、它必须自行创建这个实例

2、定义了静态的该类私有对象

3、一个类只有一个实例——最基本的要求

4、只提供私有构造器

5、它必须自行向整个系统提供这个实例

6、提供一个静态的公有方法,返回创建或者获取本身的静态私有对象

懒汉模式:在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例。

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author
 * @date 2022-09-17 16:43:22
 * @version 1.0.0
 * @description 懒汉模式:在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例。
 */

public class DataScoreConfig {
    /**
     * DataSourceConfig类的声明
     */
    private static DataScoreConfig dataScoreConfig = null;
    /**
     * Properties类的文件处理引用
     */
    Properties properties = null;
    /**
     * @description 私有话构造方法
     * @author
     * @date 2022-09-17 16:53:13
     * @param
     * @return {@link null}
     */
    public DataScoreConfig(){
        properties = new Properties();
        String configFile = "database.properties";
        InputStream inputStream = DataScoreConfig.class.getClassLoader().getResourceAsStream(configFile);
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * @description
     * 查看dataSourceConfig是否为空
     * 为空则重新创建引用
     * 不为空直接返回
     * @author
     * @date 2022-09-17 16:53:05
     * @param
     * @return {@link DataScoreConfig}
     */
    public static synchronized DataScoreConfig getInstance(){
        if (dataScoreConfig == null){
            dataScoreConfig = new DataScoreConfig();
        }
        return dataScoreConfig;
    }
    /**
     * @description
     * 通过properties对象的getProperty方法
     * 获取database.properties文件中的对应可以的值
     * @author
     * @date 2022-09-17 16:53:01
     * @param key
     * @return {@link String}
     */
    public String getProperty(String key){
        String value = properties.getProperty(key);
        return value;
    }

饿汉模式:在类加载的时候,就完成初始化

/**
 * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
 * @author
 * @date 2022-09-17 16:43:22
 * @version 1.0.0
 * @description 饿汉模式:在类加载的时候,就完成初始化
 */

public class DataScoreConfig {
    /**
     * DataSourceConfig类的声明
     */
    private static DataScoreConfig dataScoreConfig = new DataScoreConfig;
    /**
     * Properties类的文件处理引用
     */
    Properties properties = null;
    /**
     * @description 私有话构造方法
     * @author
     * @date 2022-09-17 16:53:13
     * @param
     * @return {@link null}
     */
    public DataScoreConfig(){
        properties = new Properties();
        String configFile = "database.properties";
        InputStream inputStream =                                     
         DataScoreConfig.class.getClassLoader().getResourceAsStream(configFile);
        try {
            properties.load(inputStream);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * @description
     * 查看dataSourceConfig是否为空
     * 为空则重新创建引用
     * 不为空直接返回
     * @author
     * @date 2022-09-17 16:53:05
     * @param
     * @return {@link DataScoreConfig}
     */
    public static DataScoreConfig getInstance(){
        return dataScoreConfig;
    }
    /**
     * @description
     * 通过properties对象的getProperty方法
     * 获取database.properties文件中的对应可以的值
     * @author
     * @date 2022-09-17 16:53:01
     * @param key
     * @return {@link String}
     */
    public String getProperty(String key){
        String value = properties.getProperty(key);
        return value;
    }

注意: 在整个程序运行期间,有且仅有一个实例。若违背这一点,所设计的类就不是单例类

单例模式 懒汉模式 饿汉模式
概念

在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例

在类加载的时候,就完成初始化

特点

类加载速度快,但是运行时获取对象的速度较慢——时间换空间

类加载较慢,但获取对象速度快——空间换时间

延迟加载

具备

不具备

线程安全

线程不安全,解决方法使用同步(synchronized

线程安全

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/93358.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!