• JDBC的封装


    目录

    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

    然后在里面添加一下数据

    1. # 加载驱动
    2. driver = com.mysql.jdbc.Driver
    3. # 数据库地址
    4. url = jdbc:mysql://127.0.0.1:3306/myschool
    5. #用户名
    6. username = root
    7. #密码
    8. password = root

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

    1. //创建一个年纪类
    2. public class Grade {
    3. /**
    4. * 年纪编号
    5. */
    6. private int gradeId;
    7. /**
    8. * 年假名称
    9. */
    10. private String gradeName;
    11. public Grade() {
    12. }
    13. public Grade(int gradeId, String gradeName) {
    14. this.gradeId = gradeId;
    15. this.gradeName = gradeName;
    16. }
    17. /**
    18. * 获取
    19. * @return gradeId
    20. */
    21. public int getGradeId() {
    22. return gradeId;
    23. }
    24. /**
    25. * 设置
    26. * @param gradeId
    27. */
    28. public void setGradeId(int gradeId) {
    29. this.gradeId = gradeId;
    30. }
    31. /**
    32. * 获取
    33. * @return gradeName
    34. */
    35. public String getGradeName() {
    36. return gradeName;
    37. }
    38. /**
    39. * 设置
    40. * @param gradeName
    41. */
    42. public void setGradeName(String gradeName) {
    43. this.gradeName = gradeName;
    44. }
    45. @Override
    46. public String toString() {
    47. return "Grade{gradeId = " + gradeId + ", gradeName = " + gradeName + "}";
    48. }
    49. }

    数据库如下图:

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

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author
    4. * @date 2022-09-12 21:35:49
    5. * @version 1.0.0
    6. * @description 将年纪对象的所有操作抽取成接口
    7. * 实现对数据库的增删改查
    8. */
    9. public interface GradeDao {
    10. /**
    11. * @description 查询班级信息
    12. * key为空查询所有班级信息
    13. * key有值,根据key值进行模糊查询
    14. * @author
    15. * @date 2022-09-09 11:41:14
    16. * @param key 进行模糊查询的关键字
    17. * @return {@link List< Grade>}
    18. */
    19. List<Grade> getALL(String key);
    20. /**
    21. * @description 添加数据
    22. * @author
    23. * @date 2022-09-09 11:41:18
    24. * @param grade 年纪对象
    25. * @return {@link int}
    26. */
    27. int insertGrade(Grade grade);
    28. /**
    29. * @description 修改数据
    30. * @author
    31. * @date 2022-09-09 11:41:23
    32. * @param grade 年纪对象
    33. * @return {@link int}
    34. */
    35. int updateGrade(Grade grade);
    36. /**
    37. * @description 删除数据
    38. * @author
    39. * @date 2022-09-09 11:41:26
    40. * @param gradeId 年纪ID
    41. * @return {@link int}
    42. */
    43. int deleteGrade(int gradeId);
    44. }

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

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author 齐孟伟
    4. * @date 2022-09-12 21:58:38
    5. * @version 1.0.0
    6. * @description 数据库的实现类分别实现接口
    7. */
    8. public class GradeDaoImpl extends BaseDao implements GradeDao {
    9. /**
    10. * @description 查询班级信息
    11. * key为空查询所有班级信息
    12. * key有值,根据key值进行模糊查询
    13. * @author
    14. * @date 2022-09-09 11:41:14
    15. * @param key 进行模糊查询的关键字
    16. * @return {@link List< Grade>}
    17. */
    18. @Override
    19. public List<Grade> getALL(String key) {
    20. //sql语句
    21. String sql = "SELECT * FROM GRADE WHERE GRADENAME LIKE CONCAT('%',?,'%')";
    22. //将获取的key放进数组
    23. Object [] obj = {key};
    24. //处理返回结果
    25. ResultSet resultSet = this.select(sql,obj);
    26. //创建年纪对象
    27. Grade grade = null;
    28. //创建数组用来存储年纪对象
    29. List<Grade> gradeList = new ArrayList<>();
    30. try{
    31. //resultSet.next():判断返回结果是否有值
    32. while (resultSet.next()){
    33. grade = new Grade();
    34. //获取数据库表的内容,这里的1可以是获取到表的列名,1表示第一列,2,表是第二列要有顺序
    35. grade.setGradeId(resultSet.getInt(1));
    36. grade.setGradeName(resultSet.getString(2));
    37. gradeList.add(grade);
    38. }
    39. }catch (Exception e){
    40. e.printStackTrace();
    41. }finally {
    42. //关闭资源
    43. this.close(resultSet);
    44. }
    45. return gradeList;
    46. }
    47. /**
    48. * @description 添加数据
    49. * @author
    50. * @date 2022-09-09 11:41:18
    51. * @param grade 年纪对象
    52. * @return {@link int}
    53. */
    54. @Override
    55. public int insertGrade(Grade grade) {
    56. //sql语句
    57. String sql = "INSERT INTO GRADE(GRADEID, GRADENAME) VALUES (?,?)";
    58. //将对象的属性值添加到 数组中
    59. Object [] obj = {grade.getGradeId(),grade.getGradeName()};
    60. //调用 添加数据的方法
    61. return this.update(sql,obj);
    62. }
    63. /**
    64. * @description 修改数据
    65. * @author
    66. * @date 2022-09-09 11:41:23
    67. * @param grade 年纪对象
    68. * @return {@link int}
    69. */
    70. @Override
    71. public int updateGrade(Grade grade) {
    72. //sql语句
    73. String sql = "UPDATE GRADE SET GRADENAME = ? WHERE GRADEID = ?";
    74. //将对象的属性值添加到 数组中
    75. Object [] obj = {grade.getGradeName(),grade.getGradeId()};
    76. //调用 添加数据的方法
    77. return this.update(sql,obj);
    78. }
    79. /**
    80. * @description 删除数据
    81. * @author
    82. * @date 2022-09-09 11:41:26
    83. * @param gradeId 年纪ID
    84. * @return {@link int}
    85. */
    86. @Override
    87. public int deleteGrade(int gradeId) {
    88. //sql语句
    89. String sql = "DELETE FROM GRADE WHERE GRADEID = ?";
    90. //将对象的属性值添加到 数组中
    91. Object [] obj = {gradeId};
    92. //调用 添加数据的方法
    93. return this.update(sql,obj);
    94. }
    95. }

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

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

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author
    4. * @date 2022-09-12 22:01:34
    5. * @version 1.0.0
    6. * @description 将通用的操作(如打开、关闭连接等)封装到工具类
    7. */
    8. public class BaseDao {
    9. /**
    10. * 获取驱动
    11. */
    12. Connection connection = null;
    13. /**
    14. * 连接数据库并进行操作
    15. */
    16. PreparedStatement preparedStatement = null;
    17. /**
    18. * 处理返回结果
    19. */
    20. ResultSet resultSet = null;
    21. /**
    22. * @description 获取驱动
    23. * @author
    24. * @date 2022-09-09 11:50:58
    25. * @param
    26. * @return {@link Connection}
    27. */
    28. public Connection getConnection(){
    29. //根据指定的键获取对应的值
    30. DataSourceConfig dataSourceConfig = new DataSourceConfig();
    31. // 获取驱动
    32. String driver = dataSourceConfig.getProperty("driver");
    33. // 获取数据库地址
    34. String url = dataSourceConfig.getProperty("url");
    35. // 获取用户名
    36. String username = dataSourceConfig.getProperty("username");
    37. // 获取密码
    38. String password = dataSourceConfig.getProperty("password");
    39. try {
    40. //加载驱动
    41. Class.forName("com.mysql.jdbc.Driver");
    42. connection = DriverManager.getConnection(url,username,password);
    43. } catch (ClassNotFoundException e) {
    44. e.printStackTrace();
    45. } catch (SQLException throwables) {
    46. throwables.printStackTrace();
    47. }
    48. return connection;
    49. }
    50. /**
    51. * @description 查询班级信息
    52. * key为空查询所有班级信息
    53. * key有值,根据key值进行模糊查询
    54. * @author
    55. * @date 2022-09-09 11:54:58
    56. * @param sql sql语句
    57. * @param obj key值
    58. * @return {@link ResultSet}
    59. */
    60. public ResultSet select(String sql, Object[] obj){
    61. this.getConnection();
    62. try {
    63. preparedStatement = connection.prepareStatement(sql);
    64. //若传过来obj不为空,则解析参数集合
    65. if (obj != null && obj.length > 0){
    66. for (int i = 0; i < obj.length; i++) {
    67. //对问号传参
    68. preparedStatement.setObject((i + 1),obj[i]);
    69. }
    70. }
    71. resultSet = preparedStatement.executeQuery();
    72. } catch (SQLException throwables) {
    73. throwables.printStackTrace();
    74. }
    75. return resultSet;
    76. }
    77. /**
    78. * @description 对数据进行添加修改删除
    79. * @author
    80. * @date 2022-09-09 11:57:54
    81. * @param sql sql语句
    82. * @param obj key值
    83. * @return {@link int}
    84. */
    85. public int update(String sql, Object[] obj){
    86. //
    87. this.getConnection();
    88. int count = 0;
    89. try {
    90. preparedStatement = connection.prepareStatement(sql);
    91. if (obj != null && obj.length > 0){
    92. for (int i = 0; i < obj.length; i++) {
    93. preparedStatement.setObject((i + 1),obj [i]);
    94. }
    95. }
    96. count = preparedStatement.executeUpdate();
    97. } catch (SQLException throwables) {
    98. throwables.printStackTrace();
    99. }finally {
    100. close(resultSet);
    101. }
    102. return count;
    103. }
    104. /**
    105. * @description 关闭资源
    106. * @author
    107. * @date 2022-09-12 22:00:57
    108. * @param res
    109. * @return
    110. */
    111. public void close(ResultSet res){
    112. try {
    113. if (res != null){
    114. res.close();
    115. }
    116. if (resultSet != null){
    117. resultSet.close();
    118. }
    119. if (preparedStatement != null){
    120. preparedStatement.close();
    121. }
    122. if (connection != null){
    123. connection.close();
    124. }
    125. }catch (Exception e){
    126. e.printStackTrace();
    127. }
    128. }
    129. }

    6、在测试类进行测试

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author 齐孟伟
    4. * @date 2022-09-12 22:20:56
    5. * @version 1.0.0
    6. * @description 测试类
    7. */
    8. public class SchoolSystemApplication {
    9. public static void main(String[] args) {
    10. GradeDao gradeDao = new GradeDaoImpl();
    11. /**
    12. * 查询
    13. */
    14. select("",gradeDao);
    15. /**
    16. * 添加数据
    17. */
    18. Grade grade = new Grade(6,"第六阶段");
    19. gradeDao.insertGrade(grade);
    20. select("",gradeDao);
    21. /**
    22. * 修改数据
    23. */
    24. // 获取所有的对象
    25. List<Grade> gradeList = gradeDao.getALL("");
    26. // 遍历数组
    27. for (int i = 0; i < gradeList.size(); i++) {
    28. if (gradeList.get(i).getGradeId() == 6){
    29. int gradeId = gradeList.get(i).getGradeId();
    30. String gradeName = "高三";
    31. Grade grade1 = new Grade(gradeId,gradeName);
    32. gradeDao.updateGrade(grade1);
    33. }
    34. }
    35. select("",gradeDao);
    36. /**
    37. * 删除数据
    38. */
    39. gradeDao.deleteGrade(6);
    40. select("",gradeDao);
    41. }
    42. /**
    43. * @description 遍历集合里的信息
    44. * @author
    45. * @date 2022-09-12 22:21:10
    46. * @param key key值
    47. * @param gradeDao
    48. * @return
    49. */
    50. public static void select(String key,GradeDao gradeDao){
    51. List<Grade> gradeList = gradeDao.getALL(key);
    52. for (int i = 0; i < gradeList.size(); i++) {
    53. System.out.println(gradeList.get(i).toString());
    54. }
    55. System.out.println("______________________");
    56. }
    57. }

     7、单例模式

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

    方法名说明

    void load(InputStream inStream)

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

    String getProperty(String key)

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

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

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author
    4. * @date 2022-09-10 10:47:31
    5. * @version 1.0.0
    6. * @description 数据库配置类---读取数据库连接配置
    7. */
    8. public class DataSourceConfig {
    9. /**
    10. * 以类名声明的此类对象
    11. */
    12. private static DataSourceConfig dataSourceConfig = null;
    13. Properties properties = null;
    14. /**
    15. * @description
    16. * @author
    17. * @date 2022-09-10 10:48:02
    18. * @param
    19. * @return {@link null}
    20. */
    21. public DataSourceConfig(){
    22. properties = new Properties();
    23. //配置文件路径
    24. String configFile = "database.properties";
    25. //加载配置文件到输入流
    26. InputStream inputStream = DataSourceConfig.class.getClassLoader().getResourceAsStream(configFile);
    27. try {
    28. //从输入流中读取属性列表
    29. properties.load(inputStream);
    30. } catch (IOException e) {
    31. e.printStackTrace();
    32. }
    33. }
    34. /**
    35. * @description DataSourceConfig判定是否已经被创建
    36. * 如果创建过,直接返回
    37. * 如果没有,创建后返回
    38. * @author
    39. * @date 2022-09-10 10:45:49
    40. * @param
    41. * @return {@link DataSourceConfig}
    42. */
    43. public synchronized static DataSourceConfig getInstance(){
    44. if (dataSourceConfig == null){
    45. dataSourceConfig = new DataSourceConfig();
    46. }
    47. return dataSourceConfig;
    48. }
    49. /**
    50. * @description Properties对象根据传递的key值返回对应的value值
    51. * @author
    52. * @date 2022-09-10 10:45:55
    53. * @param key
    54. * @return {@link String}
    55. */
    56. public String getProperty(String key){
    57. String value = properties.getProperty(key);
    58. return value;
    59. }
    60. }

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

    1. /**
    2. * @description 获取驱动
    3. * @author
    4. * @date 2022-09-10 10:52:34
    5. * @param
    6. * @return {@link Connection}
    7. */
    8. public Connection getConnection(){
    9. //根据指定的键获取对应的值
    10. DataSourceConfig dataSourceConfig = new DataSourceConfig();
    11. String driver = dataSourceConfig.getProperty("driver");
    12. String url = dataSourceConfig.getProperty("url");
    13. String username = dataSourceConfig.getProperty("username");
    14. String password = dataSourceConfig.getProperty("password");
    15. try {
    16. //加载驱动
    17. Class.forName("com.mysql.jdbc.Driver");
    18. connection = DriverManager.getConnection(url,username,password);
    19. } catch (ClassNotFoundException e) {
    20. e.printStackTrace();
    21. } catch (SQLException throwables) {
    22. throwables.printStackTrace();
    23. }
    24. return connection;
    25. }

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

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

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

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

    4、只提供私有构造器

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

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

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

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author
    4. * @date 2022-09-17 16:43:22
    5. * @version 1.0.0
    6. * @description 懒汉模式:在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例。
    7. */
    8. public class DataScoreConfig {
    9. /**
    10. * DataSourceConfig类的声明
    11. */
    12. private static DataScoreConfig dataScoreConfig = null;
    13. /**
    14. * Properties类的文件处理引用
    15. */
    16. Properties properties = null;
    17. /**
    18. * @description 私有话构造方法
    19. * @author
    20. * @date 2022-09-17 16:53:13
    21. * @param
    22. * @return {@link null}
    23. */
    24. public DataScoreConfig(){
    25. properties = new Properties();
    26. String configFile = "database.properties";
    27. InputStream inputStream = DataScoreConfig.class.getClassLoader().getResourceAsStream(configFile);
    28. try {
    29. properties.load(inputStream);
    30. } catch (IOException e) {
    31. e.printStackTrace();
    32. }
    33. }
    34. /**
    35. * @description
    36. * 查看dataSourceConfig是否为空
    37. * 为空则重新创建引用
    38. * 不为空直接返回
    39. * @author
    40. * @date 2022-09-17 16:53:05
    41. * @param
    42. * @return {@link DataScoreConfig}
    43. */
    44. public static synchronized DataScoreConfig getInstance(){
    45. if (dataScoreConfig == null){
    46. dataScoreConfig = new DataScoreConfig();
    47. }
    48. return dataScoreConfig;
    49. }
    50. /**
    51. * @description
    52. * 通过properties对象的getProperty方法
    53. * 获取database.properties文件中的对应可以的值
    54. * @author
    55. * @date 2022-09-17 16:53:01
    56. * @param key
    57. * @return {@link String}
    58. */
    59. public String getProperty(String key){
    60. String value = properties.getProperty(key);
    61. return value;
    62. }

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

    1. /**
    2. * @authorDesc 乾坤未定, 你我皆是黑马.乾坤已定, 那就扭转乾坤
    3. * @author
    4. * @date 2022-09-17 16:43:22
    5. * @version 1.0.0
    6. * @description 饿汉模式:在类加载的时候,就完成初始化
    7. */
    8. public class DataScoreConfig {
    9. /**
    10. * DataSourceConfig类的声明
    11. */
    12. private static DataScoreConfig dataScoreConfig = new DataScoreConfig;
    13. /**
    14. * Properties类的文件处理引用
    15. */
    16. Properties properties = null;
    17. /**
    18. * @description 私有话构造方法
    19. * @author
    20. * @date 2022-09-17 16:53:13
    21. * @param
    22. * @return {@link null}
    23. */
    24. public DataScoreConfig(){
    25. properties = new Properties();
    26. String configFile = "database.properties";
    27. InputStream inputStream =
    28. DataScoreConfig.class.getClassLoader().getResourceAsStream(configFile);
    29. try {
    30. properties.load(inputStream);
    31. inputStream.close();
    32. } catch (IOException e) {
    33. e.printStackTrace();
    34. }
    35. }
    36. /**
    37. * @description
    38. * 查看dataSourceConfig是否为空
    39. * 为空则重新创建引用
    40. * 不为空直接返回
    41. * @author
    42. * @date 2022-09-17 16:53:05
    43. * @param
    44. * @return {@link DataScoreConfig}
    45. */
    46. public static DataScoreConfig getInstance(){
    47. return dataScoreConfig;
    48. }
    49. /**
    50. * @description
    51. * 通过properties对象的getProperty方法
    52. * 获取database.properties文件中的对应可以的值
    53. * @author
    54. * @date 2022-09-17 16:53:01
    55. * @param key
    56. * @return {@link String}
    57. */
    58. public String getProperty(String key){
    59. String value = properties.getProperty(key);
    60. return value;
    61. }

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

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

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

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

    特点

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

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

    延迟加载

    具备

    不具备

    线程安全

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

    线程安全

  • 相关阅读:
    MIPI CSI接口调试方法: data rate计算
    探秘Elasticsearch:高性能搜索引擎的原理与应用场景(一)
    简单了解Ajax
    什么是数据描述统计分析?(Descriptive Analysis)
    测试开发是什么?为什么现在那么多公司都要招聘测试开发?
    Spring及Spring boot 第四章-第二节 Spring声明式事务管理 @Transactional
    轻拍牛头(求约数C++)
    js获取地址中携带的省市区
    C++ 语言学习 day02 (linux ) delete 函数 面对对象的类,构造函数,析构函数
    SpringBoot集成redis+cookie实现分布式单点登录
  • 原文地址:https://blog.csdn.net/qi341500/article/details/126786442