ORM 저장소 (스토리지) 모드로 이동

ORM 사업 개발은 역설의 역할을하고있다. 많은 사람들이, ORM을 찬양 적합한 객체 지향 ORM 코드 간단하고 적절한 방법을 생각한다. ORM 숨기기 너무 많은 세부 사항이 많은 숨겨진 위험을 심어 있기 때문에 많은 사람들이 싫어. 리뷰가 많은 비즈니스 코드, ORM은 아주 재미 사용하고 있음을 발견 한 후 이동, 우리는, ORM에 더 많거나 적은 접촉을 가지고 있지만, "레이 희미한 헷갈리는을."

엔티티 프레임 워크

은 Microsoft .NET Framework를 지배 등의 엔티티 프레임 워크 및 .NET 핵심 킬러 ORM 여부 사용 또는 효율은 최고 수준이다. 그리고 엔티티 프레임 워크는 저장소 모드 (저장 모드) 개발자의 사용에 대한 임계 값을 줄일 수라고 할 수 온다. 몇 가지 실제 사례 :

WebAppContext entity = new WebAppContext();

[HttpGet]
public ActionResult Index(String verify, String email)
{
    var databasemail = entity.Mails.Find(verify);
    //code...
    entity.Mails.Add(databasemail);
    entity.SaveChanges();
    //code...
}

그것은 엔티티 프레임 워크 문맥으로 알 수있는 데이터를 용이하게 검색 할 수 직관에 따른 후속 엔티티 및 CURD 사용 데이터를 직접 액세스 할.

ORM 내부 이동 그것을 수행하는 방법인가?

ORM 사용 내부 이동

다음 내용은 이동 - 페이지 예.

번영에 ORM의 사용을 위해 이동합니다. 네 가지 사용량의 합계를 볼 수 :

원시 심문

원시 쿼리는 실제로 매우 고전적인 사용, 일반적인 보고서, 일괄 업데이트 또는 스크립트는 사실, 바로 갈 수있는 초보자에게 연락 할 때 데이터 조정이 유용 수행 ORM은 (단순) 원시 쿼리를 사용하는 경향이 사용합니다. 그래서 원시 쿼리는 실제로 거의 사용 ORM 데이터베이스 드라이버로, 코드 도처에서 학대로 이어집니다.

func Query(sql string, params ...interface{}) ([]map[string]interface{}, error) {
    rows, err := DB.Raw(sql, params...).Rows()
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    list := []map[string]interface{}{}
    for rows.Next() {
        dest := make(map[string]interface{})
        if scanErr := MapScan(rows, dest); scanErr != nil {
            return nil, scanErr
        }
        list = append(list, dest)
    }
    return list, nil
}

이렇게하면 나쁜 것이 아니라 데이터 조직의 부족, 그리고 []map[string]interface{}실제 사용에서 이런 종류의 일이 매우 간단하기 때문에 비 공동 롤오버 (공황)의 유형입니다. 원시 쿼리는 그렇게 나쁘지 아니지만 학대하지 않습니다. 일반 사용 CTE, 전제 조건 장면 윈도우 함수 등을 사용하여 원시 쿼리는 합리적이지만, 원시 쿼리에 대해 다시 관심을 지불 할 필요 :

func (service *DBService) cte(arg1, arg2 interface{}, domain ...interface{}) (sql string, args []interface{}) {
    //code...
    return
}

CTE는 원시 유사한 쿼리가 발생하는 이러한 쿼리의 빈도를 줄이기 위해 복용 반환 할 수 있습니다.

기본 쿼리 유형

이 패턴은 ORM 사용에 매우 일반적이다. ORM 모델은 약이 인 검색 작업이 실행에 직접 전달된다 :

var entity = Entity{}
PostgreSQLConnection.Model(&entity).Where(`ID = $id`).Select()

