Program Tip

ORM 및 Embedded SQL없이 Java 웹 애플리케이션을 디자인하려면 어떻게해야합니까?

programtip 2020. 12. 9. 21:40
반응형

ORM 및 Embedded SQL없이 Java 웹 애플리케이션을 디자인하려면 어떻게해야합니까?


편집 : 원래 제목 : ORM 사용의 이점에 대한 질문.

학습 목적으로 ORM을 사용하고 싶고 nhibernate를 시도하고 있습니다. 튜토리얼을 사용하고 있으며 실제 프로젝트가 있습니다. "오래된 방식"으로 가거나 ORM을 사용할 수 있습니다. 혜택을 완전히 이해하고 있는지 잘 모르겠습니다. 한편으로는 데이터베이스를 변경하고 데이터베이스에 독립적이되도록 코드에서 추상화를 만들 수 있습니다. 다른 한편으로는 실제로 데이터베이스 열을 변경하면 모든 코드를 변경해야하는 것 같습니다.

내 데이터베이스, orm 및 코드를 변경하는 대신 ORM없이 내 응용 프로그램을 사용하지 않고 데이터베이스를 변경하고 코드를 변경하지 않는 이유는 무엇입니까? 데이터베이스 구조가 그다지 변하지 않는 것입니까?

ORM은 많은 사람들이 사용하기 때문에 실질적인 이점이 있다고 생각합니다. 아직 잘 모르겠습니다.

감사합니다.

편집 : 튜토리얼에는 ORM을 작동시키는 데 사용되는 많은 파일이 있습니다.

http://www.hibernate.org/362.html

응용 프로그램이 변경되는 경우 "적절한"추상화 계층이 있다고 말하는 것은 많은 추가 작업처럼 보입니다. 내가 처음이기 때문에 유지 관리가 쉽지 않고 다시 추가 작업처럼 보입니다.

편집 : 이것은 내가 계속 돌아 오는 오래된 질문입니다. ORM이없고 Embedded SQL을 사용하지 않고 .NET LINQ-to-SQL을 사용하지 않고 애플리케이션을 올바르게 디자인하는 예를보고 싶은 것이 있습니다. 저는 현재 Java 세계에 있으며 진행 방법을 잃었습니다. 웹 애플리케이션입니다. 봄도없고 다른 세상적인 프레임 워크도 없습니다. JSP, JSTL, EL, HTML, JavaScript, CSS, Java, Tomcat. 내가 아무것도 남기지 않았 으면 좋겠다. 그리고 예, 저는 그것이 오래된 질문이라는 것을 압니다. 여전히 관련이 있습니다.


왜, 왜 업계가이 개념의 재앙에 그렇게 집착 하는가? 이전 답변 중 어느 것도 @johnny의 우려를 적절히 해결하지 못했습니다. 그것들은 모두 데이터베이스 프로그래머가 직면 한 구체적인 문제를 잘 해결하는 반쯤 손을 흔드는 정당화입니다.

@TheTXI의 대답은 같은 질문을 할 때받는 전형적인 대답입니다 : 레이어 분리. 그게 무슨 의미 일까? 이유는 않는 원하는 내 층을 분리? 또는 더 중요한 것은 관계형 계층과는 다르지만 해당 계층에서 표준 매핑이어야하는 추가 계층을 만드는 것이 어떤 이점이 있습니까?

또한 (@johhny의 아직 답이없는 요점) 이것이 우리를 변화로부터 어떻게 보호합니까? 데이터베이스가 변경되면 ORM 레이어는 거의 확실하게 따라야합니다. 실제로 개체 수준에서 조인 테이블을 모델링하지 않는 기본 관행은 테이블이 불가피하게 일부 추가 열을 늘릴 때 개체 모델에 일부 추가 필드를 추가 할뿐만 아니라 토폴로지와 강제를 변경하기 때문에이를 더욱 악화시킵니다. 코드 재 작성! 이것은 변경 관리의 재앙이며 관계에 대한 잘못된 견해 (객체를 대표한다고 생각하는)가 재앙을 초래하는 방법의 전형적인 예입니다. 관계형 데이터베이스를 프로그래밍 언어의 일치하는 개념에 직접 매핑 한 경우에는 발생하지 않았을 것입니다 ( LINQ-to-EF가 아닌 LINQ-to- SQL을 생각해보십시오 ).

