1. Object Manager의 핵심 기능 요약
| 기능 | 설명 |
|------|------|
| ✅ 커스텀 오브젝트 생성 | 사용자가 새로운 데이터 객체(예: `__c`)를 정의 |
| ✅ 필드 추가/수정/삭제 | 각 오브젝트에 다양한 타입의 필드(텍스트, 숫자, 날짜 등) 추가 가능 |
| ✅ 관계 설정 | Lookup, Master-Detail 등의 관계 정의 |
| ✅ 메타데이터 저장 | 오브젝트/필드 정보를 별도의 메타 테이블에 저장 |
| ✅ 동적 DDL/DML | 오브젝트 생성 시 DB 테이블 자동 생성 및 CRUD 쿼리 처리 |
| ✅ UI 제공 (React 기반) | 사용자 친화적인 웹 인터페이스 제공 |
| ✅ 접근 제어 (권한) | 특정 오브젝트/필드에 대한 읽기/쓰기 권한 관리 |
---
## 🧱 2. 전체 아키텍처 설계 (React + Spring Boot + MyBatis + MariaDB)
```
[Frontend: React]
↓ (REST API)
[Backend: Spring Boot]
↓
[MyBatis] → [MariaDB]
```
### 🔸 Frontend (React)
- **목표**:직관적인 UI 제공
- **주요 구성**
- Object 목록 페이지
- Object 생성 폼 (이름, 라벨 등)
- Field 관리 패널 (필드명, 타입, null 허용 여부 등)
- Relationship 설정 UI
- 실시간 미리보기 (생성될 테이블 구조)
- **라이브러리 추천**
- `react-hook-form` / `formik`: 폼 관리
- `antd` / `material-ui`: 컴포넌트
- `axios`: 백엔드 API 호출
### 🔸 Backend (Spring Boot)
- **모듈 구성**
- `object-service`: 오브젝트 메타데이터 관리
- `field-service`: 필드 메타데이터 관리
- `relationship-service`: 관계 설정 및 외래키 처리
- `dynamic-dao`: 동적 SQL 생성 및 실행
- `metadata-controller`: REST API 엔드포인트
#### 📂 주요 엔티티 설계 (JPA가 아닌 순수 MyBatis 사용 가정)
-- 1. 오브젝트 메타데이터
CREATE TABLE meta_object (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
object_name VARCHAR(100) UNIQUE NOT NULL, -- 실제 테이블 이름 (e.g., custom_account)
label VARCHAR(100) NOT NULL,
description TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP
);
-- 2. 필드 메타데이터
CREATE TABLE meta_field (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
object_id BIGINT NOT NULL,
field_name VARCHAR(100) NOT NULL, -- 컬럼명
label VARCHAR(100),
data_type ENUM('TEXT', 'NUMBER', 'DATE', 'DATETIME', 'BOOLEAN', 'LOOKUP') NOT NULL,
length INT,
precision INT,
scale INT,
is_required BOOLEAN DEFAULT FALSE,
default_value VARCHAR(255),
FOREIGN KEY (object_id) REFERENCES meta_object(id),
UNIQUE(object_id, field_name)
);
-- 3. 관계 메타데이터 (Lookup 또는 Master-Detail)
CREATE TABLE meta_relationship (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
child_object_id BIGINT NOT NULL,
parent_object_id BIGINT NOT NULL,
relationship_type ENUM('LOOKUP', 'MASTER_DETAIL') DEFAULT 'LOOKUP',
field_name VARCHAR(100), -- 생성될 외래키 컬럼명
FOREIGN KEY (child_object_id) REFERENCES meta_object(id),
FOREIGN KEY (parent_object_id) REFERENCES meta_object(id)
);
> 💡 **주의**: 실제 테이블은 `meta_object.object_name` 기반으로 동적으로 생성됨 (ex: `custom_account`, `custom_project`)
## ⚙️ 3. 핵심 로직 구현 방안
### ✅ 1. 오브젝트 생성 시 동적 테이블 생성
- 사용자가 "New Object"를 생성하면:
- `meta_object`에 레코드 삽입
- MariaDB에 `CREATE TABLE custom_xxx (...)` 실행
- 예시 (Spring에서 동적 DDL):
```java
@Service
public class DynamicTableService {
@Autowired
private SqlSession sqlSession;
public void createTable(String tableName) {
String sql = String.format(
"CREATE TABLE %s (id BIGINT AUTO_INCREMENT PRIMARY KEY)", tableName);
sqlSession.getConnection().createStatement().execute(sql);
}
public void addColumn(String tableName, String columnName, String columnType) {
String sql = String.format("ALTER TABLE %s ADD COLUMN %s %s",
tableName, columnName, mapToDbType(columnType));
sqlSession.getConnection().createStatement().execute(sql);
}
}
```
> ⚠️ **주의**: DDL은 MyBatis보다 JDBC 직접 사용 권장 (MyBatis는 DML 중심)
---
### ✅ 2. 동적 CRUD 구현 (DML)
- 오브젝트와 필드가 동적으로 결정되므로, 정적 Mapper 사용 불가
- **해결책**: XML 기반 동적 SQL or Java에서 StringBuilder로 쿼리 생성
#### 예: 동적 SELECT (MyBatis XML 활용)
```xml
<select id="findRecords" resultType="map">
SELECT
<foreach collection="fields" item="field" separator=",">
${field}
</foreach>
FROM ${tableName}
<where>
<if test="condition != null">
${condition}
</if>
</where>
</select>
```
또는 Java에서 `Map<String, Object>` 기반으로 처리:
```java
public List<Map<String, Object>> query(String tableName, Map<String, Object> params) {
String sql = "SELECT * FROM " + tableName;
// 파라미터 바인딩은 PreparedStatement 사용
return jdbcTemplate.queryForList(sql);
}
```
---
### ✅ 3. 관계 처리 (외래키)
- `meta_relationship`에 기반하여 `ALTER TABLE ADD CONSTRAINT ... FOREIGN KEY` 실행
- 예: `custom_opportunity` → `custom_account` 연결
```sql
ALTER TABLE custom_opportunity
ADD COLUMN account_id BIGINT,
ADD CONSTRAINT fk_account
FOREIGN KEY (account_id) REFERENCES custom_account(id);
```
---
### ✅ 4. React에서의 동적 폼 생성
- 백엔드에서 `/api/objects/{name}/schema`로 메타데이터 조회
- 그에 맞춰 Form 렌더링
```jsx
// React 예시
useEffect(() => {
fetch(`/api/objects/${objectName}/schema`)
.then(res => res.json())
.then(schema => setFields(schema.fields));
}, []);
return (
<form>
{fields.map(field => (
<input
key={field.id}
type={mapDataTypeToInput(field.data_type)}
placeholder={field.label}
/>
))}
</form>
);
```
---
## 🔐 4. 보안 및 권한 고려사항
- **오브젝트/필드 접근 제어**:
- 별도의 `user_permission`, `role`, `field_level_security` 테이블 필요
- **SQL Injection 방지**:
- 동적 쿼리는 반드시 `PreparedStatement` 사용
- 사용자 입력은 무조건 검증 및 이스케이프
- **DDL 실행 권한 제한**:
- 운영 환경에서는 DDL을 개발자 전용 모드에서만 허용
---
## 🔄 5. 생명주기 관리 및 버전 관리 (고급)
- 오브젝트 변경 이력 추적 (Audit Log)
- 스키마 마이그레이션 도구 연동 (Liquibase/Flyway 확장형 사용)
- 메타데이터 내보내기/가져오기 (JSON 형식)
---
## ✅ 6. 기술 스택 적합성 평가
| 기술 | 역할 | 적합성 |
|------|------|--------|
| **React** | 동적 폼, 메타기반 UI | ⭐⭐⭐⭐☆ |
| **Spring Boot** | REST API, 트랜잭션, DI | ⭐⭐⭐⭐⭐ |
| **MyBatis** | 동적 SQL, 메타 기반 쿼리 | ⭐⭐⭐⭐☆ (XML 유연성 있음) |
| **MariaDB** | 스토리지, DDL/DML | ⭐⭐⭐⭐☆ |
| | **단점**: JSON 스토리지 부족 | → MySQL 8.0+ 권장 |
> 💡 대안: **PostgreSQL**은 JSONB, 동적 스키마에 더 유리함
---
## 🚀 7. 추천 아키텍처 개선 방향
1. **Metadata-first 설계**
- 모든 CRUD는 메타데이터 기반으로 결정
2. **Event-driven 처리**
- 오브젝트 생성 시 Kafka/Spring Event로 알림
3. **캐싱 (Redis)**
- 메타데이터는 자주 참조되므로 Redis 캐싱
4. **API Gateway + Microservices (확장 시)**
---
## 📚 8. 참고 자료 및 유사 오픈소스
- **Joget DX**, **ProcessMaker**: Low-code 플랫폼 (메타기반)
- **Hasura**, **PostgREST**: PostgreSQL 기반 동적 API 생성기
- **Apache MetaModel**: 자바에서 동적 데이터 접근 라이브러리
- **Spring Data JDBC**: 정적 ORM이 아닌 유연한 접근
## ✅ 결론
> Object Manager 유사 기능은 React + Spring + MyBatis + MariaDB 조합으로 충분히 구현 가능**하지만, 다음과 같은 점에 주의해야 합니다:
- ✅ **메타데이터 중심 설계**가 핵심
- ✅ **동적 DDL/DML 처리**는 안정성과 보안 강화 필요
- ✅ **UI는 메타데이터 기반으로 동적 렌더링**
- ✅ **관계 및 제약 조건은 외래키 + 메타 테이블로 관리**
---
## 🛠️ 다음 단계 제안
1. `meta_object`, `meta_field` 테이블 생성
2. Spring에서 Object CRUD API 구현 (MyBatis)
3. React에서 Object 생성 폼 개발
4. 오브젝트 생성 시 MariaDB 테이블 자동 생성 테스트
5. Field 추가 → 컬럼 추가 기능 연결
6. 관계 설정 및 외래키 자동 생성
7. 동적 폼 렌더링 및 데이터 저장
카테고리 없음
메타데이터 기반의 동적 오브젝트/테이블 관리 시스템
반응형
반응형