ORM을 활용 보인다, 그 결과를 확인하는 것은 구조적 실체이지만, 사실이 모델은 실제로 이전 쿼리 원시 모드의 변형이지만, 상대적으로 더 안전합니다. 전체 모양은 방향 감각을 만드는 통일 조직 및 관리 쿼리가 없기 때문에 이러한 쿼리는 모델 매핑 ORM을 사용하지만, 그 모든 곳에서, 말을하는 것입니다 PostgreSQLConnection.Model. 또한, 이러한 모델로 이전, 데이터 수준의 논리적 표현에서 완료 할 수 없습니다.

로직 레벨의 표현 데이터

예를 들어, Corporation기업이 실제로이 Staffs이 모드는, 쿼리가있는 경우, 강력한 관계 데이터를 Corporation.Staffs구축 가야 Staff모델을, 다음 WHERE명령문이 추가 된 CORPORATION_ID같은 매개 변수 정보를. 그러나 이론적으로, 나는 사업체의 직접해야 회사의 직원 정보를 찾을 수있다 Staffs내 아들 속성이나 메서드에 액세스 할 수 있습니다.

물론, ORM은 이러한 문제를 개선 할 수있는 기능을 제공하거나. 갈-PG 특성 관계 데이터 검색 기준 (그러나이 기능 이상 판 ...)를 제공하는 형상을 제공하는 .Staffs방법. 그러나 쿼리에서 명시 적으로 문을 즉시 조건을 지정할 필요를 검색 할 필요가, 마침내있어 .Staffs실제로 이미 데이터의 결과를 발견, 유연성의 정도 (예를 들어, 단지 ID 목록의 조건을 충족해야합니다) 상대적으로 낮다.

반웨어 하우징 모드 (또는 데이터 서비스 모드를 읽고)

이 모드는 실제로 나는이 모델은 데이터 서비스로 캡슐화 된 데이터 액세스 로직의 여러 유형의 것, 이전에 사용했던 패턴입니다 :

type (
    //IService 服务契约定义
    IService interface {
        Save(*models.Entity) error
        Find(interface{}, ...func(*orm.Query)) (*models.Entity, error)
        Where(models.Entity, ...func(*orm.Query)) ([]models.Entity, error)
        Count(models.Entity, ...func(*orm.Query)) (int, error)
    }

    service struct {
        Pg    *pg.DB
    }
)

그런 다음 대응을 달성하기 위해 :

  • 저장하기
  • 검색
  • 어디
  • 카운트

다음과 같은 논리적 관계형 데이터를 기반으로 다른 데이터 액세스 인터페이스를 추가 Corporation추가 할 수있는 서비스 Staffs계약을 정의합니다.

그런 다음 클라이언트 통합 등록에이 서비스를 설정합니다

type (
    //Services 基础服务集合
    Services struct {
        Corporation corporation.IService
    }
)

사실 이러한 모델의 사용이 모델은 데이터에 대한 통합 입구 액세스를 구성하고, 또한 데이터 레벨 로직의 문제를 해결하기 위해 노력하지만, 이러한 데이터에 액세스하는 가장 큰 문제는 수프를 변경하지 않습니다되어 있지만, 궁극적 인 형태에 매우 근접하고있다 드레싱 :

service.Corporation.Staffs(corp, `ID IN (?)`, pg.In(array))

위의 성명에서, 나는 해당 의미를 직접 공사 스태프에 정보 액세스를 통해 보였지만, 사실 :

用企业信息数据服务查询员工信息

대신 :

企业的员工信息

앞 본질적으로 두 가지 문제를 해결하지 않습니다, 아마 Nongfu 봄과 Cestbon 사이의 차이입니다. 그래서, 저장 모드 엔티티 프레임 워크처럼, 그것은 더 우아한를 달성하는 방법에 이동?

저장 모드

우리는뿐만 아니라 명령문의 엔티티 프레임 워크 컨텍스트에 반환 할 수 있습니다 :