이 공간 (방 안의 코끼리)에서 가장 큰 답이없는 질문은 ORM이 해결해야하는 문제는 무엇입니까? 그리고 "객체 관계형 임피던스 불일치"라고 말하지 마십시오. 그것은 또 다른 손을 흔드는 전자 장치입니다. 임피던스 불일치가있는 이유와 데이터베이스로가는 언어가 아닌 언어로 제공되는 데이터베이스 여야하는 이유를 설명하십시오. 내 설명은 대부분의 프로그래밍 언어가 관계형 데이터를 표현하고 작업하는 데는 짜증이 나지만 이것은 근본적인 원칙이 아니라 사라지기 시작하는 역사적 현실입니다 (LINQ-to-SQL은 그 방향의 첫 번째 아기 단계였습니다). 사운드 아키텍처를 기반으로합니다.

ORM이 지연 로딩, 캐싱, 어리둥절한 지속성 및 소유권 의미 체계 등으로 인해 너무 복잡해진 이유가 있습니다. 그리고이 모든 추가 사항이 키보드에서 멀어 지더라도 여전히 기본을 효율적으로 해결하지 못하는 이유가 있습니다. "어떤 쌍의 구성원이 둘 이상의 그룹을 공유합니까?"와 같은 문제 관계형 모델은 네트워크와 계층 적 모델이 그러한 문제의 무게로 인해 무릎을 꿇고있을 때 구상되었습니다. 그것은 신선한 공기의 숨결이었습니다. 이제 우리 모두는 고양이 오줌이 가득한 옛 모래밭으로 돌아가고 싶어하는 것 같습니다. 그리고 우리는 새로운 것을 발명했다고 생각합니다 (우리가 코를 잡고있는 한).

(저는이 답변에 대해 자유롭게 하향 표를받을 것으로 기대합니다.하지만 그렇게 할 때 댓글을 남겨주세요. 이유를 아는 한 제가 틀렸다는 말을해도 괜찮습니다.)

편집 : 시간을내어 의견을 내주신 @Chris에게 감사드립니다. 그것은 나에게 해결해야 할 몇 가지 구체적인 요점을 제공합니다 ... (아래에서 @Chris를 자주 언급하지만 나는 그를 구체적으로 작업에 데려가려는 것이 아닙니다. 그의 응답은 내가 토론 할 때 항상 듣는 종류의 댓글과 같습니다. 그래서 나는 그가 내 비판을 개인적인 모욕으로 받아들이지 않기를 바랍니다. 그런 식으로 의도 된 것이 아니며 그가 응답하는 데 걸린 시간에 진심으로 감사합니다.)

먼저 @Chris의 의견과 답변에서 분명한 몇 가지 오해를 정리하겠습니다.

  1. 필자는 모든 명백한 이유와 그다지 분명하지 않은 이유 때문에 코드에서 원시 SQL을 옹호하지 않습니다 (예 : SQL은 함수 분해를 사실상 불가능하게 만드는 대수도 미적분도 아닙니다).
  2. 저는 모 놀리 식 애플리케이션 디자인을 옹호하지 않습니다. 일반적으로 레이어는 좋은 것입니다.
  3. 나는 특수 필드, 메서드 및 속성과 같은 많은 라인 노이즈를 가진 오염 개체 모델을 옹호하지 않습니다. 그러나 솔직히 이것은 도메인 / 객체 모델이 ORM 유니버스에만 존재하기 때문에 멍청이입니다. 이제 LINQ-to-SQL에는 이러한 모든 클래스에 노이즈가 많은 비트가 포함되어 있지만 그저 비하인드 스토리에 불과합니다. 당신은 그 코드를 편집하지 않으며, 일반적으로 그것을 보지 말아야합니다.

