SpringOne-DataAccess-Pollack

Download Report

Transcript SpringOne-DataAccess-Pollack

Welcome to

Introduction to Data Access with Spring.NET

Mark Pollack Principal CodeStreet LLC

Overall Presentation Goal

Learn about Spring.NET's support for ADO.NET, O/R Mappers, and transaction management abstraction

Speaker’s Qualifications

Mark Pollack is a founding partner at CodeStreet LLC, a software and consulting firm in the financial services industry.

.NET and J2EE architect and developer specializing in front office solutions, EAI, and message based middleware Spring Developer (2003) • JmsTemplate Founder of Spring.NET (2004) Co-lead of Spring.NET with Aleks Seovic

Quick overview of Spring.NET

.NET Data Access Landscape ADO.NET Framework NHibernate integration Transaction management

Outline

Spring.NET Overview

Concepts in Spring are not platform specific Want to build .NET apps in a similar way • Need for an application framework Not a blind port of Spring Version 1.0 released September 2005

Spring.NET subsystems Web AOP Desktop Services (Exporters) Core 3 rd Party Integration Data Access

Data Access Landscape

Wide range of data access strategies and technologies Developer toolbox has matured • PEAA – Fowler • Know how to ‘codify’ best practice patterns Technologies • ADO.NET, O/R Mappers Transaction Management • Local – ADO.NET

– System.Transactions (.NET 2.0) • Distributed - MS-DTC/COM+Services – EnterpriseServices (.NET 1.1) – – System.Transactions (.NET 2.0) .NET 3.0 (WinFX)

Spring Data Access

Provide uniform best practice approach across data access technologies.

IoC integration Transaction management • Programmatic and declarative Resource management • ‘Template’/callback APIs Exception Translation Added value • Make ‘native’ APIs easier to use – ADO.NET • Higher level encapsulation of Data Access – DAO support classes, “AdoOperation” objects

Spring.NET Data Access

“Spring.Java” users should feel right at home • • ADO.NET, to first order Java ported O/R Mappers, to second order.

ADO.NET framework NHibernate support • iBatis.NET under development.

Early Adopter stage • • Well hedged by “Spring.Java” design A small feature set used in production now.

– Daily P/L calculations and reporting for a major hedge fund.

ADO.NET API overview

Uniform API between “Text SQL” and Stored procedures • IDbCommand property: CommandType IDbParameters used extensively • In, Out, InOut, Return Few easy methods on Command class • • ExecuteScalar, ExecuteNonQuery, ExecuteReader DataSets – DataAdapter + CRUD IDbCommands Parameter binding • • By name is prevalent in API Generally, no fallback to generic placeholder if provider supports named parameters Transaction object • Can assign to a command object.

Motivations for ADO.NET framework

Provide usable provider independent API • • No factory in BCL (.NET 1.1) Simplistic and at times incomplete interfaces IoC integration • Connection String management Easier parameter management • BCL interfaces leads to verbose code Exception Handling • Not singly rooted (.NET 1.1) • • Base exception + error code (.NET 2.0) No portable “DAO” exception hierarchy

Motivations for ADO.NET framework II

Centralize resource management • • Connection, Command, DataReader ‘using’ is A Good Thing.

– Does reduce try/finally verbosity but ‘no catch’ Transaction management • Ad-hoc passing around of Transaction object API Quirks • Exception reading a null from IDataReader

AdoTemplate

Execute() • • • ICommandCallback, CommandDelegate Use of delegates – i.e. stateless callbacks.

Use of variable length arguments, boxing ExecuteScalar(), ExecuteNonQuery(), Query() • IRowCallback, IRowMapper, IResultSetExtractor Variations with • • IDbCommandSetter, IDbCommandCreator One “inline” parameter – string name, Enum dbType, int size, object parameterValue Factory Method for creating IDbParameters

Callback Interface

Central method of AdoTemplate • Resource Management • Transaction Aware

public interface IAdoOperations { . . . public Object Execute(ICommandCallback action); } public Object Execute(CommandDelegate del); public interface ICommandCallback { Object DoInCommand(IDbCommand command); } public delegate Object CommandDelegate(IDbCommand command);

Standard ADO.NET

