Мне сложно понять, как наследование работает с реляционными базами данных.
Предположим, что у меня есть следующие классы:
public class Train {
private int id;
private String callsign;
private List<Component> components = new ArrayList<Component>();
public Train(){}
public Train(String callsign){
this.callsign = callsign;
}
... getters & setters ...
}
public abstract class Component {
private int id;
private String callsign;
private Train train;
public Component() {
}
public Component(String callsign) {
this.callsign = callsign;
}
... getters & setters ...
}
public class Wagon extends Component{
private int numOfSeats;
public Wagon(String callsign, int numOfSeats) {
super(callsign);
this.numOfSeats = numOfSeats;
}
public Wagon() {
}
... getters & setters ...
}
Поезд создается из компонентов (List), и в этом примере есть несколько подклассов компонентов (только Wagon).
Чтобы этого не произошло, я подумал, что структура Table Per Type Inheritance
будет подходящей, но в этом я столкнулся с проблемами.
Моя структура базы данных:
CREATE TABLE 'Train' (
'id' int(11) NOT NULL,
'callsign' varchar(255) DEFAULT NULL,
PRIMARY KEY ('id'),
UNIQUE KEY 'UK_callsign_train' ('callsign')
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE 'Component' (
'id' int(11) NOT NULL,
'callsign' varchar(255) NOT NULL,
'train_FK' int(11) DEFAULT NULL,
PRIMARY KEY ('id'),
UNIQUE KEY 'UK_callsign_comp' ('callsign'),
KEY 'FK_comp_train' ('train_FK'),
CONSTRAINT 'FK_comp_train' FOREIGN KEY ('train_FK') REFERENCES 'Train' ('id')
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE 'Wagon' (
'numOfSeats' int(11) NOT NULL,
'id' int(11) NOT NULL,
PRIMARY KEY ('id'),
CONSTRAINT 'FK_wagon_comp' FOREIGN KEY ('id') REFERENCES 'Component' ('id')
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Поэтому теперь я хочу создать метод DAO, который возвращает объект Train, включая все его компоненты. Я мог бы запросить поезд по его идентификатору и найти соответствующие компоненты в таблице Component с помощью train_fk, но в этом проблема начинается. В таблице Component
только частично хранятся данные, которые мне нужны (в случае Wagon obj остальная часть информации живет в таблице Wagon
).
В этом случае очевидно, что мне нужно запросить таблицу Wagon
для остальной информации, но что, если у меня больше типов. Как я могу узнать, в какой таблице запрашивать и какой объект обрабатывать?
Я понимаю, что это невозможно с текущей структурой, но как это делается обычно? Каковы стандартные решения для обработки наследования, подобные этому в реляционной базе данных?
Заранее спасибо!
PS: Я пытаюсь сделать это без использования JPA, Hibernate или любой другой структуры, просто JDBC;)
Я бы предложил добавить столбец в таблице Component, который указывает подтип.
Когда вы затем присоединяетесь к поезду с компонентом и всеми подтипами, вы можете идентифицировать на стороне Java то, что вам нужно создать.
Второй вариант может быть аргументом case в select:
select *,
case
when w.id is not null then 'wagon'
end as type
from train t
join component c on c.train_FK = t.id
left outer join Wagon w on w.id = c.id