이제 반대에 대한 몇 가지 반대 :

  1. 응용 프로그램이 데이터베이스와 독립적으로 구축 될 수 있다는 주장은 근거가 없습니다. 대체로 ORM은 데이터 레이어에 대한 표준 매핑 일뿐입니다 (테이블 Foo와 Bar는 클래스 Foo와 Bar가되고 테이블 FooBar는 클래스 Foo와 Bar 사이에 일종의 끔찍한 관계가됩니다). 이 매핑에는 흔들림의 여지가 많지 않으므로 데이터 모델을 변경하려면 거의 확실하게 개체 모델을 변경해야합니다. 해당 데이터베이스 모델에서 근본적으로 분기 된 개체는 모든 관련자에게 추가적인 유지 관리 문제에 지나지 않기 때문에 이것은 내 관점에서 좋은 것입니다.
  2. ORM이 데이터 모델 독립성을 유발한다는 환상이 사라지면 데이터 모델에 대한 직접 결합의 악에 대한 모든 항의는 논쟁 거리가됩니다. 그러나 나는 이것을 단순히 무시하는 것보다 조금 더 추구하고 싶습니다. 커플 링은 시스템 설계의 필수 기능입니다. 어느 시점에서 결정과 가정이 이루어져야합니다. 단일 "사물"테이블을 사용하여 모든 것을 프로그래밍 할 수는 없습니다. 도메인에 특정 개념이 포함되어 있는지 확인한 다음 이러한 개념을 존중하는 스키마와 코드를 만들고이를 일류 시민으로 취급하고 하드 코딩해야합니다. 아이디어 그 응용 프로그램을 해야지데이터베이스와 독립적이라는 것은 잘못된 방법입니다. 데이터베이스는 비즈니스 지식을 가장 순수하게 표현한 것입니다 (항상 그런 것은 아니라는 것을 알고 있으며 나중에 다룰 것입니다). 이러한 표현에 대한 결합은 가장 강력한 복원력을 보장해야합니다. 이러한 데이터 모델은 비즈니스 자체가 본질적인 변화를 겪을 때만 변경되기 때문입니다. 요컨대, 잘 설계된 데이터베이스 스키마에 결합하는 것은 매우 좋은 일입니다.
  3. 레이어링은 그 자체로 끝이 아닙니다. 특정 목표를 달성하기 때문에 좋습니다. 앞의 요점은 ORM이 수행하는 방식으로 데이터베이스와 앱 간의 계층화가 변화에 대한 탄력성의 실제 목표를 달성하는 데 효과적이거나 필요하지 않음을 보여줍니다. 이것은 좋은 데이터베이스 디자인을 통해 이루어집니다.
  4. @Chris는 데이터베이스가 OO 디자인을 방해하는 일을 지시한다고 주장합니다. 이것은 충분히 사실이지만 OO 디자인이 지식을 모델링하는 가장 좋은 방법 인 경우에만 흥미 롭습니다. 시장에서 OODBMS의 거의 완전한 실패는 이것이 사실이 아님을 암시합니다. 술어 논리 기반을 가진 관계형 모델은 OO 모델의 그래프 이론적 복잡성을 발생시키지 않고 OO 디자인과 동일한 표현력을 보유합니다.
  5. @Chris가 오늘날의 문제 (따라서 NoSQL 운동)를 해결하지 못한다는 이유로 관계형 모델에 대한 반대는 완전히 표를 벗어났습니다. NoSQL은 "관계형 모델 없음"이 아니라 "SQL 없음"을 의미합니다. 안타깝게도 NoSQL 운동의 지지자조차도 이와 관련하여 무지한 것 같습니다. SQL에는 관계형 모델에서 근본적인 이탈로 인해 많은 결함이 발견되었습니다. SQL이 짜증나 기 때문에 관계형 모델을 포기해야한다고 말하는 것은 아기를 목욕물로 내 던지는 다소 노골적인 경우입니다.
  6. ORM을 사용하지 않는다고 해서 애플리케이션 구축 노력이 세 배가 되지는 않습니다 . 이것은 터무니없는 주장이며 @Chris조차도 codegen 대안에 대한 백핸드 칭찬으로 백도어를 열어두고있는 것 같습니다. LINQ-to-SQL의 sqlmetal과 같은 Codegen 도구는 애플리케이션의 데이터 모델이 데이터베이스의 데이터 모델과 절대적으로 달라야한다는 교리에 얽매이지 않는 모든 사람을위한 완벽한 솔루션입니다.

ORM에 대한 저의 경험은 그들이 튜토리얼에서 훌륭하게 작동하고 현실 세계에서 끝없는 고통과 좌절을 유발한다는 것입니다. LINQ-to-SQL이 처음에 ORM에 동기를 부여한 많은 문제를 수정했기 때문에 그런 종류의 고문을 당할 이유가 없습니다.

한 가지 중요한 문제가 남아 있습니다. 현재의 SQL 데이터베이스는 물리적 계층과 논리적 계층의 분리에 대해 의미있는 제어 수준을 제공하지 않습니다. 테이블에서 디스크에있는 항목으로의 매핑은 대부분 고정되어 있으며 전적으로 SQL DBMS의 제어하에 있습니다. 이것은 둘을 명시 적으로 분리 한 관계형 모델에 대한 계획의 일부가 아니 었으며 논리적 모델이 제안한 것과는 완전히 다른 구조로 디스크에 저장할 수있는 데이터의 일관된 논리적 표현을 정의 할 수있었습니다. 예를 들어 시스템 (또는 dba)은 성능상의 이유로 고도로 정규화 된 논리 모델을 물리적으로 자유롭게 비정규화할 수 있습니다. SQL 엔진은 이러한 문제 분리를 허용하지 않기 때문에 순전히 필요에 따라 논리적 모델을 비정규 화하거나 고문하는 것이 일반적입니다. 그 결과 논리적 모델이 항상 정확할 수는 없으므로 데이터베이스를 지식의 가장 순수한 표현으로 사용하는 이상은 완전히 실현 될 수 없습니다. 그러나 실제로 디자이너는 일반적으로 데이터베이스에서 도메인 모델로의 표준 매핑을 고수합니다. 다른 것은 유지 관리하기가 너무 힘들 기 때문입니다.


: NHibernate에 내 경험으로는 Visual Basic에서 같은 비트입니다 쉽게 문제를 만드는 정말 쉬운, 그러나 그것은 또한 더 열심히보다 아무것도하게 정말 열심히 또는 완전히 불가능합니다.

기본 아이디어는 ORM이 지속성 코드를 작성할 필요가 없다는 것입니다. 이러한 코드에는 많은 중복이 있으므로 특정 비즈니스 계층에 한정되지 않고 일반 코드로 만들고 프로젝트 전체에서 다시 사용하는 것이 매우 유혹적입니다. 여태까지는 그런대로 잘됐다. 간단한 개체 계층 구조 및 비즈니스 요구 사항의 경우 실제로 이것은 실제로 잘 작동합니다. 데이터베이스가 변경되면 ORM 매핑 파일을 변경해야하지만 일반적으로 매우 간단하고 한 곳에서만 변경하면됩니다. 데이터베이스에 액세스하는 코드를 변경하는 것보다 훨씬 쉽습니다.

문제는 데이터베이스와 요구 사항이 점점 복잡 해짐에 따라 ORM이 따라 잡기가 점점 더 어려워진다는 것입니다. 따라서 ORM은 점점 더 복잡해집니다. 또한 모든 경우에 효율적으로 수행하는 방법을 알아낼만큼 똑똑하지 않기 때문에 일부 작업을 비효율적으로 수행하는 지름길도 필요합니다 . 더욱이, 전체 아이디어는 투명하게 작동한다는 것이므로 이러한 성능 문제가 사용자 경험에 영향을 미칠 정도로 악화 될 때까지 종종 볼 수 없습니다. 관련된 문제는 버그를 찾기가 훨씬 더 어렵다는 것입니다. 디버그하지 않으면 ORM 내부에서 무슨 일이 일어나고 있는지 알 수 없기 때문입니다. (예, NHibernate 코드를 거쳐야했으며 피크닉이 아닙니다!)

So you start bypassing the ORM for some things and use SQL directly instead. Of course, you then have to make that code work with the code that does use the ORM, which is more work. You end up writing code to load and save some objects manually and to somehow work that into the ORM code. Eventually you start wondering if the ORM is creating more work for you than it's saving - not to mention the performance and bug hunting headaches.