namespace Tencent.Models
{
    public class WebAppContext : DbContext
    {
        public WebAppContext() : base("name=WebAppContext") {}
        public virtual DbSet<Entity> Entities { get; set; }
    }
}

나는 아직 발견 Entity.Entities실제로하지 Entity입력 만 DbSet<T>입력합니다. 이유는 세 가지 방법 이전에 본질적인 차이는 모두 데이터를 추론 및 데이터에 대한 액세스를 제공하기 위해 일반 일반 이동 구조 (딱지)을 사용하는 것이 없다있다.

저장 모드를 위해, 우리는 (데이터베이스 컨텍스트로 이동 구조) 데이터베이스 컨텍스트 구조를 구축해야한다 :

type (
    //Corporation 应用数据库模型
    Corporation struct {
        tableName struct{} `sql:"corporations"`
        *models.Corporation

        db *pg.DB
    }
)

//Save 保存
func (c *Corporation) Save() (err error) {
    if c.ID > 0 {
        err = c.db.Update(c)
    } else {
        err = c.db.Insert(c)
    }
    return
}

//Query 查询
func (c *Corporation) Query() (query *orm.Query) {
    return c.db.Model(c)
}

즉, 데이터베이스와 상호 작용하고, 데이터베이스 컨텍스트와 연관 될 온 실제 비즈니스 사례에 흐른다. 이 경우, 가능한 Corporation예시적인 방법을 정의하는 Staffs방법 :

//Staffs 公司员工列表
func (c *Corporation) Staffs(valid ...bool) *orm.Query {
    tables := c.db.Model((*User)(nil)).Where(`"corporation_id" = ?`, c.ID)
    if len(valid) > 0 {
        tables.Where(`"valid" IS ?`, valid[0])
    }
    q := c.db.Model().With("users", tables).Table("users")
    return q
}

이것은 CTE 쿼리를 반환합니다. 등가 .Staffs () 메소드가 아닌 직접 쿼리를 실행하지만, 사전에 쿼리를 "회사 직원의 데이터 세트"를 제공 할 수 있습니다. 당신은 직원 정보가 실제로 필요와 관련된 ID를 확인해야하는 경우 :

var staffIDs []int
err := corporation.Staffs().Column("id").Select(&staffIDs)

이후의 쿼리 작업.

통합 저장 모드를 달성하기 위하여,이 구조는 통합 저장소에 등록 할 수있다 :

type (
    //Service 数据库服务协议
    Repository interface {
        User(...*models.User) *User
        Corporation(...*models.Corporation) *Corporation
    }

    repository struct {
        *pg.DB
    }
)

//NewService 在目标连接上新建服务
func NewRepository(db *pg.DB) Repository {
    return &repository{db}
}

이전 수정 Corporation정의 db *pg.DB입니다 db *repositoryCorporation등록 팩토리 메소드 Repository:

//Corporation 企业数据库服务
func (service *service) Corporation(corp ...*models.Corporation) (entity *Corporation) {
    if len(corp) == 0 {
        corp = append(corp, nil)
    } else if corp[0] != nil {
        defer entity.Clean()
    }
    entity = &Corporation{Corporation: corp[0], db: service}
    return
}

이 시점에서, 이동의 저장소와 ORM은 끝을 만듭니다. 저장소 패턴은 효과적으로 데이터 모델, 컨텍스트 모델 데이터베이스에서 분리하고, 논리적 데이터 레벨을 제공하면서 DB 액세스가 정말 간단. 사업이 이동을 사용해야하는 경우, 이동 또한 .NET 또는 Java ORM 접근 방식에서 배울 수, 데이터베이스에 액세스하는 ORM을 사용합니다.

이 SR에 도로를하지 않습니다.

전제 Benpian 문학은 SR에 ORM 도로에 대한 모든 이야기와 ORM이다.

추천

출처www.cnblogs.com/johnwii/p/11751283.html