public class NativeAdoTestObjectDao : ITestObjectDao { // Connection String Property ...

public void Create(string name, int age) { using (SqlConnection connection = new SqlConnection(connectionString)) { string sql = String.Format("insert into TestObjects(Age, Name) " + "VALUES ({0}, '{1}')", age, name); } } } using (SqlCommand cmd = new SqlCommand(sql, connection) { connection.Open(); comm.ExecuteNonQuery(); }

AdoTemplate Example public class TestObjectDao : AdoDaoSupport , ITestObjectDao { public void Create(string name, int age) { } } AdoTemplate.ExecuteNonQuery

( String.Format(CommandType.Text, "insert into TestObjects(Age, Name) " + "VALUES ({0}, '{1}')", age, name));

Connection String Management

Custom Schema to set common connection string properties • XML’ized .NET 2.0 Connection String builders

Parameter Creation IDbParameters parameters = adoTemplate.NewDbParameters(); parameters.Add("Name", DbType.String, 12).Value = name; parameters.Add("Age", SqlDbType.Int

).Value = age; adoTemplate.ExecuteNonQuery(CommandType.Text, sql, parameters);

Use any provider Sql Type Enumeration Helper methods for parameter creation • AddOut, AddInOut, DataSet related

AdoOperations

OO model for DB operations • Preferred approach

AdoQuery

- Result set mapping to objects

AdoNonQuery AdoScalar –

Insert/Update/Delete Return single value

StoredProcedure

• out parameters and multiple result sets

AdoDataSetQuery*

– Return DataSet Use of

ICommandCreater

implementation for efficient parameter re-creation.

MappingAdoQuery public class TestObjectQuery : MappingAdoQuery { private static string sql = "select TestObjectNo, Age, Name from TestObjects"; } public TestObjectQuery(IDbProvider dbProvider) : base(dbProvider, sql) { CommandType = CommandType.Text; }

NullMappingDataReader

reader, protected override object MapRow( IDataReader int num) { TestObject to = new TestObject(); to.ObjectNumber = reader.GetInt32(0); to.Age = reader.GetInt32(1); to.Name = reader.GetString(2); return to; }

NullMappingDataReader TestObjectQuery testObjectQuery = new TestObjectQuery(dbProvider); IList testObjectList = testObjectQuery.Query();

IDataReaderWrapper • • • NullMappingDataReader implementation Specified in AdoTemplate Say goodbye to code like this…

to.ObjectNumber = (!reader.IsDBNull(0)) ? reader.GetInt32(0) : -1; to.Age = (!reader.IsDBNull(1)) ? reader.GetInt32(1) : -1; to.Name = (!reader.IsDBNull(2)) ? reader.GetString(2) : String.Empty;

AdoNonQuery public class CreateTestObjectNonQuery : AdoNonQuery { private static string sql = "insert into TestObjects(Age,Name) values (@Age,@Name)"; public CreateTestObjectNonQuery(IDbProvider dbProvider) : base(dbProvider, sql) { } DeclaredParameters.Add("Age", DbType.Int32); DeclaredParameters.Add("Name", SqlDbType.NVarChar, 16); Compile(); } public void Create(string name, int age) { ExecuteNonQuery(name, age); }

Variable length arguments

StoredProcedure

ADO.NET supports discovery of Stored Procedure parameters.

public class CallCreateTestObject : StoredProcedure { public CallCreateTestObject(IDbProvider dbProvider) Compile(); : base(dbProvider, "CreateTestObject") { DeriveParameters(); } } public void Create(string name, int age) { ExecuteNonQuery(name, age); }

StoredProcedure

Easy access to out parameters

public class CallCreateTestObject : StoredProcedure { public CallCreateTestObject(IDbProvider dbProvider) Compile(); : base(dbProvider, "CreateTestObject") { DeriveParameters(); } } public void Create(string name, int age) { IDictionary inParams = new Hashtable(); inParams["name"] = name; inParams["age"] = age; IDictionary outParams = ExecuteNonQuery(inParams); }

O/R Mapping Support

Easy ‘porting’ code/concepts from .NET versions of Java O/R • • NHibernate IBatis.NET

Two levels of support • • IoC helpers for central object injection/configuration Template classes for resource/tx management.

Others as well….

• • • • • DB40 WilsonORM Gentle.NET

Neo Microsoft - ADO.NET 3.0 LINQ for X.

NHibernate Example public class NativeNHTestObjectDao : ITestObjectDao { // SessionFactory property ...

public void Create(TestObject to) { ISession session = null; ITransaction transaction = null; try { session = SessionFactory.OpenSession(); transaction = session.BeginTransaction(); session.Save(to); transaction.Commit(); } catch { if(transaction != null) transaction.Rollback(); throw; } finally { if(session != null) session.Close(); } } }

NHibernateTemplate DAO Implementation public class NHTestObjectDao : HibernateDaoSupport , ITestObjectDao { [Transaction()] public void Create(TestObject to) { HibernateTemplate.Save(to); } }

Support for declarative and programmatic transaction management for any data access technology

Microsoft Transaction Management

ADO.NET (1.1) EnterpiseServices (1.1) System.Transactions (2.0)

.NET 3.0 (WinFX)

Local     Distributed Declarative     Programmatic         The sweet spot • Declarative transaction management + local transactions

ADO.NET Transactions

ADO.NET

• • Connection/Transaction pair.

Associate multiple DbCommands with the same transaction • API –

Transaction.Begin(), Commit(), Rollback()

EnterpriseService Transactions

Access to COM+ services • • MS-DTC for transaction management Declarative transaction demarcation features Cumbersome to deploy and develop • • Declarative demarcation only at class level NB: Spring.Services provides an EnterpriseServicesExporter Originally required inheriting from

ServicedComponent

Providers are aware of transaction context of the thread • Similar to approach in Spring Template/TxMgr but part of standard ADO.NET API.

Always uses MS-DTC to access database API •

ServiceDomain.Enter(), Leave; ContextUtil.SetAbort()

.NET 2.0 Transactions

Easy to use programming model Providers are aware of transaction context of the thread Uses most efficient means of db access • Local transactions can be promoted to distributed – “Promotable Single Phase Enlistment” (PSPE) • Only Microsoft providers for now – SqlServer 2005, MSMQ.

API • •

new TransactionScope(); .Complete(), Dispose(), Transaction.Current.Rollback()

Transaction Managers AdoPlatformTransactionManager

• Local transactions

ServiceDomainPlatformTransactionManager

• Distributed transactions

TxScopePlatformTransactionManager

• Local or Distributed as needed.

Switching is just a small configuration change.

Callback interfaces •

ITransactionCallback

TODOs

Use ADO.NET and O/R Mappers within in same transaction “KeyHolder” to easily access created keys Custom schema for transaction mgmt DataSet functionality LOB support Nested Transactions…

Summary

Spring’s approach to Data Access is very applicable to .NET development ADO.NET framework will give you real productivity gains Give it a whirl • • Feedback more than welcome!

www.springframework.net

Q&A

DEMO