따라서 튜토리얼에서 찾을 수있는 매우 간단한 응용 프로그램을 작성하는 경우 ORM이 잘 작동합니다. 그것보다 더 복잡하다면 그만한 가치가 없다고 생각합니다. 물론 간단한 응용 프로그램의 경우 절약되는 시간도 적습니다. 내 결론 : ORM에 신경 쓰지 마십시오. ORM은 어두운면으로가는 길입니다.


이 글을 읽기 전에 나는 종종 ORM 도구가 프로젝트에 미치는 영향을 이해하는 데 다른 사람들이 정말로 귀찮은 지 궁금해했습니다. @Evgeny, @Marcelo Cantos, @Jimmy B는 이것을 쉬게했습니다.

요컨대, 그들은 ORM 도구를 둘러싼 대부분의 문제로 인해 죽어 있습니다. 그들이 다루지 않았거나 충분히 다루지 않은 부부가 있습니다.

첫째, ORM을 사용한다고해서 코드가 줄어드는 것은 아닙니다. SQL이 적다는 것을 의미 할 수 있지만 확실히 코드가 적다는 것을 의미하지는 않습니다. 이러한 행을 따라 도구 생성 코드가 잘못 될 수 있습니다. 더 나쁜 것은 잘못 생성 된 코드를 보상하는 것은 좌절감의 연습입니다.

둘째, ORM 도구는 SQL을 이해할 필요가 없음을 의미하지 않습니다. 다른 말로 표현하자면, SQL이 효과적인 프로그래머라는 것을 알아야합니다 (내장 된 사람과 같은 예외가 있습니다). 이러한 도구에서 내 보낸 쿼리 (유형 및 수 모두)는 성능 또는 리소스 관점에서 충분하지 않습니다. 이미 SQL을 알아야한다면 왜 자신을 족쇄합니까?

셋째, ORM 도구는 시간을 절약하지 않습니다. 적절한 크기의 응용 프로그램을 처리하기 위해 선택한 ORM 도구를 제출하는 데 더 많은 시간을 소비합니다. 상해에 대한 모욕을 더하기 위해, 당신이 끝났을 때 당신은 쿼리의 질이 당신이 직접 한 것보다 일반적으로 더 나쁘다는 것을 알게 될 것입니다. 요점은 ORM = 프로젝트에 더 많은 시간을 할애하면 결과가 나빠집니다.

넷째, DBMS 독립성은 일반적으로 시간 낭비입니다. 대부분의 응용 프로그램은 수명 동안 정확히 하나의 DBMS를 사용합니다. Oracle, SQL Server, MySql 등 무엇이든 상관 없습니다. 응용 프로그램은 DBMS가 제공하는 기능을 활용할 수 있기 때문에 훨씬 더 나아질 것입니다. DBMS에 구애받지 않는다는 것은 서브 파 쿼리로 제한해야한다는 것을 의미합니다.

다섯째, 모든 것이 객체가 될 필요는 없습니다. 이것은 주목해야 할 중요한 사항입니다. 페이지에 특정 데이터 세트를 표시하라는 요청을 자주받습니다. 이는 종종 두 개 이상의 테이블에서 데이터를 결합하는 것을 의미합니다. 앱에서 일부 데이터를 표시하기 위해 이러한 모든 개체를 만들고 인스턴스화해야합니까? 아니면 쿼리를 실행하고 원하는 형식으로 화면 / 브라우저로 데이터를 직접 내보내는 것이 더 낫습니까?

ORM은 가장 단순한 것들에도 많은 오버 헤드를 추가합니다. 대부분의 ORM은 테이블에서 간단한 UPDATE를 수행하기 위해 여러 SQL 쿼리를 생성합니다.

