简体   繁体   English

将派生类存储在数据库中的良好实践

[英]Good practice to store derived classes in the database

I'm writing a simple java application (in study purpose) to manage employees and I need an advise: how to store and retrieve data from the database. 我正在编写一个简单的Java应用程序(出于学习目的)来管理员工,我需要一个建议:如何存储和检索数据库中的数据。

Code, that I have wrote so far is too big to put it here, so, in two words: 到目前为止,我写的代码太大了,无法用两个词来表示:

I have next hierarchy: abstract class Employee: 4 attributes, getters, setters class Salaried: 2 new attribute class Hourly : 2 new attributes class Director: 3 new attributes class Manager : 1 new attribute 我有下一个层次结构:抽象类雇员:4个属性,getters,setters类薪水:2个新属性类每小时:2个新属性类Director:3个新属性类Manager:1个新属性

I have a MySQL data with 1 table (create script): 我有一个带有1个表的MySQL数据(创建脚本):

CREATE TABLE `employee` (
  `SSN` int(9) NOT NULL PRIMARY KEY,
  `FirstName` varchar(20) NOT NULL,
  `LastName` varchar(20) NOT NULL,
  `Department` varchar(20) NOT NULL,
  `Salary` float(10) NULL,
  `OvertimeHours` float(10) NULL,
  `HourlyWage` float(10) NULL,
  `NumberHours` float(10) NULL,
  `Organization` varchar(30) NULL,
  `Bonus` float(10) NULL
);

First 4 fields are general for all employees. 前4个字段对所有员工都是通用的。

Salary and OvertimeHours are attributes of the Salaried class 工资加班时间工资类的属性

HourlyWage and NumberHours are attributes of the Hourly class HourlyWageNumberHoursHourly类的属性

Salary , Bonus and Organization are attributes of the Director class 薪金奖金组织Director类的属性

Salary also is a attribute of the Manager class 薪金也是Manager类的一个属性

I've created a static class Database to work with the MySQL. 我创建了一个静态类Database与MySQL一起使用。

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;


public abstract class Database {
    // constants
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String DBNAME = "records";
    private static final String DBUSER = "root";
    private static final String DBPASS = "";
    private static final String CONURL = "jdbc:mysql://localhost/" + DBNAME;

    // class attributes
    private static Connection connection = null;


    public static boolean fillEmployee(Employee emp, int ssn)
    {
        try {
            PreparedStatement stm = connection.prepareStatement(
                "SELECT FirstName, LastName, Department "
              + "FROM employee "
              + "WHERE SSN = ?"
            );

            stm.setInt(1, ssn);

            ResultSet rs = stm.executeQuery();

            if(!rs.next())
                return false;

            emp.setSocialSecurity(ssn);
            emp.setFirstName(rs.getString("FirstName"));
            emp.setLastName(rs.getString("LastName"));
            emp.setDepartment(rs.getString("Department"));

            stm.close();
            rs.close();

        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.exit(0);
        }
        return true;
    }


    public static boolean deleteEmployee(int ssn){
        try {
            PreparedStatement stm = connection.prepareStatement(
                "DELETE "
              + "FROM employee "
              + "WHERE SSN = ?"
            );

            stm.setInt(1, ssn);
            return (stm.executeUpdate() == 1);

        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.exit(0);
        }
        return false;
    }


    // class methods
    public static Salaried getSalariedEmployee(int ssn){
        Salaried employee = new Salaried();
        try {

            if(!fillEmployee(employee, ssn))
                return null;

            PreparedStatement stm = connection.prepareStatement(
                "SELECT Salary, OvertimeHours "
              + "FROM employee "
              + "WHERE SSN = ?"
            );

            stm.setInt(1, ssn);
            ResultSet rs = stm.executeQuery();

            employee.setSalary(rs.getFloat("Salary"));
            employee.setOvertimeHours(rs.getFloat("OvertimeHours"));

            stm.close();
            rs.close();

        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            System.exit(0);
        }
        return employee;
    }

    public static void createConnection() {
        if (connection !=  null) 
            return;

        try {

            Class.forName(DRIVER);
            connection = DriverManager.getConnection(CONURL, DBUSER, DBPASS);

        } catch (Exception e) {

            System.out.println(e.getMessage());
            System.exit(0);

        }
    }

    public static void closeConnection(){
        if (connection == null) 
            return;

        try{

            connection.close();
            connection = null;

        } catch (Exception e) {

            System.out.println(e.getMessage());
            System.exit(0);

        }
    }
}

What are you thinking about getSalariedEmployee and fillEmployee methods? 您如何看待getSalariedEmployeefillEmployee方法? How can I improve the overall design and architecture of my application? 如何改善应用程序的整体设计和体系结构?

I think you could wait for creating the employee object in getSalariedEmployee. 我认为您可以等待在getSalariedEmployee中创建employee对象。 instantiate it only if you find the db object. 仅在找到db对象时实例化它。 Because if you return null when not finding it, you still create the employee object. 因为如果找不到时返回null,则仍会创建employee对象。

Perhaps you should start with a good reading of the book Patterns of Enterprise Architecture . 也许您应该首先阅读《企业体系结构模式 》一书。 It has a good chapter covering the different ways in which we typically deal with the database. 它有一章很好,涵盖了我们通常处理数据库的不同方式。

You can read quick definitions of these in the companion web site: 您可以在随附的网站上阅读这些的快速定义:

All the patterns have advantages and disadvantages and some of them have entire frameworks that help you write code for them. 所有模式都有优点和缺点,其中一些具有完整的框架,可帮助您为它们编写代码。

The first thing I would do is stop using static methods for all your Database functions. 我要做的第一件事是停止对所有数据库功能使用静态方法。 Also why is Database an abstract class? 还有为什么数据库是抽象类? Is there another class that extends Database with specific implementations (like MyDatabase or OracleDatabase. 是否有另一个类可以使用特定的实现(例如MyDatabase或OracleDatabase)来扩展Database。

You might consider using static methods to return an instance of a Database and then convert the static methods to public instance methods. 您可能考虑使用静态方法返回数据库的实例,然后将静态方法转换为公共实例方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM