JDBC - 结构优化1
文章目录
- JDBC - 结构优化1
- 三层架构
- 1 什么是三层架构
- 2 三层架构项目搭建
- 结构优化1 - 学生信息管理
- 1 封装工具类
- 2 ORM
- 3 DAO
三层架构
1 什么是三层架构
**三层架构:**将程序划分为表示层, 业务逻辑层, 数据访问层三层,各层之间采用接口相互访问,并通过实体类对象作为数据传递的载体。
- 表示(界面)层(User Interface Layer)。
- 业务逻辑(服务)层(Business Logic Layer)。
- 数据访问(持久)层(Data Access Layer)。
**调用关系:**表示层调用业务层,业务层调用数据访问层。
**目的:**是为了实现“高内聚低耦合”的思想。
2 三层架构项目搭建
开发步骤:
- util:存放工具类(DbUtils)
- entity:存放实体类(Book)
- dao:存放 DAO 接口(BookDao)
- impl:存放 DAO 接口实现类(BookDaoImpl)
- service:存放 Service 接口(BookService)
- impl:存放 service 接口实现类(PersonServiceImpl)
- view|ui:存放程序启动类(BookSystem
结构优化1 - 学生信息管理
1 封装工具类
优化1:
- 在JDBC的使用中,连接数据库、关闭连接等存在着大量的重复代码。
- 把传统的JDBC代码进行重构,抽取出通用的JDBC工具类。
重用性方案:
- 封装获取连接方法:
- public static Connection getConnection(){}
- 封装释放资源方法:
- public static void closeAll(Connection conn , Statement sm , ResultSet rs){}
代码演示:
public class DBUtils {// 1 注册驱动static { //静态代码块, 只执行一次try {// 获取驱动对象Class.forName("com.mysql.jdbc.Driver");} catch (Exception e) {e.printStackTrace();}}// 2 获取连接public static Connection getConnection() {Connection connection = null;try {connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb?useSSL=false&characterEncoding=utf-8","root","1234");} catch (SQLException e) {throw new RuntimeException(e);}return connection;}// 3 释放资源public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {try {if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException e) {throw new RuntimeException(e);}}
}
优化2:
- 重用性方案中的参数都是硬编码,当驱动、URL等参数需要更换时,需要重新编译。
- 通过配置文件读取配置信息,使用软编码方式,更灵活的方案。
跨平台方案:
- 创建properties配置文件。
- 创建Properties集合:
- public static final Properties prop = new Properties();
- 静态代码块中,使用输入流,读取配置文件。
代码演示:
DBUtils:
public class DBUtils {private static String url;private static String user;private static String pwd;// 1 注册驱动static {try {// 读取属性配置文件Properties properties = new Properties();FileInputStream fis = new FileInputStream("Properties/db.properties");properties.load(fis);fis.close();// 变量赋值String driver = properties.getProperty("driver");url = properties.getProperty("url");user = properties.getProperty("user");pwd = properties.getProperty("pwd");// 获取驱动对象Class.forName("com.mysql.jdbc.Driver");} catch (Exception e) {e.printStackTrace();}}// 2 获取连接public static Connection getConnection() {try {return DriverManager.getConnection(url,user,pwd);} catch (SQLException e) {throw new RuntimeException(e);}}// 3 释放资源public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {try {if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException e) {throw new RuntimeException(e);}}
}
db.properties:
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mysql?useSSL=false&characterEncoding=utf-8
user = root
pwd = 1234
2 ORM
概念:
- ORM(Object Relational Mapping): 对象关系映射
- 对结果集(ResultSet)遍历时, 取出的都是零散的数据
- 在实际开发中, 我们需要将零散的数据进行封装整理
实体类(Entity)
- 一行数据中, 多个零散的数据进行整理
- 通过entity的规则对表中的数据进行对象的封装
注意:
- 表名=类名; 列名=属性名; 提供个属性的getter和setter方法
- 提供无参构造方法(视情况添加有参构造)
- 包的命名: entity beans domian pojo…
代码演示:
public class Student {private Integer stuId;private String stuName;private Integer stuAge;private String stuGender;private String stuAddress;private Date stuBorn;public Student() {}public Student(Integer stuId, String stuName, Integer stuAge, String stuGender, String stuAddress, Date stuBorn) {this.stuId = stuId;this.stuName = stuName;this.stuAge = stuAge;this.stuGender = stuGender;this.stuAddress = stuAddress;this.stuBorn = stuBorn;}//getter setter方法以及重写toString方法
}
表:
stuId | stuName | stuAge | stuGender | stuAddress | stuBorn |
---|---|---|---|---|---|
1 | 张三 | 24 | 男 | 北京 | 2000-1-1 |
2 | 李四 | 25 | 男 | 哈尔滨 | 1999-1-1 |
实体类与表一一对应:
- 属性 = 列名。
- 属性类型 = 列的类型。
- 提供构造方法、get/set方法。
3 DAO
概念:
- DAO(Data Access Object): 数据访问对象
- DAO实现了用户交互或业务逻辑与数据库访问相分离, 提高代码的重用性
- 对同一张表的所有操作都封装在 XxxDaoImpl对象中
- 根据增删改查提供具体的方法(Insert UPdate Delete Select SelectAll)
代码演示:
Dao接口
public interface StudentDao {void insert(Student student);void update(Student student);void delete(int stuId);List<Student> selectAll();
}
DaoImpl实现类
public class StudentDaoImpl implements StudentDao {@Override// 1 添加数据public void insert(Student student) {Connection connection = null;PreparedStatement preparedStatement = null;try {// 1 获取连接connection = DBUtils.getConnection();// 2 创建预编译命令String sql = "INSERT INTO companydb.student VALUES (NULL,?,?,?,?,?)";preparedStatement = connection.prepareStatement(sql);// 3 参数赋值preparedStatement.setObject(1,student.getStuName());preparedStatement.setObject(2,student.getStuAge());preparedStatement.setObject(3,student.getStuGender());preparedStatement.setObject(4,student.getStuAddress());preparedStatement.setObject(5,student.getStuBorn());// 4 执行命令preparedStatement.executeUpdate();} catch (Exception e) {throw new RuntimeException(e);} finally {//5 关闭DBUtils.closeAll(connection,preparedStatement,null);}}@Override// 2 修改数据public void update(Student student) {Connection connection = null;PreparedStatement preparedStatement = null;try {// 1 获取连接connection = DBUtils.getConnection();// 2 创建预编译命令String sql = "UPDATE companydb.student SET stu_name=?,stu_age=?,stu_gender=?,stu_address=?,stu_born=? where stu_id=?";preparedStatement = connection.prepareStatement(sql);// 3 参数赋值preparedStatement.setObject(1,student.getStuName());preparedStatement.setObject(2,student.getStuAge());preparedStatement.setObject(3,student.getStuGender());preparedStatement.setObject(4,student.getStuAddress());preparedStatement.setObject(5,student.getStuBorn());preparedStatement.setObject(6,student.getStuId());// 4 执行命令preparedStatement.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);} finally {//5 关闭DBUtils.closeAll(connection,preparedStatement,null);}}@Override// 3 删除public void delete(int stuId) {Connection connection = null;PreparedStatement preparedStatement = null;try {// 1 获取连接connection = DBUtils.getConnection();// 2 创建预编译命令String sql = "DELETE FROM companydb.student WHERE stu_id = ?";preparedStatement = connection.prepareStatement(sql);// 3 参数赋值preparedStatement.setObject(1, stuId);// 4 执行命令preparedStatement.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);} finally {//5 关闭DBUtils.closeAll(connection, preparedStatement, null);}}@Override// 4 查询public List<Student> selectAll() {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;ArrayList<Student> list = new ArrayList<>();try {// 1 获取连接connection = DBUtils.getConnection();// 2 创建预编译命令String sql = "SELECT * FROM companydb.student";preparedStatement = connection.prepareStatement(sql);// 3 执行命令resultSet = preparedStatement.executeQuery();// 4 处理while (resultSet.next()) {int stuId = resultSet.getInt("stu_id");String stuName = resultSet.getString("stu_name");int stuAge = resultSet.getInt("stu_age");String stuGender = resultSet.getString("stu_gender");String stuAddress = resultSet.getString("stu_address");java.sql.Date stuBorn = resultSet.getDate("stu_born");Student student = new Student(stuId, stuName, stuAge, stuGender, stuAddress, stuBorn);list.add(student);}System.out.println();} catch (SQLException e) {throw new RuntimeException(e);} finally {// 5 关闭DBUtils.closeAll(connection,preparedStatement,resultSet);}return list;}
}
MyStudentSystem:
public class MyStudentSystem {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);//菜单boolean flag = true;StudentDao studentDao = new StudentDaoImpl();do {System.out.println("1.添加 2.修改 3.删除 4.查询全部数据 0.退出");System.out.println("请选择...");int choose = scanner.nextInt();switch (choose) {case 1:try {studentDao.insert(new Student(0,"刘禅",5,"男","哈尔滨",new Date()));System.out.println("添加成功...");} catch (Exception e) {System.out.println("添加失败...");}break;case 2:try {studentDao.update(new Student(108,"光头强",18,"男","东北",new Date()));System.out.println("修改成功...");} catch (Exception e) {System.out.println("修改失败...");}break;case 3:System.out.println("请输入要删除的学生的stu_id");int stu_id = scanner.nextInt();try {studentDao.delete(stu_id);System.out.println("删除成功...");} catch (Exception e) {System.out.println("删除失败...");}break;case 4:try {List<Student> students = studentDao.selectAll();for (Student student : students) {System.out.println(student.toString());}} catch (Exception e) {System.out.println("查询失败...");}break;case 0:flag = false;break;default:System.out.println("非法输入...");}} while (flag);System.out.println("欢迎再次使用本系统...");}
}