여섯째, 내 마음에있는 가장 중요한 문제는 ORM이 보안을 저하시키는 것입니다. 물론 s'procs와 함께 ORM을 사용할 수 있습니다. 하지만 대부분의 사람들은 그렇지 않습니다. ORM을 활용 한 거의 모든 앱은 사이트가 크랙되면 전체 데이터베이스를 쉽게 죽이거나 도난 당할 수있는 방식으로 데이터베이스를 노출했습니다 . ORM 도구는 즉석에서 SQL을 생성합니다. 즉, 직접 테이블 액세스가 필요합니다. 즉, 앱이 손상되면 해커가 직접 테이블에 액세스 할 수 있습니다. 이는 애플리케이션에서 적어도 하나의 보안 계층을 효과적으로 제거했음을 의미합니다.


이 질문이 얼마 전에 게시되었다는 것을 알고 있지만 조니와 똑같은 것이 궁금합니다. 저는 지적인 사람들이 여러 개의 대규모 프로젝트에서 Hibernate를 사용하는 것을 보았습니다. 모든 경우에 그것은 완화되지 않은 재앙이었습니다. 제 경험상 대부분의 엔터프라이즈 애플리케이션에서 가장 복잡하고 성능에 영향을 미치는 단일 영역은 비즈니스 계층과 데이터베이스 계층 사이입니다. 이것이 데이터베이스 상호 작용을 관리 가능한 청크로 캡슐화하기 위해 데이터 액세스 계층을 추가하는 이유의 일부입니다.

내가 ORM을 사용하면서 본 가장 큰 주장은 "손으로 작성한 코드를 줄이고"비즈니스 로직과 데이터 액세스를 분리하는 추상화 계층을 제공한다는 것입니다. 나는 이것들 중 어느 것도 매우 단순한 경우를 제외하고는 사실이 아니라고 주장한다.

Hibernate (및 대부분의 다른 ORM 도구)가 작동하도록하려면 모든 데이터베이스 및 개체 상호 작용을 문서화하는 최대 절전 매핑 파일을 만들거나 주석을 사용하여 동일한 관계를 문서화합니다. 어떤 경우에는 테스트하기 더 어렵지만 덜 복잡하지는 않은 xml 구성 파일로 코드를 옮겼습니다. 다른 하나는 도메인 모델 전체에 데이터베이스와 상호 작용하는 방법에 대한 논리를 배포합니다. 요점은 실제 "코드"를 덜 작성했지만 코드를 구성 파일이나 주석으로 옮기는 것입니다! = "코드가 적습니다". 코드의 복잡성을 우리가 직접 제어하고 완화 할 수있는 코드에서 훨씬 적은 제어력을 가진 타사 도구로 이동합니다.

데이터베이스 계층에서 비즈니스 / 도메인 계층을 분리해야하는 ORM 추상화 계층은 이러한 "분리"에 대응하는 더 미묘한 효과를 갖는 경향이 있습니다. ORM 계층이 이상적이지 않은 것으로 간주되는 방식으로 개체 모델 및 / 또는 데이터베이스의 설계에 영향을 미치는 프로젝트를 몇 개나 보셨습니까? 잘못된 물리 비유를 사용하려면 비즈니스 계층, ORM 계층 및 데이터베이스 계층에 모두 질량이 있다고 가정합니다. 다른 층 사이에 ORM 층이 존재하는 것만으로도 다른 층을 변화시키고 뒤틀리는 힘을 발휘하는 경향이 있습니다. ORM 계층에 필요했기 때문에 비즈니스 모델에 적합하지 않은 기본 키 개체를 도입해야 했습니까? ORM 도구를 사용할 수 있기 때문에 특히 복잡한 개체 그래프 모델을 수용하기 위해 데이터베이스 구조를 조정해야 했습니까? 그렇지 않으면 처리합니까? 극단적으로 생각하면 ORM 계층의 존재는 데이터베이스 상호 작용이 작동하는 방식에 대한 전체 관점을 왜곡 할 수 있습니다. 지속되는 개체 그래프를 처리하는 서비스 계층 대신, 마치 격리 된 것처럼 각 도메인 개체에 대한 개별 데이터 액세스 계층 개체를 만드는 것으로 이어질 수 있습니다. 저는이 모든 시나리오를 다양한 각도에서 보았습니다. 아마도 ORM 도구 세트에 대한 경험이 없을 것입니다. 아마도 잘못된 데이터베이스 구조 일 수 있습니다. 나는 그것을 의심한다. 내가 본 모든 것은 ORM 솔루션이 부적절하다는 것을 나타냅니다. 마치 그들이 고립되어 사는 것처럼. 저는이 모든 시나리오를 다양한 각도에서 보았습니다. 아마도 ORM 도구 세트에 대한 경험이 없을 것입니다. 아마도 잘못된 데이터베이스 구조 일 수 있습니다. 나는 그것을 의심한다. 내가 본 모든 것은 ORM 솔루션이 부적절하다는 것을 나타냅니다. 마치 그들이 고립되어 사는 것처럼. 저는이 모든 시나리오를 다양한 각도에서 보았습니다. 아마도 ORM 도구 세트에 대한 경험이 없을 것입니다. 아마도 잘못된 데이터베이스 구조 일 수 있습니다. 나는 그것을 의심한다. 내가 본 모든 것은 ORM 솔루션이 부적절하다는 것을 나타냅니다.

