目录
1、在src里面创建一个文件,命名为:database.properties
2、定义实体类:实体类的表名与数据库的表名一致,表中大每一列为实体类的属性
4、由不同数据库的实现类分别实现接口;实现类实现接口并继承数据库工具类
5、将通用的操作(如打开、关闭连接等)封装到工具类数据库工具类
在编写JDBC时存在一些问题:
1、可读性差
2、不利于后期维护和修改
3、不利于代码复用
采用面向接口编程,可以降低代码间的耦合性
JDBC封装:
1、隔离业务逻辑代码和数据访问代码
2、隔离不同数据库的实现
1、定义实体类传输数据
2、将所有增删改查操作抽取
3、由不同数据库的实现类分别实现接口
4、将通用的操作(打开,关闭连接,增删改查等)封装到数据库工具类BaseDao的通用方法中
具体实现:
然后在里面添加一下数据
- # 加载驱动
- driver = com.mysql.jdbc.Driver
- # 数据库地址
- url = jdbc:mysql://127.0.0.1:3306/myschool
- #用户名
- username = root
- #密码
- password = root
- //创建一个年纪类
- 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 + "}";
- }
- }
数据库如下图:

- /**
- * @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);
- }
- /**
- * @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);
- }
- }
对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();
- }
- }
- }
- /**
- * @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("______________________");
- }
- }
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) | 线程安全 |