Fox DB Access¶
Fox DB Access 는 NeoDEEX 에서 제공하는 데이터베이스 액세스 프레임워크 입니다. Fox DB Access 의 FoxDbAccess
클래스가 제공하는 단일 API 를 사용하여 MS SQL Server, Oracle, PostgreSQL, MySQL 과 같은 다양한 데이터베이스에 접근이 가능합니다. 또한 Fox DB Access 의 API 는 ADO.NET 이라 불리는 데이터액세스 API 들 보다 훨씬 사용하기 간편하며 성능이 고려된 API 입니다.
Fox DB Access 에 포함된 Fox Query 는 MyBatis 와 유사한 SQL 매퍼 기능을 제공합니다. 즉, SQL 문장을 외부 XML 파일(.foxml
)에 기록해두고 이 SQL 문장들을 읽어 수행할 수 있습니다. Fox Query 를 통해 코드와 SQL 문장을 분리할 수 있으며 코드 수정 없이 쿼리를 변경할 수 있습니다.
이 외에도 Fox DB Access 는 FoxDbAccess
클래스를 통해 수행되는 모든 SQL 문장에 대한 로그를 남길 수 있습니다. 수행되는 SQL 문장, 쿼리 수행 시간, 매개변수 값, 쿼리를 수행한 사용자 ID 등 쿼리와 관련된 다양한 정보를 Fox Logging 을 통해 파일, DB 등에 기록이 가능합니다.
-
Fox DB Access 를 사용하는 방법을 단계적인 예제를 통해 빠르게 익히고 개념을 이해할 수 있습니다.
What's the problem?¶
.NET 환경에서 전통적인 데이터 액세스 방법은 데이터 제공자(data provider)라 불리는 데이터베이스별 라이브러리를 사용하였습니다. MS SQL 에 접근하기 위해서는 MSSQL Data Provider 인 Microsoft.Data.SqlClient
패키지를 사용해야 하며, Oracle 에 접근하기 위해서는 Managed ODP.NET Core 를 사용해야 합니다.
이렇게 각 데이터베이스 별로 서로 다른 데이터 제공자를 사용해야 하며 각 데이터 제공자 라이브러리는 서로 다른 데이터 액세스 객체들을 제공합니다. 예를 들어 MS SQL 을 위한 데이터 제공자는 SqlConnection
, SqlCommand
, SqlDataAdapter
등의 클래스를 제공하며 PostgreSQL 을 위한 Npgsql 데이터 제공자는 NpgsqlConnection
, NpgsqlCommand
, NpgsqlDataAdapter
등의 클래스를 제공합니다.
따라서 데이터액세스 코드는 데이터 제공자에 맞도록 작성되어야 했습니다. 다음 코드는 PostgreSQL 을 위한 데이터 액세스 코드입니다. 이 코드에서 연결을 위해 NpgsqlConnection
객체를 생성하였고 SQL 문장 수행을 위해 NpgsqlCommand
객체를 생성하여 ExecuteScalar
메서드를 호출하였습니다.
위와 같은 전통적인 데이터 액세스 코드는 다음과 같은 문제점을 가지고 있습니다.
-
복잡하고 지루한 코드의 반복
데이터 액세스마다
Command
객체를 생성해야 하며 SQL 문장이 매개변수를 사용한다면(99%의 쿼리가 매개변수를 사용할 것입니다) 코드는 더욱 복잡해질 수 있습니다. 이러한 코드들은 상당한 양의 코드 라인을 필요로하며 대개의 경우 반복적으로 나타나게 됩니다. -
복잡한 연결 관리 코드
데이터베이스에 대한 연결을 열고 닫을 때 예외 발생 시 닫히지 않는 연결을 방지하기 위해
try~finally
문장을 사용해야합니다. 만약 트랜잭션이 관여되면 중첩된try~catch~finally
문장을 사용해야 할 수도 있습니다. -
낮은 이식성
특정 데이터베이스에 대한 데이터 액세스 코드는 다른 데이터베이스에 대한 이식성이 매우 낮습니다. 두 데이터베이스가 동일한 스키마를 제공하고 표준적인 SQL 문장을 사용할 수 있다할지라도 데이터 제공자마다 서로 다른
Connection
,Command
등의 타입을 사용하기 때문입니다. -
하드 코드된 쿼리
쿼리에 사용되는 SQL 문장 혹은 저장 프로시저 이름이 하드 코드되어 있기 때문에 쿼리를 변경하면 빌드와 배포를 다시 해야 합니다. 쿼리가 자주 변경되는 기업내 LOB 환경에서 앱 코드를 자주 빌드하고 배포하기 쉽지 않을 수 있습니다.
Fox DB Access 에 대한 이해¶
Fox DB Access 는 앞서 언급한 전통적인 데이터 액세스의 불편함을 줄이기 위한 라이브러리 입니다. Fox DB Access 는 NeoDEEX 가 지원하는 여러 .net 데이터 프로바이더들에 대해 wrapper 클래스들을 제공합니다.
편리한 데이터 액세스¶
예를 들어 FoxNpgsqlDbAccess
클래스는 Npgsql 데이터 프로바이더이 여러 API 들에 대해 연결 관리, 편리한 데이터 액세스 등의의 기능을 제공합니다. FoxNpgsqlDbAccess
클래스를 사용하면 기존 데이터 액세스 코드는 다음과 같이 작성할 수 있습니다.
FoxNpgsqlDbAccess
클래스는 내부적으로 NpgsqlConnection
객체를 생성하며 ExecuteSqlScalar
메서드는 데이터베이스 연결을 열고 NpgsqlCommand
객체를 생성하여 쿼리를 수행한 후 데이터베이스 연결을 닫고 결과를 반환합니다. 레거시 데이터액세스 코드에 비해 Fox DB Access 를 사용한 데이터 액세스 코드는 간결하며 효율적입니다. 또한 데이터베이스 연결은 프레임워크 내부에서 자동으로 처리되어 적절하게 열리고 닫히게 됩니다.
Information
ExecuteSqlScalar
와 같은 쿼리 수행 메서드들은 데이터베이스에 대한 연결의 상태에 따라 자동으로 연결을 열거나 닫습니다. 만약 데이터베이스 연결이 이미 열려있다면 열기를 수행하지 않으며 닫기 역시 수행하지 않습니다. 데이터베이스 연결 관리에 대한 상세한 내용은 연결 관리 문서를 참고 하십시요.
단일 API¶
Fox DB Access 의 데이터 액세스 클래스인 FoxNpgsqlDbAccess
클래스는 FoxDbAccess
추상 클래스(abstract class)에서 파생된 구체 클래스(concrete class) 입니다. FoxDbAccess
클래스를 활용하여 의존성 주입(dependency injection) 패턴을 사용할 수 있습니다. NeoDEEX 의 구성 설정에서 생성할 구체 클래스를 지정하고 FoxDbAccess
클래스의 CreateDbAccess
메서드를 호출할 수 있습니다.
다음 neodeex.config.json
파일은 데이터 액세스에 관련된 구성 설정의 예를 보여 줍니다. 이 구성 설정에서 PostgreSQL 데이터베이스에 접속하기 위해 구체 클래스로 FoxNpgsqlDbAccess
클래스를 지정하고 관련된 연결 문자열도 지정하고 있습니다.
Note
NeoDEEX 의 구성 설정에 대한 기본적인 내용은 Fox Configuration 기능을 참고 하십시요.
이제 데이터 액세스 코드는 FoxNpgsqlDbAccess
타입과 같은 구체 클래스를 사용하지 않고 FoxDbAccess
추상 클래스를 사용하여 다음과 같이 작성할 수 있습니다.
위와 같은 코드의 장점은 특정 데이터베이스에 의존적인 타입을 사용하지 않기 때문에 이식성이 높아진다는 것입니다. 이식성을 고려하지 않더라도 다른 데이터베이스에 대한 코드 역시 위와 동일하게 FoxDbAccess
타입을 사용하여 데이터 액세스 코드를 작성할 수 있습니다. Fox DB Access 는 이처럼 데이터베이스에 의존적이지 않은 단일 API 를 사용하여 데이터베이스 액세스를 가능하게 합니다.
Query mapper¶
Fox Db Access 가 제공하는 Fox Query 기능은 위와 코드에서 처럼 SQL 문장이 소소 코드에 하드 코드 되는 것을 막을 수 있습니다. Fox Query 는 별도의 XML 파일인 .foxml
파일을 읽어 SQL 문장을 사용하여 쿼리를 수행하도록 할 수 있습니다. 이처럼 쿼리들을 코드가 아닌 외부 파일에 기록해 두고 쿼리를 읽어 수행하는 기능을 쿼리 매퍼(query mapper) 혹은 SQL 매퍼(SQL mapper)라 부르며 대표적인 쿼리 매퍼 라이브러리로 MyBatis 가 있습니다. MyBatis 수준은 아니지만 Fox Query 는 국내 실정에 사용하기 편리한 수준에서 쿼리 매퍼 기능을 제공합니다.
다음은 Foxml 파일의 예로서 northwind.foxml
파일의 예 입니다.
northwind.foxml
파일 내의 쿼리를 사용하는 코드는 다음과 같습니다.
위 코드에서 ExecuteQueryScalar
메서드는 northwind.foxml
파일의 <statement>
태그들 중에서 id
가 get_product
인 태그를 찾아 SQL 문장을 읽어 쿼리를 수행합니다.
FoxDbAccess
추상 클래스 및 의존성 주입 패턴과 Fox Query 는 코드의 데이터베이스 의존도를 크게 낮출 수 있습니다. 데이터베이스가 PostgreSQL 에서 Oracle 로 변경된다면 구성 설정 파일과 .foxml
파일을 수정 혹은 교체함으로써 손쉽게 대처가 가능합니다.
Monitoring¶
Fox DB Access 는 FoxDbAccess
클래스 혹은 그 파생 클래스들에 의해 수행되는 쿼리들에 대한 상세한 정보를 기록하는 기능을 가지고 있습니다. 이 기능을 Fox DB Profile 이라 부릅니다. Fox DB Profile 은 활성화 되면 수행되는 쿼리의 SQL 문장, 수행 시간, 매개변수 값등의 정보를 수집합니다. 그리고 수집된 정보를 호출자에게 반환하거나 로그에 기록할 수 있습니다. 다음은 로그에 기록된 쿼리 수행 정보입니다.
Fox DB Profile 을 통해 수행되는 쿼리의 낮은 성능, 기대하지 않은 쿼리 결과와 같은 문제점을 파악할 수 있습니다. 별도의 데이터베이스 도구를 사용하지 않더라고 기본으로 제공되는 진단 기능을 활용하여 개략적으로 데이터 액세스의 문제점을 인지할 수 있고 이를 기본으로 전문적인 쿼리 모니터링 도구나 튜닝 도구를 활용하여 정확한 문제 파악 및 해결을 시도할 수 있습니다.
Summary¶
Fox DB Access 는 앞서 나열한 기능들을 통해 편리하고 강력한 데이터 액세스 코드를 구축할 수 있습니다. 개발자들은 편리한 API 를 통해 데이터베이스 연결이나 트랜잭션 관리 등의 반복적이고 부차적인 부분보다 비즈니스 로직이나 효율적인 쿼리 구사에 집중할 수 있습니다.