데이터 액세스 계층이 복잡성 중 하나이고 성능 병목 현상이 발생하기 쉽다는 내 주장을 받아 들인다면, 더 적은 코드와 분리라는 목표를 달성하지 못하고 동시에 부정적인 영향을 미치는 도구를 추가하는 것을 고려해야하는 이유는 무엇입니까? 내 응용 프로그램의 다른 계층 구조?


@Marcelo Cantos의 답변에 철저히 응답했지만 ORM 사용의 주요 이점을 요약하겠습니다.

PI (Persistence Ignorance) 및 DDD (Domain Drive Design)

A ORM lends itself perfectly to both of these overall design patterns. For correct object orientated design you will work with hierarchical and polymorphic objects for expressing how data flows inside your application. With a good design you will frequently strive for POCO objects (plain old C/C# objects, I've seen other definitions of this word) because if I have a Person that has a List I should have just that. I shouldn't have a DataTable of persons and a DataTable of addresses that I somehow force to work with my application. Along with that I shouldn't need to tie tons of database specific logic to my objects, why should the FirstName field of my person need to be have something like [ColumnName("First_Name")] [Length(255)] [DataType(Types.Nvarchar)] or any other assortment of crazy attributes or code that defines how many database exists forced into my domain design?

Less Hand Written Code

There is a substantial reduction in the number of lines of code written when you remove the need to write an Select, Insert, Update and Delete statement for every single object in your application to save it to the database. This leaves you with only the need to write queries that mean something. Also many ORMs (like NHibernate) will include a language that is layered on top of SQL which is more defined to interact with and can be less syntactically filled of hoops.

The time this shows up fullest is consider an application that has a UserTable that is linked to every single object and for some reason you HAVE to change the primary key name or type. At this point you will potentially need to alter every single stored procedure in the database where with a correctly implemented ORM solution you will only need to alter a few configuration mappings (or possibly none) and it's done.


The basic benefit of using ORM tools is to facilitate the principal of separating the business logic from the data access in a multi-layered application. If you can successfully build a data access layer that is responsive to changes in the database (by changing your mapping), there is less overall code for you to have to muck around with when changes are made.

Separation of the layers is typically the goal of 3 tier or n-tiered applications, and ORM is a good method of doing that.


Primary driver: less overall code to manage/maintain


The question that I haven’t seen anyone address is what problem or problems ORMs are supposed to solve. The problem that ORMs are supposed to solve deal with the disconnection between application side code and the database and the amount of time developers spend with database concerns. The disconnection between the database and application code refers to having to run the application to realize that the code written referenced to an invalid column. ORMs are supposed to close this gap making for a model in which the database, application, and data move together; I compile I know code is out of sync (provided I keep my Model up-to-date).

I’ve used 3 different ORMs (EF, LINQ to SQL, and N-Hibernate), on various size projects from small to large enterprise applications. In addition I’m no stranger to going about it with ADO.NET; DataReaders and mapping to classes, DataSets and various generation tools. I have seen good and bad implementations in the 3 different ORMs and with no ORM method. The majority of problems I’ve seen go back to anti-patterns, and not understanding limitations of a particular ORM. The following article (Anti-Patterns To Avoid In N-Tier Applications) does a nice job of highlighting many of these Anti-Patterns. Even the best of software architects, developers, and just smart people have participated in their share of Anti-Patterns before they discovered a design pattern and or the value of certain design principles that solved the problem created by the Anti-Pattern.

Not knowing your tool is another issue because this is where issues with performance come in. It’s clear many are unsure of the performance differences between Dynamic SQL and stored procedures in respect to executing database logic such as CRUD operations. Well the verdict is in and Dynamic commands are proven to be just as efficient as their stored procedure counterparts. Both have advantages and disadvantages. The key is knowing what they are and selecting the appropriate choice for the situation.


If all I get from my ORM is to save me from the need to maintain stored procedures then that is good enough for me.

However there's much more in that an ORM allows us be free of the hostage-like grip database schemas impose on the design of our code. Things are much simpler when I can model my code exactly like the real world, and I can still do this with a (good) ORM which helps (and hides) the mapping of a potential unsightly legacy db with terrible naming conventions into a structure that means something and not care about redundant code like this everywhere:

using (SqlWrapper sql = SqlWrapper.Create(WrapperConnectionType.ShopNet, "sStore_InsertUpdate_v4"))
            {
                sql.AddParameter("StoreId", StoreId);
                sql.AddParameter("StoreName", StoreName);
                sql.AddParameter("Region", Region);
                sql.AddParameter("PostCode", PostCode);
                sql.AddParameter("Tel", Tel);
                sql.AddParameter("Email", Email);
                sql.AddParameter("RegionId", RegionId);
                sql.AddParameter("MapImage", MapImage);
                sql.AddParameter("ShopImage", ShopImage);
                sql.AddParameter("Visible", Visible ? 'Y' : 'N');
                sql.AddParameter("TazEnabled", TasEnabled ? 'Y' : 'N');
                sql.AddParameter("Latitude", Latitude);
                sql.AddParameter("Longitude", Longitude);
                sql.AddParameter("StoreOpeningDate", OpeningDate);
                sql.AddParameter("CustomerNo", CustomerNo);
                sql.AddParameter("ReserveAtStoreEnabled", RasEnabled);
                sql.AddParameter("OpeningHoursId", OpeningHours.Id);
                sql.AddParameter("AddressLine1", AddressLine1);
                sql.AddParameter("AddressLine2", AddressLine2);
                sql.AddParameter("City", City);
                sql.AddParameter("District", District);
                sql.AddParameter("County", County);
                sql.AddParameter("CountryCode", CountryCode);
                sql.AddParameter("GoogleCategories", GoogleCategories);
                sql.AddParameter("GooglePlacesEnabled", GooglePlacesEnabled);
                sql.AddParameter("ManagerName", ManagerName);
                sql.AddParameter("MapZoomLevel", MapZoomLevel);
                sql.AddParameter("IpAddress", IpAddress);
                sql.AddParameter("FlibbleEnabled", FlibbleEnabled);
                sql.AddParameter("RegionalManager", RegionalManagerId);
                sql.AddParameter("ShutlLogin", ShutlLogin);
                sql.AddParameter("ShutlPassword", ShutlPassword);
                sql.Execute();
            }

and lets eradicate (but not forget) these type of battles:

System.IndexOutOfRangeException
at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name)

The argument for me doesn't have to be any more complicated than that, I get a couple of nice things and something awful is taken away. Nuff said, Next!

No one is arguing that an ORM is a 100% replacement for everything traditional. It won't be a great tool for writing complex reports, for that use SPs and views, and use NHibernate to call them natively and map them automatically to your c# entities. Great, still all the power of SQL and no crappy mapping code.

Be gone into the darkness ye storer of 0s & 1s and come hither ye light of wholesome c# weltanschauung.


1 advantage you get is that your data layer is separated from the object layer, so when you have multiple applications/projects dependent on that layer you change it once in the ORM and all applications/projects that reference the object layer don't have to change, where as without it you would have to make changes in all projects.

참고URL : https://stackoverflow.com/questions/760834/how-can-i-design-a-java-web-application-without-an-orm-and-without-embedded-sql

반응형