Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

38
Welcome to

Transcript of Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Page 1: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Welcome to

Page 2: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Introduction to Data Access with Spring.NET

Mark Pollack

PrincipalCodeStreet LLC

Page 3: 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

Page 4: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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

Page 5: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Outline

Quick overview of Spring.NET

.NET Data Access Landscape

ADO.NET Framework

NHibernate integration

Transaction management

Page 6: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Spring.NET Overview

Concepts in Spring are not platform specificWant to build .NET apps in a similar way• Need for an application framework

Not a blind port of SpringVersion 1.0 released September 2005

Page 7: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Spring.NET subsystems

Core

AOPServices

(Exporters)Data Access

Web Desktop3rd Party

Integration

Page 8: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Data Access Landscape

Wide range of data access strategies and technologiesDeveloper 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)

Page 9: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Spring Data Access

Provide uniform best practice approach across data access technologies.IoC integrationTransaction management • Programmatic and declarative

Resource management• ‘Template’/callback APIs

Exception TranslationAdded value• Make ‘native’ APIs easier to use – ADO.NET • Higher level encapsulation of Data Access

– DAO support classes, “AdoOperation” objects

Page 10: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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.

Page 11: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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.

Page 12: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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

Page 13: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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

Page 14: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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

Page 15: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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);

Page 16: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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(); } } }}

Page 17: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

AdoTemplate Examplepublic 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));

}}

<object id="testObjectDao" type=“MyApp.DAL.TestObjectDao,MyApp.DAL"> <property name="ConnectionString" value="Data Source=(local);Database=Spring;

UserID=springqa;Password=springqa; Trusted_Connection=False"/>

</object>

Page 18: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Connection String Management

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

<sqlServerConnection name="myConnectionString" dataSource="(local)" initialCatalog="Northwind" persistSecurityInfo="true" userID=“${userID}" password="${password}" />

Page 19: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Parameter Creation

Use any provider Sql Type Enumeration

Helper methods for parameter creation• AddOut, AddInOut, DataSet related

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);

Page 20: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

AdoOperations

OO model for DB operations• Preferred approach

AdoQuery - Result set mapping to objectsAdoNonQuery- Insert/Update/DeleteAdoScalar – Return single valueStoredProcedure • out parameters and multiple result sets

AdoDataSetQuery* – Return DataSetUse of ICommandCreater implementation for efficient parameter re-creation.

Page 21: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

public class TestObjectQuery : MappingAdoQuery {

private static string sql = "select TestObjectNo, Age, Name from

TestObjects"; public TestObjectQuery(IDbProvider dbProvider) : base(dbProvider, sql) { CommandType = CommandType.Text; }

protected override object MapRow(IDataReader reader, int num) {

TestObject to = new TestObject(); to.ObjectNumber = reader.GetInt32(0); to.Age = reader.GetInt32(1); to.Name = reader.GetString(2); return to; }}

MappingAdoQuery

NullMappingDataReader

Page 22: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

NullMappingDataReader

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;

TestObjectQuery testObjectQuery = new TestObjectQuery(dbProvider);

IList testObjectList = testObjectQuery.Query();

Page 23: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

AdoNonQuerypublic 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

Page 24: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

StoredProcedure

ADO.NET supports discovery of Stored Procedure parameters.

public class CallCreateTestObject : StoredProcedure {

public CallCreateTestObject(IDbProvider dbProvider) : base(dbProvider, "CreateTestObject") { DeriveParameters(); Compile(); }

public void Create(string name, int age) { ExecuteNonQuery(name, age); }}

Page 25: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

StoredProcedure

Easy access to out parameterspublic class CallCreateTestObject : StoredProcedure {

public CallCreateTestObject(IDbProvider dbProvider) : base(dbProvider, "CreateTestObject") { DeriveParameters(); Compile(); }

public void Create(string name, int age) { IDictionary inParams = new Hashtable(); inParams["name"] = name; inParams["age"] = age; IDictionary outParams = ExecuteNonQuery(inParams); }}

Page 26: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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.

Page 27: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

NHibernate Examplepublic 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(); } }}

Page 28: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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

Page 29: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Microsoft Transaction Management

Local Distributed Declarative Programmatic

ADO.NET (1.1)

EnterpiseServices (1.1)

System.Transactions (2.0)

.NET 3.0 (WinFX)

The sweet spot• Declarative transaction management + local

transactions

Page 30: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

ADO.NET Transactions

ADO.NET• Connection/Transaction pair.• Associate multiple DbCommands with the

same transaction• API

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

Page 31: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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 ServicedComponentProviders 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 databaseAPI• ServiceDomain.Enter(), Leave; ContextUtil.SetAbort()

Page 32: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

.NET 2.0 Transactions

Easy to use programming model Providers are aware of transaction context of the threadUses 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()

Page 33: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Transaction Managers

AdoPlatformTransactionManager

• Local transactionsServiceDomainPlatformTransactionManager

• Distributed transactionsTxScopePlatformTransactionManager

• Local or Distributed as needed.

Switching is just a small configuration change.Callback interfaces• ITransactionCallback

Page 34: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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…

Page 35: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

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

Page 36: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

Q&A

Page 37: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.

DEMO

Page 38: Welcome to. Introduction to Data Access with Spring.NET Mark Pollack Principal CodeStreet LLC.