20
Omaha Java Users Group March 18, 2008 Corey A. Spitzer

iBATIS

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: iBATIS

Omaha Java Users Group

March 18, 2008

Corey A. Spitzer

Page 2: iBATIS

The Context

• J2EE (with Spring)

• OOP

• SQL Relational Database

Page 3: iBATIS

What is iBATIS?

DatabaseLogic / DAO

CodeiBATIS

Object Oriented

Relational

Object

Query

Page 4: iBATIS

A More Detailed Look

SqlMapClient

SQL Maps

insert()

update()

delete()

query()

loads

javax.sql.DataSource

calls

Queries

Result Maps

Database

MagicMagic

Codecalls

Page 5: iBATIS

The SQL Map Anatomy

<sqlMap namespace="myNamespace">

<resultMap id="myClass" class="full.package.MyClass">

<result property="foo" column="col1"/>

<result property="bar" column="col2"/>

...

</resultMap>

...

<!-- ===================================================== -->

<sql id="myQuery" resultMap="myClass">

SELECT col1, col2 FROM table1

</sql>

...

</sqlMap>

SqlMapClient

SQL Maps

loads

DataSource

calls

Database

MagicMagic

Codecalls

Page 6: iBATIS

The Code Anatomyimport java.sql.SQLException;

import com.ibatis.sqlmap.client.SqlMapClient;

...

public class MyDAO

{

private SqlMapClient myDB;

public void frobnicate(MyObject someObject) throws SQLException

{

List<MyClass> list = myDB.queryForList("myQuery");

Foo myFoo = (Foo)myDB.queryForObject("getFooByID", 1337);

myDB.update("myQuery3");

myDB.insert("myQuery4", someObject);

...

}

...

}

SqlMapClient

SQL Maps

loads

DataSource

calls

Database

MagicMagic

Codecalls

Page 7: iBATIS

Any Questions so far?

SqlMapClient

SQL Maps

insert()

update()

delete()

query()

loads

javax.sql.DataSource

calls

Queries

Result Maps

Database

MagicMagic

Codecalls

Page 8: iBATIS

Implicit Mapping

<sqlMap namespace="myNamespace">

<resultMap id="myClass" class="full.package.Class">

<result property="foo" column="col1"/>

<result property="bar" column="col2"/>

...

</resultMap>

...

<!-- ===================================================== -->

<sql id="myQuery" resultClass="full.package.Class">

SELECT col1 as foo, col2 as bar FROM table1

</sql>

...

</sqlMap>

Page 9: iBATIS

Inheritance

Fruit

id - int

dateBought - long

Apple

wormCount - float

Orange

bioengineered - boolean

Object Oriented Code Relational Database

fruits

id - mediumint(7), PK

date_bought - int(11)

type - enum('a', 'o')

apples

fruit_id - mediumint(7), FK

worm_count - decimal(4,1)

oranges

fruit_id - mediumint(7), FK

bioengineered - bool

Page 10: iBATIS

Complex Members

Cake

id - int

flavor - String

toppings - List<CakeTopping>

CakeTopping

id - int

name - String

containsHFCS - boolean

Object Oriented Code Relational Database

cakes

id - mediumint(7), PK

flavor - enum('chocolate', ...)

cakes_to_toppings

cake_id - mediumint(7), FK

topping_id - mediumint(7), FK

cake_toppings

id - mediumint(7), PK

name - varchar(20)

contains_hfcs - bool

Page 11: iBATIS

Parameters & Dynamic Queries

Page 12: iBATIS

Custom Type Handlers

public class YesNoBoolTypeHandler implements TypeHandlerCallback {

public Object getResult(ResultGetter getter) throws SQLException {

if ("Y".equalsIgnoreCase(getter.getString())) {

return new Boolean (true);

} else if ("N".equalsIgnoreCase(getter.getString())) {

return new Boolean (false);

} else {

throw new SQLException();

}

}

public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {

if (((Boolean)parameter).booleanValue()) setter.setString("Y");

else setter.setString("N");

}

public Object valueOf(String s) {

return new Boolean ("Y".equalsIgnoreCase(s));

}

}

Page 13: iBATIS

Custom Type Handlers

<resultMap id="myClass" class="my.package.MyClass">

...

<result property="foo" column="bar" typeHandler="some.package.YesNoBoolTypeHandler"/>

...

</resultMap>

<insert id="myQuery" resultMap="myClass" parameterClass="my.package.MyClass">

INSERT INTO table1 SET bar = #foo,handler=some.package.YesNoBoolTypeHandler#

</insert>

Page 14: iBATIS

Paging / Selecting a Range

Page 15: iBATIS

selectKey

<insert id="addForumThread" parameterClass="java.util.HashMap">

INSERT INTO forum_threads SET

forum_id = #forumID#,

title = #title#,

created_time = #createdTime#,

last_updated_time = #createdTime#,

<selectKey resultClass="int">

SELECT MAX(id) FROM forum_threads

</selectKey>

</insert>

Page 16: iBATIS

Caching Features

<cacheModel id="fooCache" type="{LRU|MEMORY|FIFO|OSCACHE}" readOnly="{true|false}" serialize="{true|false}">

<flushInterval hours="24"/>

<flushOnExecute statement="insertFoo"/>

<flushOnExecute statement="updateFoo"/>

<flushOnExecute statement="deleteFoo"/>

<property name="size" value="1000"/>

</cacheModel>

<select id="getFoo" cacheModel="fooCache">

SELECT * FROM bar WHERE id = #value#

</select>

<insert id="insertFoo">

INSERT INTO bar SET ...

</insert>

...

Page 17: iBATIS

Transactions

public updateItemDescription(String itemId, String newDescription) throws SQLException{

try {

sqlMap.startTransaction();

Item item = (Item) sqlMap.queryForObject("getItem", itemId);

item.setDescription (newDescription);

sqlMap.update("updateItem", item);

sqlMap.commitTransaction();} finally {

sqlMap.endTransaction();}

}

Page 18: iBATIS

What About Hibernate?

• Separation of code and SQL

• Simpler configuration and setup*

• Total control over SQL queries

• Shallow learning curve

• Handles application complexities

better**

iBATIS Hibernate• SQL alongside code

• Cross-DB query language (HQL)

• ???

• Works very well when data model

closely resembles object model**

**No Fluff Just Stuff's Mark Richards' two cents:

http://www.nofluffjuststuff.com/media.jsp?mediaId=27

*Source: http://www.devx.com/Java/Article/31481/0/page/1

Page 19: iBATIS

Who is Using iBatis?

• CNet.com

• MySpace.com

• OfficeMax.com

• JPMorganChase.com

• 1up.com

• PowerSentry.com

(and more)

Source: http://www.ociweb.com/mark/programming/iBATIS.html#WhoUses

Page 20: iBATIS

Now What?

http://ibatis.apache.org