DA05 관계형 구조 설계
35002 단어 designlearningarchitecture
本篇主要讲如何实现程序里的对象与关系数据库之间的记录进行对应,这个问题可以分为以下几个小问题:
정합성 보장 필드
객체에 데이터베이스 ID 필드를 저장하여 메모리에 있는 객체와 데이터베이스 행 간의 객체 ID를 유지합니다.
通过保存数据库中的主键来保证对象的唯一
class KeyTable {
public int getKey(String tableName) {
//get the next key from the table
String query = "SELECT nextID FROM keys WHERE name = {0} FOR UPDATE";
String queryPrepared = DB.prepare(query, tableName);
IDbCommand comm = new OleDbCommand(queryPrepared, DB.Connection);
ResultSet rs = comm.executeReader();
Record record = rs.get(0);
int result = record.getLong(1);
//update the table with the next key
int nextKey = result + 1;
String update = "UPDATE keys SET nextID = {0} WHERE name = {1}";
String updatePrepared = DB.prepare(update, nextKey, tableName);
comm = new OleDbCommand(queryPrepared, DB.Connection);
comm.executeNonQuery();
return result;
}
}
实际上以上的例子已经很少使用,因为数据库现在支持主键自动递增了.另外,对于之前的一些패턴无需使用정합성 보장 필드例如테이블 모듈, 트랜잭션 스크립트, 테이블 데이터 게이트웨이它们的영역对象中已经存贮了记录在数据库中的主键.
외부 키 매핑
객체 간의 연관을 테이블 간의 외부 키 참조에 매핑합니다.
如果영역对象中包含了组合关系,例如개체 A的一个熟悉是객체 B那么数据库中,A对应的表和B对应的表就会有一个外键关系.
下面的例子中,아티스트会有多个앨범一个앨범含有多个앨범表中有一个아티스트外键,추적하다.表中有一个앨범外键.
class Artist {
private int id;
private String name;
...
}
class Track {
private int id;
private String title;
private String style;
...
}
class Album {
private int id;
private String title;
private Artist artist;
private ArrayList<Track> tracks;
...
}
아티스트, 트랙 및 앨범对于的数据库表如下Artist:
id: int
name: varchar
Track:
id: int
album_id: int (foreign key)
title: varchar
Album:
id: int
artist_id: int (foreign key)
title: varchar
对于的데이터 매퍼:class AlbumMapper {
public Album find(long id) {
String sql = "SELECT ID, artistID, title " +
" from albums " +
" WHERE ID = {0}";
String sqlPrepared = DB.prepare(sql, id);
IDbCommand comm = new OleDbCommand(sqlPrepared, DB.Connection);
ResultSet rs = comm.executeQuery();
rs.next();
//get the artist information
long artistID = rs.getLong(1);
ArtistMapper artistMapper = new ArtistMapper();
Artist artist = artistMapper.find(artistID);
//get the track information
TrackMapper trackMapper = new TrackMapper();
Track [] tracks = trackMapper.findForAlbum(id);
Album result = new Album(id, title, artist, tracks);
return result;
}
}
class TrackMapper {
public Track [] findForAlbum(long albumId) {
String sql = "SELECT ID, title " +
" from tracks " +
" WHERE albumID = {0}";
String sqlPrepared = DB.prepare(sql, albumID);
IDbCommand comm = new OleDbCommand(sqlPrepared, DB.Connection);
ResultSet rs = comm.executeQuery();
Track [] result = new Track[rs.size()];
for (int i = 0; i < rs.size(); i++) {
rs.next();
result[i] = new Track(rs.getLong(0), rs.getString(1));
}
return result;
}
}
但是执行앨범的찾아내다方法会总共执行三次JDBC的질의하다这样效率比较低,我们可以直接使用数据库的连表查询来对찾아내다方法进行修改:class AlbumMapper {
public Album find(long id) {
String sql = "SELECT a.ID, a.artistID, a.title, r.name " +
" from albums a, artists r " +
" WHERE ID = {0} and a.artistID = r.ID";
String sqlPrepared = DB.prepare(sql, id);
IDbCommand comm = new OleDbCommand(sqlPrepared, DB.Connection);
ResultSet rs = comm.executeQuery();
rs.next();
//get the artist information
long artistID = rs.getLong(1);
String artistName = rs.getString(3);
Artist artist = new Artist(artistID, artistName);
//get the track information
...
}
}
외부 키 매핑的优缺点
찬성 의견
기만하다
연관 테이블 매핑
연관된 링크를 포함하는 테이블의 외부 키를 포함하는 테이블로 저장합니다.
对于多对多的情况,我们无法用一个外键来表示这样的关系,연관 테이블 매핑就仿照了关系数据库来创建一个新的表来记录这些关系.
还是아티스트的例子,아티스트和계기有多对多的关系:
class Artist {
private int id;
private String name;
...
}
class Instrument {
private int id;
private String name;
}
Artist:
id: int
name: varchar
Instrument:
id: int
name: varchar
artist-instruments:
artist_id: int
instrument_id: int
对应的,예술의 대가会是这样:class ArtistMapper {
public Artist find(long id) {
String sql = "SELECT ID, name " +
" from artists " +
" WHERE ID = {0}";
String sqlPrepared = DB.prepare(sql, id);
IDbCommand comm = new OleDbCommand(sqlPrepared, DB.Connection);
ResultSet rs = comm.executeQuery();
rs.next();
//get the name
String name = rs.getString(1);
//get the instruments information
Instrument [] instruments = loadInstruments(id);
Artist result = new Artist(id, name, instruments);
return result;
}
// find instruments that the artist plays in artist-instruments table
public Instrument [] loadInstruments(long artistID) {
String sql = "SELECT artistID, instrumentID " +
" from artist-instruments " +
" WHERE artistID = {0}";
String sqlPrepared = DB.prepare(sql, id);
IDbCommand comm = new OleDbCommand(sqlPrepared, DB.Connection);
ResultSet rs = comm.executeQuery();
//load the instrument details using an InstrumentMapper
Instrument [] result = new Instrument[rs.size()];
InstrumentMapper instrumentMapper = new InstrumentMapper();
for (int i = 0; i < rs.size(); i++) {
rs.next();
result[i] = instrumentMapper.find(rs.getLong(2));
}
return result;
}
}
연관 테이블 매핑的优缺点
찬성 의견
기만하다
삽입값(매핑에 의존)
한 객체를 다른 객체 테이블의 여러 필드에 매핑합니다.
포함된 값은 객체의 값을 소유자의 필드에 매핑합니다.또한 포함된 값은 소속 객체를 로드/저장할 때 로드/저장됩니다.
有时我们不需要为每一个类都创建一个对应的数据库表,因为有一些表会显得没有意义.
总的来说,내포된 가치只存在于一对一的关系.
class Employee {
int id;
String name;
Period period; // working period
Money salary;
}
class Period {
Date startDate;
Date endDate;
}
class Money {
float amount;
String currency;
}
我们并不为上面的三个类创建三个表,而是之创建一个表:Employee:
id: int
name: varchar
startDate: Date
endDate: Date
salary: float
currency: varchar
对应的제도원如下:class EmploymentMapping {
public Employment find(long id) {
String sql = "SELECT * from Employments WHERE id = {0}";
String sqlPrepared = DB.prepare(sql, id);
IDbCommand comm = new OleDbCommand(sqlPrepared, DB.Connection);
ResultSet rs = comm.executeQuery();
Record record = rs.get(0);
//lookup the information from the Person table
long personID = rs.getFloat(2);
Person person = personMapper.find(personID);
//create the data range and money objects
Date startDate = rs.getDate(3);
Date endDate = rs.getDate(4);
DateRange dateRange = new DateRange(startDate, endState);
float amount = rs.getFloat(5);
String currency = rs.getString(6);
Money money = new Money(amount, currency);
//create the Employment instance
Employment result = new Employment(id, person, dateRange, money);
return result;
}
...
}
표 상속
클래스의 계승 차원 구조를 하나의 표로 표시하고 이 표는 각 클래스의 모든 필드의 열을 포함한다.
用一张表来存储所有种类的학급这张表的列包含了所有的属性,对于不同학급的반대, 반대하다它们所在的行只使用它的属性对应的字段,其余字段则设为空.同时,还需要一个记录其类型的字段타이핑
我们有三个类:선수并有以下的继承关系:
class Player {
protected String name;
protected int age;
}
class Footballer extends PLayer {
protected String club;
}
class Cricketer extends PLayer {
protected int battingAverage;
}
对应的数据库表,我们仅创建一个,包含以上所有属性以及一个유형:Player:
name: varchar
age: int
club: varchar
batting_average: int
type: int
표 상속的优缺点
찬성 의견
기만하다
클래스 테이블 상속
클래스의 계승 차원 구조를 나타내고 클래스마다 표가 있다.
与표 상속相对,为每一个类创建一个탁자.
每一次对子类表的数据库操作,都会与其父类表进行连表操作.
还是用上面플레이어的例子,这次的表是这样的:
Player:
name: varchar
age: int
Footballer:
club: varchar
Cricketer:
batting_average: int
클래스 테이블 상속的优缺点
찬성 의견
기만하다
콘크리트 시계 계승
클래스의 계승 차원 구조를 나타내고 차원 구조에서 각 구체적인 클래스는 표가 있다.
与클래스 테이블 상속类似,有多个表,子类对应的表包含了所有的属性:
Footballer:
name: varchar
age: int
club: varchar
Cricketer:
name: varchar
age: int
batting_average: int
세부 상속的优缺点
찬성 의견
기만하다
Reference
이 문제에 관하여(DA05 관계형 구조 설계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/declair/da05-object-to-relational-structural-design-3k6j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)