<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4368777317649012081</atom:id><lastBuildDate>Thu, 16 Feb 2012 06:37:01 +0000</lastBuildDate><category>ruby</category><category>i18n</category><category>javascript</category><category>java</category><category>mysql</category><category>funny</category><category>interesting</category><category>pojo</category><category>junit</category><category>jstl</category><category>videos</category><category>jsp</category><category>web applications</category><category>tomcat</category><category>gui</category><category>opinions</category><category>mybatis</category><category>log4j</category><category>el</category><category>android</category><category>css</category><category>struts</category><category>agile</category><category>git</category><category>servlets</category><category>rails</category><category>dao</category><category>logback</category><category>eclipse</category><category>wsh</category><category>tld</category><title>The IdleWorx Blog</title><description>Java,Tomcat,Servlets,JSP,Android,Ruby and other programming stuff</description><link>http://blog.idleworx.com/</link><managingEditor>noreply@blogger.com (IdleWorx)</managingEditor><generator>Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/idleworxblog" /><feedburner:info uri="idleworxblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-5938111996039499377</guid><pubDate>Sat, 22 Dec 2012 00:56:00 +0000</pubDate><atom:updated>2011-06-28T18:01:48.312-07:00</atom:updated><title>Welcome to the IdleWorx blog</title><description>&lt;p&gt; This is the official blog of &lt;a href="http://www.idleworx.com" target="_blank"&gt;idleworx.com&lt;/a&gt;. 
A blog covering Android, JSP, Servlets, Tomcat, JavaScript, Ruby and other web development stuff. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-5938111996039499377?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cT4iRsOpZgaw7_KAhIzaifHRrvc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cT4iRsOpZgaw7_KAhIzaifHRrvc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cT4iRsOpZgaw7_KAhIzaifHRrvc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cT4iRsOpZgaw7_KAhIzaifHRrvc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/1KaJL_HhDFg/welcome.html</link><author>noreply@blogger.com (IdleWorx)</author><feedburner:origLink>http://blog.idleworx.com/2000/01/welcome.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-4455820721088616223</guid><pubDate>Mon, 06 Feb 2012 00:50:00 +0000</pubDate><atom:updated>2012-02-05T16:50:37.632-08:00</atom:updated><title>The Do Not Track movement is useless</title><description>&lt;h2&gt;
... or why privacy is your own responsibility&lt;/h2&gt;
The &lt;b&gt;Do Not Track&lt;/b&gt; movement (&lt;a href="http://donottrack.us/"&gt;donottrack.us&lt;/a&gt;)&amp;nbsp;is, according to their website&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;"a technology and policy proposal that enables users to opt out of tracking by websites they do not visit"&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
and from a recent article in USA Today,&amp;nbsp;&lt;a href="http://www.usatoday.com/tech/news/story/2011-11-15/facebook-privacy-tracking-data/51225112/1" target="_blank"&gt;How Facebook tracks you across the web&lt;/a&gt;&amp;nbsp;we find out the following&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;"Facebook's efforts to track the browsing habits of visitors to its site have made the company a player in the "Do Not Track" debate, which focuses on whether consumers should be able to prevent websites from tracking the consumers' online activity."&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Companies like Facebook, Google, etc have a vested interest in finding out as much information about &lt;b&gt;EVERYTHING&lt;/b&gt; you do.&amp;nbsp;That's how they make money. So any &lt;i&gt;movement&lt;/i&gt;&amp;nbsp;that proposes these companies self-regulate and take more care of our&amp;nbsp;privacy needs is simply useless. &lt;br /&gt;
&lt;br /&gt;
Even if regulation was passed forcing these companies to allow users to opt out of tracking,&amp;nbsp;that doesn't mean it wouldn't still occur.&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://donottrack.us/"&gt;donottrack.us&lt;/a&gt; website also mentions that&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;"Several large third parties have already committed to honor Do Not Track ... "&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
So what? Does that mean anything really?&lt;br /&gt;
&lt;br /&gt;
What do you know about what they do with this information even if they "&lt;i&gt;committed"&lt;/i&gt;&amp;nbsp;to work against their own self and business interests&amp;nbsp;by not tracking you?&lt;br /&gt;
&lt;br /&gt;
I'll tell you. Absolutely nothing!&lt;br /&gt;
&lt;br /&gt;
Do you have a signed contract with them that says they can never track you?&amp;nbsp;Is there an actual law&amp;nbsp;that prevents them from tracking you? No?&amp;nbsp;Then stop daydreaming.&lt;br /&gt;
&lt;br /&gt;
When it comes to personal privacy and security, you can't outsource it (especially to those who have an interest in your lack of privacy). There's no easy way.
&lt;br /&gt;
&lt;br /&gt;
So if you care about &lt;a href="http://www.schneier.com/blog/archives/2009/12/my_reaction_to.html" target="_blank"&gt;your privacy&lt;/a&gt;, &lt;a href="http://www.documentary24.com/privacy-is-dead-get-over-it--317/" target="_blank"&gt;educate yourself&lt;/a&gt;&amp;nbsp;and &lt;a href="http://torrentfreak.com/which-vpn-providers-really-take-anonymity-seriously-111007/" target="_blank"&gt;protect yourself&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-4455820721088616223?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4hO0L2PJracjCSPx0AWzWdPcpK8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4hO0L2PJracjCSPx0AWzWdPcpK8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4hO0L2PJracjCSPx0AWzWdPcpK8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4hO0L2PJracjCSPx0AWzWdPcpK8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/HO5pFMwwjqg/do-not-track-movement-is-useless.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2012/02/do-not-track-movement-is-useless.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-5381207489493623322</guid><pubDate>Thu, 02 Feb 2012 06:22:00 +0000</pubDate><atom:updated>2012-02-01T22:22:01.079-08:00</atom:updated><title>Goodbye Delicious, Hello Pinboard</title><description>&lt;br /&gt;
&lt;h2&gt;
&lt;span style="font-weight: normal;"&gt;Goodbye Delicious&lt;/span&gt;&lt;/h2&gt;
There are two types of people in the world, those who rarely save bookmarks, and those who have thousands. If you're like me, you probably have thousands or at least a few hundred. For me it's more exactly 4466 bookmarks at last count. (If you're not like me, a &lt;i&gt;bookmark hoarder&lt;/i&gt;, then you probably want to skip this article.)&lt;br /&gt;
&lt;br /&gt;
Over the past 10-15 years I've collected tons of bookmarks because I like to keep track of cool, useful and interesting things I find online so if I ever want to go back to them I can.&lt;br /&gt;
&lt;br /&gt;
I've spent countless hours over the years keeping things clean, ordered and organized so I can actually make use of this information. As you can imagine if you don't keep this many bookmarks organized and neat there's absolutely no point in saving them in the first place, since you won't be able to find anything if you so choose at a later time.&lt;br /&gt;
&lt;br /&gt;
Bookmarks, when used correctly are nothing more than a self maintained cache of the things you've found most interesting or useful. Thus they are a treasure trove of data for various services such as &amp;nbsp;&lt;a href="http://delicious.com/" target="_blank"&gt;delicious&lt;/a&gt;&amp;nbsp;or &lt;a href="http://en.wikipedia.org/wiki/List_of_social_bookmarking_websites" target="_blank"&gt;various others&lt;/a&gt; which have capitalized on this.&lt;br /&gt;
&lt;br /&gt;
Delicious was founded in 2003, and was essentially the company that introduced social bookmarking and tagging to the masses. That said and done I didn't really get on board with them until a few years ago when I outgrew my&amp;nbsp;bookmarking&amp;nbsp;needs. Trying to manage several thousand bookmarks&amp;nbsp;across&amp;nbsp;multiple browsers and multiple computers does that to you.&lt;br /&gt;
&lt;br /&gt;
But delicious has not delivered and has recently started to fall short, in part due to Yahoo firing the delicious team, and its subsequent purchase by &lt;a href="http://www.avos.com/delicious-press-release/" target="_blank"&gt;Youtube founders&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here's just a few problems I found:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Slow syncing of bookmarks in browser&lt;/li&gt;
&lt;li&gt;Having to sometimes log in every day&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Firefox addons would stop working after upgrading to certain version of Firefox&lt;/li&gt;
&lt;li&gt;The pain and waste of time trying to find a way to mark all my bookmarks private when bookmarking through a browser plugin. Why, delicious? Why?&lt;/li&gt;
&lt;li&gt;Inconsistent tag naming - You could use spaces in an older versions of the Firefox plugin, but only commas in newer versions. Because it wasn't made clear, myself and I'm sure plenty of others, had had to go through tons of delicious bookmarks and convert tags like "programming jsp reference useful" into the 4 separate tags they should have been in the first place. Not cool)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
And there were other &lt;a href="http://blog.earth2marsh.com/2012/01/dearest-delicious.html" target="_blank"&gt;unhappy campers&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style="font-weight: normal;"&gt;Hello Pinboard&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
As delicious was going down, I learned of other social bookmarking sites, &lt;a href="http://pinboard.in/"&gt;pinboard.in&lt;/a&gt; being one that caught my attention.&lt;br /&gt;
&lt;br /&gt;
Throughout the years, I had migrated over from IE Favorites to Firefox Bookmarks to delicious bookmarks. I had hand&amp;nbsp;curated my bookmarks and cleaned them up with link checkers to remove expired ones. It was time to move on to something better.&lt;br /&gt;
&lt;br /&gt;
So last night, I finally made the switch and created an account on pinboard.in. It's not free mind you&amp;nbsp;(&lt;i&gt;there is a one time fee of about $9&lt;/i&gt;), but from everything I read it's worth it &amp;nbsp;Not to mention &lt;a href="http://web.appstorm.net/general/interviews/interview-meet-maciej-ceglowski-of-pinboard-in/" target="_blank"&gt;the guy behind it&lt;/a&gt; seems like a great chap and has his stuff together.&lt;br /&gt;
&lt;br /&gt;
And from the first looks, I love it.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Importing almost 4500 bookmarks from both firefox and delicious was painless. Took a few minutes.&lt;/li&gt;
&lt;li&gt;Interface is great, simple, minimal and quick, exactly what I wanted&lt;/li&gt;
&lt;li&gt;Great default privacy settings give you the ability to 'add bookmarks as private by default'&lt;/li&gt;
&lt;li&gt;'enable public profile' is OFF by default&lt;/li&gt;
&lt;li&gt;and more&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
I did notice there was no &lt;i&gt;easy&lt;/i&gt; way to rename a tag in pinboard (&lt;a href="http://pinboard.in/faq#rename_tag" target="_blank"&gt;there is a way though&lt;/a&gt;), but I'm planning to play around with the Pinboard API soon and see what I can cook up.&lt;br /&gt;&lt;br /&gt;I'm sure pinboard is not perfect, but hey, it is the best I've found so far for my bookmarking needs.&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-5381207489493623322?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Jmg2dtOPYdXGiVm90TfXmj-CdBs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jmg2dtOPYdXGiVm90TfXmj-CdBs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Jmg2dtOPYdXGiVm90TfXmj-CdBs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jmg2dtOPYdXGiVm90TfXmj-CdBs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/bc9R1WKfFCg/goodbye-delicious-hello-pinboard.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.idleworx.com/2012/02/goodbye-delicious-hello-pinboard.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-6374180030512657660</guid><pubDate>Wed, 18 Jan 2012 03:31:00 +0000</pubDate><atom:updated>2012-01-17T19:36:11.383-08:00</atom:updated><title>A simple birthday reminder app</title><description>Are you looking for an easy breazy birthday reminder app to keep track of all your friends' birthdays that you seem to forget every year? Well, look no further.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The time has come for you to get your self organized and never forget another birthday again. Check out &lt;a href="http://beta.birthdayduck.com/"&gt;http://beta.birthdayduck.com&lt;/a&gt; a simple, clean and useful birthday reminder service from IdleWorx&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Here's a screenshot&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="http://1.bp.blogspot.com/-I5vOiB5Vt3c/TxY8GVwMC6I/AAAAAAAAADc/8LFyUDMPt-s/s1600/main.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-I5vOiB5Vt3c/TxY8GVwMC6I/AAAAAAAAADc/8LFyUDMPt-s/s320/main.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
It has the essential features you need in a birthday reminder application:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Reminders by email&lt;/li&gt;
&lt;li&gt;Reminders by SMS/text message&lt;/li&gt;
&lt;li&gt;A simple way to add names ands birthdays&lt;/li&gt;
&lt;li&gt;Import contacts from Facebook&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
No bells and whistles. birthdayduck.com aims to help you organize your life, by making it very easy to remember people's birthdays.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
It works like a birthday reminder calendar, except you won't need to worry about it all the time. The application will send you reminders by email and sms before someone's birthday.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We're currently in &lt;b&gt;beta&lt;/b&gt;, and getting ready to launch soon.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: #0b5394;"&gt;&lt;b&gt;If you sign up now at
&amp;nbsp;&lt;a href="http://beta.birthdayduck.com/"&gt;http://beta.birthdayduck.com&lt;/a&gt;&amp;nbsp;&amp;nbsp;and you are one of the first 50 sign-ups you'll receive a free lifetime account on birthdayduck.com once we launch.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: #0b5394;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: #0b5394;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: #0b5394;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-6374180030512657660?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FGqKdFDEdSvq9YPnSg1Q_9zSHss/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FGqKdFDEdSvq9YPnSg1Q_9zSHss/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FGqKdFDEdSvq9YPnSg1Q_9zSHss/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FGqKdFDEdSvq9YPnSg1Q_9zSHss/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/kDi4ta4YrfE/birthday-reminder-app.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-I5vOiB5Vt3c/TxY8GVwMC6I/AAAAAAAAADc/8LFyUDMPt-s/s72-c/main.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2012/01/birthday-reminder-app.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-3294680615175376737</guid><pubDate>Thu, 29 Dec 2011 00:35:00 +0000</pubDate><atom:updated>2011-12-28T16:35:15.736-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">videos</category><category domain="http://www.blogger.com/atom/ns#">interesting</category><title>How algorithms shape our world (video)</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/TDaFwnOiKVE/0.jpg"&gt;&lt;param name="movie" value="http://www.youtube.com/v/TDaFwnOiKVE&amp;fs=1&amp;source=uds" /&gt;
&lt;param name="bgcolor" value="#FFFFFF" /&gt;
&lt;embed width="320" height="266"  src="http://www.youtube.com/v/TDaFwnOiKVE&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;
Kevin Slavin argues that we're living in a world designed for -- and 
increasingly controlled by -- algorithms. In this riveting talk from 
TEDGlobal, he shows how these complex computer programs determine: 
espionage tactics, stock prices, movie scripts, and architecture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-3294680615175376737?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NnY1qAStI362nCCrtzBWlMlGWoY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NnY1qAStI362nCCrtzBWlMlGWoY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NnY1qAStI362nCCrtzBWlMlGWoY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NnY1qAStI362nCCrtzBWlMlGWoY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/LgQvmszTPWU/how-algorithms-shape-our-world-video.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/12/how-algorithms-shape-our-world-video.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-6114301729051161879</guid><pubDate>Wed, 21 Dec 2011 02:05:00 +0000</pubDate><atom:updated>2011-12-20T18:05:17.434-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">opinions</category><title>Your time is not worth that much</title><description>I noticed a lot of people in the startup/programming/HN community seem to measure their time in the equivalent of how much money they could be making during that time.&lt;br /&gt;
&lt;br /&gt;
For example, you ask a friend to do something for you that takes 2 hours, and they tell you that in those 2 hours they could be making
300$ because that's their hourly rate if they were doing freelance work. So essentially if they aren't paid for these 2 hours they are basically
loosing 300$.&lt;br /&gt;
&lt;br /&gt;
I say this way of estimating how much your time is worth is flawed.&lt;br /&gt;
&lt;br /&gt;
The only time this estimate is true is when you have a guy waiting at your door 24/7 for you to open it and give you work, and let you charge him 150$/hr for that work (per the example above).&lt;br /&gt;
&lt;br /&gt;
Given any other time, your time estimate is probably way off. Because if you don't have work available NOW at the rate you're estimating yourself to be worth, your time is just not worth as much as you think it is.
In fact, if you don't have any work lined up for that rate, your time is worth almost nothing. It's free time.&lt;br /&gt;
&lt;br /&gt;
Could you be making money during your free time? Yes, however if you are not ready at that very moment to take on the work at your going rate, your lost opportunity cost is not 150$/hr, but 0$.&lt;br /&gt;
&lt;br /&gt;
The other problem with correctly estimating what your time is worth is how easy it is easy to overestimate. I mean hey, in this next hour that I don't do anything I could be making a million dollars by winning the lottery. 
So my hourly rate is a million dollars. Just like the example above, that rate IS possible, but highly unprobable not to mention ridiculously unsustainable.&lt;br /&gt;
&lt;br /&gt;
To dig in further, the wiki informs us that:&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
"The notion of opportunity cost plays a crucial part in ensuring that scarce resources are used efficiently"&amp;nbsp;&lt;/blockquote&gt;
&lt;br /&gt;
And that's a good thing. If you're wasting your time on the couch picking your nose, you could be doing much better things with your time (Eg. creating something useful for others and getting paid for it too)&lt;br /&gt;
&lt;br /&gt;
Some people however have the tendency to put a dolar value on &lt;b&gt;EVERYTHING&lt;/b&gt; in their lives. And sadly it's a rather limited world view when everything has a dollar value and an opportunity cost.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
News Flash: Not everything in life has a dollar value&lt;/h3&gt;
&lt;br /&gt;
The wiki has a fairly straight forward example of this&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
"Opportunity costs are not always measured in monetary units or being able to produce one good over another. 
For instance, an individual could choose not to mow his or her lawn, in an attempt to create a prairie land for additional wild life. Neighbors of this individual may see this as unsightly, and want the lawn to be mowed. In this case, the opportunity cost of additional wild life is unhappy neighbors."
&lt;/blockquote&gt;
&lt;br /&gt;
We are not robots and life is not a well written ruby script (as some would like to believe).&lt;br /&gt;
&lt;br /&gt;
You can always look at everything in terms of the lost opportunity cost (and the dollar value associated with it), however, often the lost opportunity cost in dollars is far less valuable as an indicator of how much your time is really worth, and in some cases it can't even be used to accurately describe the lost opportunity cost, such as the opportunity cost of non-tangible things.&lt;br /&gt;
&lt;br /&gt;
For example, spending 2 hours playing with your kids or volunteering and genuinely helping out another human being, is &lt;b&gt;INFINITELY&lt;/b&gt; more important, beneficial and fulfilling than your lost opportunity cost of 300$ that you could be making doing freelance work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So to sum it up, while it's good to have a perspective about how much your time is worth, don't over do it.&lt;br /&gt;
&lt;br /&gt;
There are obvious cases when estimating your time makes perfect sense, but breaking down your entire waking time into lost opportunity costs is a bit too much in my opinion.&lt;br /&gt;
&lt;br /&gt;
Just like with most things in life, aim for moderation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-6114301729051161879?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Aj2Jd3mkkV3cUGpUsORNVRi3vjY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Aj2Jd3mkkV3cUGpUsORNVRi3vjY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Aj2Jd3mkkV3cUGpUsORNVRi3vjY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Aj2Jd3mkkV3cUGpUsORNVRi3vjY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/BJAkckZmd6Q/your-time-is-not-worth-that-much.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/12/your-time-is-not-worth-that-much.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-8223264219872265851</guid><pubDate>Sat, 01 Oct 2011 16:16:00 +0000</pubDate><atom:updated>2011-10-01T09:16:06.660-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">agile</category><category domain="http://www.blogger.com/atom/ns#">funny</category><title>Agile Hitler is not Happy</title><description>&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/l1wKO3rID9g" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-8223264219872265851?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0Biy9RHLdZASSzzv8H9Ekai0rBA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0Biy9RHLdZASSzzv8H9Ekai0rBA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0Biy9RHLdZASSzzv8H9Ekai0rBA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0Biy9RHLdZASSzzv8H9Ekai0rBA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/uu3gUTYOoAA/agile-hitler-is-not-happy.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/l1wKO3rID9g/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/10/agile-hitler-is-not-happy.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-2854899576369654261</guid><pubDate>Sat, 24 Sep 2011 01:01:00 +0000</pubDate><atom:updated>2011-09-23T18:01:20.277-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">dao</category><title>MyBatis DAO Example Code Tutorial</title><description>&lt;p&gt;This tutorial will show how how to integrate MyBatis with the Data Access Object pattern (DAO) and MySQL for use in Java Web Apps.&lt;/p&gt;

&lt;p&gt;In case you're not familiar, MyBatis is the new version of the iBatis Data Mapper Java Framework, which allows you to use a relational database with object-oriented applications.&lt;/p&gt;

&lt;p&gt;If you're not familiar with the DAO pattern or the benefits of using it read more about it here &lt;a href="http://www.ibm.com/developerworks/java/library/j-genericdao.html" target="_blank"&gt;Generic implementation of the DAO pattern&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Full code of this mybatis dao example tutorial is available on &lt;a href="https://github.com/idleworx/MyBatisDAOHelper" target="_blank"&gt;github here&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;Step 1 - Define the interface&lt;/h2&gt;
&lt;p&gt;
Create an IParentDAO interface to define the main method calls for all objects. This interface can be used as the parent for various DAO implementations. Here are the default CRUD methods that all objects will have
&lt;/p&gt;

&lt;pre&gt;
get(id)
getByName(name)
getAll()
create(obj)
update(object)
delete(id)
&lt;/pre&gt;

&lt;p&gt;Create the IParentDAO.java class &lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

public interface IParentDAO&amp;lt;T, PK&amp;gt;{
 public T get(PK id) throws PersistenceException;//get obj of type T by the primary key 'id' 
 public T getByName(String name) throws PersistenceException;//get obj of type T by the 'name' field, if one exists for that table
 public ArrayList&amp;lt;T&amp;gt; getAll() throws PersistenceException;//get all objects of type T
 public int create(T objInstance) throws PersistenceException;//insert an object of type T into the database
 int update(T transientObject) throws PersistenceException; //update an object of type T    
 int delete(PK id)  throws PersistenceException;//delete an object of type T
}

&lt;/pre&gt;


&lt;h2&gt;Step 2 - Create the base class&lt;/h2&gt;

&lt;p&gt;Create the MyBatisDAO abstract base class. This will be the default MyBatis implementation of the DAO. You can of course write a different one for JDBC, Spring etc. &lt;i&gt;Feel free to remove the logging code if you don't need it. I used &lt;a href="http://logback.qos.ch/" target="_blank"&gt;Logback&lt;/a&gt; for that.&lt;/i&gt;&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

import java.util.ArrayList;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** 
 *  Class contains all the basic CRUD related methods which are inherited by all objects
 *  Children daos should generally not overwrite these method but add extra ones as needed.  
 */
public abstract class MyBatisDAO&amp;lt;T, PK&amp;gt; implements IParentDAO&amp;lt;T, PK&amp;gt;{
 
 private static Logger log = LoggerFactory.getLogger(MyBatisDAO.class);
 private static final String NAMESPACE = &amp;quot;mappers&amp;quot;; 
 
 private SqlSessionFactory sf; //reference to mybatis session factory 
 private Class&amp;lt;T&amp;gt; type;
  
 /** 
  * Define prefixes for easier naming convetions between XML mapper files and the DAO class 
  **/ 
 public static final String PREFIX_SELECT_QUERY = &amp;quot;get&amp;quot;;     //prefix of select queries in mapper files (eg. getAddressType) 
 public static final String PREFIX_INSERT_QUERY = &amp;quot;create&amp;quot;; //prefix of create queries in mapper files (eg. createAddressType)
 public static final String PREFIX_UPDATE_QUERY = &amp;quot;update&amp;quot;;  //prefix of update queries in mapper files (eg. updateAddressType)
 public static final String PREFIX_DELETE_QUERY = &amp;quot;delete&amp;quot;;  //prefix of delete queries in mapper files (eg. deleteAddressType)
 
 /** Default Constructor */
    public MyBatisDAO(Class&amp;lt;T&amp;gt; type,SqlSessionFactory sf) {
        this.type = type;
        this.sf = sf;
        if(sf==null)
   log.error(&amp;quot;Error: Could not instantiate MyBatisDAO. Loading myBatis sessionFactory failed.&amp;quot;);  
    }
    
    /** Use this method to get a session factory for using in any methods impelmented in child dao classes */
    protected SqlSessionFactory getSessionFactory() {
  return sf;
 }

    /** 
     *  Default get by id method. 
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt; 
     *  Almost all objects in the db will 
     *  need this (except mapping tables for multiple joins, which you 
     *  probably shouldn't even have as objects in your model, since proper 
     *  MyBatis mappings can take care of that).
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;
     *  Example: 
     *  &amp;lt;/br&amp;gt;
     *  If your DAO object is called CarInfo.java, 
     *  the corresponding mapper query id should be: &amp;amp;lt;select id=&amp;quot;getCarInfo&amp;quot; ...  
     */
    public T get(PK id) throws PersistenceException {
        
     SqlSession session = sf.openSession(); 
     T obj = null;
  try
  {  
   String query = NAMESPACE+&amp;quot;.&amp;quot;+PREFIX_SELECT_QUERY+this.type.getSimpleName();  //If the object's calls name is AddressType.java, this matches the mapper query id: &amp;quot;namespace.getAddressType&amp;quot;
   obj = (T)session.selectOne(query,id);      
  }
  finally
  {
   session.close();
  }
  return obj;
    }
    
    /** 
     *  Method returns all rows for this object.
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  Example:
     *  &amp;lt;/br&amp;gt;  
     *  If your DAO object is called CarInfo.java, 
     *  the corresponding mapper query id should be: &amp;amp;lt;select id=&amp;quot;getAllCarInfo&amp;quot; ...  
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  SQL Executed: select * from [tablename]
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  Notes:
     *  &amp;lt;/br&amp;gt;   
     *  Consider overdiding this method in order to handle large numbers of objects 
     *  with multiple references.  
     *  LAZY LOADING should be enabled in this case, otherwise you might run out of memory (eg. get all UserAccounts if the table has 1,000,000 rows)
     *  look into the aggresiveLazyLoading property 
     *  */
    public ArrayList&amp;lt;T&amp;gt; getAll() throws PersistenceException {
        
     SqlSession session = sf.openSession(); 
     ArrayList&amp;lt;T&amp;gt; list = null;
  try
  {     
   String query = NAMESPACE+&amp;quot;.&amp;quot;+PREFIX_SELECT_QUERY+&amp;quot;All&amp;quot;+this.type.getSimpleName();
   list = (ArrayList&amp;lt;T&amp;gt;)session.selectList(query); 
  }
  finally
  {
   session.close();
  }   
  return list;
    }
    
    /** 
     *  Method returns first object which matches the given name (exact match).
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  It's up to you to decide what constitutes an object's name. Typically you would have a 
     *  NAME column in the table, but not all objects have this. Generally this method should be overriden (if you need it at all)
     *  in the child dao class.
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;
     *  Example:
     *  &amp;lt;/br&amp;gt;  
     *  If your DAO object is called CarInfo.java, 
     *  the corresponding mapper query id should be: &amp;amp;lt;select id=&amp;quot;getCarInfoByName&amp;quot; ...  
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  SQL Executed (example): select * from [tablename] where NAME = ? 
     *  
     */
    public T getByName(String name) throws PersistenceException {
        
     SqlSession session = sf.openSession();
     T obj = null;
  try
  { 
   String query = NAMESPACE+&amp;quot;.&amp;quot;+PREFIX_SELECT_QUERY+this.type.getSimpleName()+&amp;quot;ByName&amp;quot;;
   obj = (T)session.selectOne(query,name);   
  }
  finally
  {
   session.close();
  }
  return obj;
    }
    
    
    /** 
     *  Method inserts the object into the table.
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;
     *  You will usually override this method, especially if you're inserting associated objects.
     *  &amp;lt;/br&amp;gt; 
     *  Example:
     *  &amp;lt;/br&amp;gt;  
     *  If your DAO object is called CarInfo.java, 
     *  the corresponding mapper query id should be: &amp;amp;lt;insert id=&amp;quot;createCarInfo&amp;quot; ...  
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  SQL Executed (example): insert into [tablename] (fieldname1,fieldname2,...) values(value1,value2...) ... 
     *  
     */
    public int create(T o) throws PersistenceException{        
     SqlSession session = sf.openSession();
     Integer status = null;
     try
  {   
      String query = NAMESPACE+&amp;quot;.&amp;quot;+PREFIX_INSERT_QUERY+o.getClass().getSimpleName();
   status = (Integer)session.insert(query,o);
   session.commit();   
  }
  finally
  {
   session.close();
  }  
  return status;
    }
    
    
    /** 
     *  Method updates the object by id.
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;
     *  You will usually override this method. But it can be used for simple objects.
     *  &amp;lt;/br&amp;gt; 
     *  Example:
     *  &amp;lt;/br&amp;gt;  
     *  If your DAO object is called CarInfo.java, 
     *  the corresponding mapper query id should be: &amp;amp;lt;update id=&amp;quot;updateCarInfo&amp;quot; ...  
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  SQL Executed (example): update [tablename] set fieldname1 = value1 where id = #{id} 
     *  
     */
    public int update(T o)throws PersistenceException {
        
     SqlSession session = sf.openSession();
  Integer status = null;
     try
  {   
   String query = NAMESPACE+&amp;quot;.&amp;quot;+PREFIX_UPDATE_QUERY+o.getClass().getSimpleName();
      status = session.update(query,o);
   session.commit();
   
  }
  finally
  {
   session.close();
  } 
  return status;
     
    }

    
    /** 
     *  Method deletes the object by id.
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;
     *  Example:
     *  &amp;lt;/br&amp;gt;  
     *  If your DAO object is called CarInfo.java, 
     *  the corresponding mapper query id should be: &amp;amp;lt;delete id=&amp;quot;deleteCarInfo&amp;quot; ...  
     *  &amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;  
     *  SQL Executed (example): update [tablename] set fieldname1 = value1 where id = #{id} 
     *  
     */
    public int delete(PK id)  throws PersistenceException{
  SqlSession session = sf.openSession();
  Integer status = null;
  try
  {   
   String query = NAMESPACE+&amp;quot;.&amp;quot;+PREFIX_DELETE_QUERY+this.type.getSimpleName();
   status = session.delete(query,id);
   session.commit();
  } 
  finally
  {
   session.close();
  } 
  return status;
  
    }
}

&lt;/pre&gt;

&lt;h3&gt;Naming Convetions&lt;/h3&gt;

&lt;p&gt;You'll notice there are four prefix constants defined in the class above.&lt;/p&gt;

&lt;p&gt;The reason for this is to keep consistency between the sql query ids you will define in the mybatis mapper.xml files (see Step 4) and the method names defined in the MyBatisDAO class we're implementing.&lt;/p&gt;

&lt;p&gt;This won't work exactly like ActiveRecord or similar frameworks where there is a pluralization engine but it will still simplify things a lot. &lt;/p&gt;

&lt;p&gt;For example, if you have an object called Status for which you will create a DAO, you will have to define the following mybatis querries&lt;/p&gt;

&lt;style&gt;
#tableNamingConvetions{
        text-align: left;
 border-spacing: 0px;
 border: 1px solid #aeb3b6;
 border-collapse: collapse;
        width:90%;        
}
#tableNamingConvetions td,th{
   font-size:12px;
}

&lt;/style&gt;

&lt;table id="tableNamingConvetions" border="1"&gt;
&lt;tr&gt;
  &lt;th&gt;Java Method&lt;/th&gt;
  &lt;th&gt;MyBatis Query Id&lt;/th&gt;
  &lt;th&gt;Convention&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;dao.get(1)&lt;/td&gt;
  &lt;td&gt;&amp;lt;select id="getStatus" ...&lt;/td&gt;
  &lt;td&gt;get&lt;b&gt;ClassName&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;dao.getAll()&lt;/td&gt;
  &lt;td&gt;&amp;lt;select id="getAllStatus" ...&lt;/td&gt;
  &lt;td&gt;getAll&lt;b&gt;ClassName&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;dao.getByName(String name)&lt;/td&gt;
  &lt;td&gt;&amp;lt;select id="getStatusByName" ...&lt;/td&gt;
  &lt;td&gt;get&lt;b&gt;ClassName&lt;/b&gt;ByName&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;dao.create(obj)&lt;/td&gt;
  &lt;td&gt;&amp;lt;insert id="createStatus" ...&lt;/td&gt;
  &lt;td&gt;create&lt;b&gt;ClassName&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;dao.update(obj)&lt;/td&gt;
  &lt;td&gt;&amp;lt;update id="updateStatus" ...&lt;/td&gt;
  &lt;td&gt;update&lt;b&gt;ClassName&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;dao.delete(id)&lt;/td&gt;
  &lt;td&gt;&amp;lt;delete id="deleteStatus" ...&lt;/td&gt;
  &lt;td&gt;delete&lt;b&gt;ClassName&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;Don't worry, this will make a lot more sense once you get to &lt;b&gt;Step 4&lt;/b&gt;&lt;/p&gt;

&lt;h2&gt;Step 3 - Write the actual DAO classes&lt;/h2&gt;

&lt;p&gt;Now you need to implement your concrete DAO classes.&lt;/p&gt;

&lt;p&gt;Let's say you have a simple object called Status which maps to a simple table, and has 2 attributes, an ID and a NAME. Think of it as an object you could use to represent the status of a task. &lt;i&gt;I chose this to illustrate a very basic example here&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;The table for this object would look like this&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
  &lt;th&gt;ID&lt;/th&gt;
  &lt;th&gt;NAME&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;1&lt;/td&gt;
  &lt;td&gt;Done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;2&lt;/td&gt;
  &lt;td&gt;In Progress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;3&lt;/td&gt;
  &lt;td&gt;Not Started&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;And the java class (or DTO object) would look like this (Status.java)&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

public class Status 
{
 private int id;
 private String name;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 @Override
 public String toString() {  
  return "[Status] " + "(" + id + ") " + name;
 }
}

&lt;/pre&gt;

&lt;p&gt;Writing the DAO class for the Status object now becomes trivial since you're inheriting all the default CRUD methods from MyBatisDAO.java defined above.&lt;/p&gt; 

&lt;p&gt;Here's how the &lt;b&gt;StatusDAO.java&lt;/b&gt; should look:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

import org.apache.ibatis.session.SqlSessionFactory;

import com.idleworx.mybatisdao.MyBatisDAO;
import com.idleworx.mybatisdao.tests.objects.Status;

public class StatusDAO extends MyBatisDAO&amp;lt;Status,Integer&amp;gt;{
 
 //Don't forget to define the default custom constructor when implementing a new 
 //child DAO class, and set the class type accordingly 
 public StatusDAO(Class&amp;lt;Status&amp;gt; type,SqlSessionFactory containerSessionFactory) {
  super(type,containerSessionFactory);
 }
 
}

&lt;/pre&gt;

&lt;p&gt;You'll notice here that all you need to do is call the constructor from the parent MyBatisDAO.java class. Now all the default CRUD methods are available for the StatusDAO.java class.&lt;/p&gt;

&lt;p&gt;You are free of course to add any additional methods as needed here that go beyond the CRUD methods that were defined. For example something like&lt;br&gt;&lt;br&gt;&lt;b&gt; getStatusForBlog(Integer blogId)&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://github.com/idleworx/MyBatisDAOHelper" target="_blank"&gt;full code example&lt;/a&gt;. &lt;br&gt;&lt;i&gt;Both the MyBatisDAO.java and IParentDAO.java classes are included.&lt;/i&gt;&lt;/p&gt; 

&lt;p&gt;Of course you will still have to define the MyBatis mapper SQL statements for the default CRUD methods defined in MyBatisDAO.java, as well as additional SQLs for other DAO methods you choose to implement. Which brings us to the next step ... &lt;/p&gt;

&lt;h2&gt;Step 4 - Defining the mybatis mapper&lt;/h2&gt;

&lt;p&gt;The last major step in the puzzle, is writing the actual SQL that will implement all the default CRUD methods and any other methods you've implemented for the Status object.&lt;/p&gt;

&lt;p&gt;Your code may differ of course, but note the use of the &lt;b&gt;naming conventions&lt;/b&gt; for naming the sql statements which I talked about earlier. &lt;/p&gt;

&lt;p&gt;That is the key to this whole thing, and it will make your life a lot easier when writing other DAOs which extend the MyBatisDAO class.&lt;/p&gt;

&lt;p&gt;Here is an example of how the mapper file for the StatusDAO object would look like. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;StatusMapper.xml&lt;/b&gt;&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;
&amp;lt;!DOCTYPE mapper PUBLIC &amp;quot;-//mybatis.org//DTD Mapper 3.0//EN&amp;quot; &amp;quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;quot;&amp;gt;

&amp;lt;mapper namespace=&amp;quot;mappers&amp;quot;&amp;gt;
 
 &amp;lt;select id=&amp;quot;getStatus&amp;quot; parameterType=&amp;quot;int&amp;quot; resultType=&amp;quot;Status&amp;quot;&amp;gt;
  select 
   status_id as &amp;quot;id&amp;quot;,
   status_name as &amp;quot;name&amp;quot;
  from daohelper.status where status_id = #{id}
 &amp;lt;/select&amp;gt;
 
 &amp;lt;select id=&amp;quot;getAllStatus&amp;quot; parameterType=&amp;quot;int&amp;quot; resultType=&amp;quot;Status&amp;quot;&amp;gt;
  select 
   status_id as &amp;quot;id&amp;quot;,
   status_name as &amp;quot;name&amp;quot;
  from daohelper.status order by status_id
 &amp;lt;/select&amp;gt;
 
 &amp;lt;select id=&amp;quot;getStatusByName&amp;quot; parameterType=&amp;quot;int&amp;quot; resultType=&amp;quot;Status&amp;quot;&amp;gt;
  select 
   status_id as &amp;quot;id&amp;quot;,
   status_name as &amp;quot;name&amp;quot;
  from daohelper.status where status_name = #{name}
 &amp;lt;/select&amp;gt;
 
 &amp;lt;insert id=&amp;quot;createStatus&amp;quot; keyColumn=&amp;quot;status_id&amp;quot; useGeneratedKeys=&amp;quot;true&amp;quot; parameterType=&amp;quot;Status&amp;quot;&amp;gt;
  insert into daohelper.status (status_name)
  values (#{name})  
 &amp;lt;/insert&amp;gt;
 
 &amp;lt;update id=&amp;quot;updateStatus&amp;quot; parameterType=&amp;quot;Status&amp;quot;&amp;gt;
  update daohelper.status set status_name = #{name} where status_id = #{id}  
 &amp;lt;/update&amp;gt;
 
 &amp;lt;delete id=&amp;quot;deleteStatus&amp;quot; parameterType=&amp;quot;int&amp;quot;&amp;gt;
  delete from daohelper.status where status_id = #{id}  
 &amp;lt;/delete&amp;gt; 
 
&amp;lt;/mapper&amp;gt;

&lt;/pre&gt;

&lt;p&gt;Note here the use of the &lt;b&gt;mapper&lt;/b&gt; namespace which is the same as referenced by the MyBatisDAO abstract class. &lt;/p&gt;

&lt;p&gt;It's used for convenience in this case, and generally you should be able to use multiple mapper files with the same namespace as long as the you don't have multiple queries with the same id across several xml mapper files (which would be a bad idea anyway)&lt;/p&gt;

&lt;h2&gt;Errors&lt;/h2&gt;

&lt;p&gt;Just a side note on some errors you may encounter.&lt;/p&gt;

&lt;p&gt;If you call one of the default CRUD methods but don't define the appropriate query in the mapper.xml file, you will get an error like this:&lt;/p&gt;

&lt;pre&gt;
org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for mappers.getAllFrog
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for mappers.getAllFrog
&lt;/pre&gt;


&lt;h2&gt;Wrapping it up&lt;/h2&gt;

&lt;p&gt;By this point I hope you've managed to build yourself a small but working DAO implementation based on the MyBatisDAO abstract class. &lt;p&gt;

&lt;p&gt;You can download the &lt;a href="https://github.com/idleworx/MyBatisDAOHelper" target="_blank"&gt;full code example&lt;/a&gt; for more a better overview. &lt;/p&gt;

&lt;p&gt;It also contains a jUnit example, the mybatis configuration file (mybatis.config.xml) as well as the simple DDL statments for setting up the MySQL table.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt;If you need to use this from a Servlet or Spring controller, see my other blog post about &lt;a href="http://blog.idleworx.com/2010/06/initialize-mybatis-servletcontextlisten.html" target="_blank"&gt;defining a servletcontextlistener&lt;/a&gt;

&lt;h3&gt;Hope you found this useful. Improvements or suggestions are welcome.&lt;/h3&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-2854899576369654261?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zLqp3_00X-KySmTxdpYnUersHvY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zLqp3_00X-KySmTxdpYnUersHvY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zLqp3_00X-KySmTxdpYnUersHvY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zLqp3_00X-KySmTxdpYnUersHvY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/QlQiOd14LRU/mybatis-dao-example-code-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/09/mybatis-dao-example-code-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-965972119421870947</guid><pubDate>Wed, 29 Jun 2011 00:59:00 +0000</pubDate><atom:updated>2011-06-28T17:59:50.591-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><title>Creating a simple android app with 2 buttons</title><description>&lt;p&gt;How do I build a very simple android app you ask? 
It's easy, building a basic android application is not that hard. 
Making something really useful, cool and bug free, now that takes a good developer.&lt;/p&gt;

&lt;p&gt;
This is a brief tutorial will show you how to code a very basic two button android application (with a start button and a stop button). &lt;/p&gt;
&lt;p&gt;
You can use this code as an android project template or starting point for simple projects. 
&lt;/p&gt;

&lt;h3&gt;Two Button Application Use Case&lt;/h3&gt;

&lt;p&gt;A simple two button application, can be your starting point for various android projects. It can be useful for example when you have an application that starts and stops a service from the click of a button &lt;a href="#"&gt;Watch for tutorial on this soon. &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt;This tutorial assumes you have completed the &lt;a href="http://developer.android.com/resources/tutorials/hello-world.html" target="_blank"&gt;HelloWorld Tutorial&lt;/a&gt; in the Android docs and you are a little familiar with Eclipse and ADT. The tutorial is aimed at developers who are very new to Android.&lt;/p&gt;

&lt;h3&gt;Creating a two button app&lt;/h3&gt;

&lt;h4&gt;1) Create the project &lt;/h4&gt;

&lt;p&gt;In Eclipse create a new Android project and define the properties as shown below. Feel free to use your own package names.&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-93u87AJdFjc/Tgp00B7q__I/AAAAAAAAADA/XfLJnv12c-c/s1600/01_create_project.png" imageanchor="1" style=""&gt;&lt;img border="0" height="400" width="263" src="http://3.bp.blogspot.com/-93u87AJdFjc/Tgp00B7q__I/AAAAAAAAADA/XfLJnv12c-c/s400/01_create_project.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h4&gt;2) Create a simple layout&lt;/h4&gt;

&lt;p&gt;For our main activity we're going to define a very basic layout consisting of one TextView and two Buttons (a start button and a stop button).&lt;/p&gt;

&lt;p&gt;Modify your &lt;b&gt;project/res/layout/main.xml&lt;/b&gt; file to this:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;LinearLayout xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;
    android:orientation=&amp;quot;vertical&amp;quot;
    android:layout_width=&amp;quot;fill_parent&amp;quot;
    android:layout_height=&amp;quot;fill_parent&amp;quot;
    &amp;gt;
&amp;lt;TextView  
    android:layout_width=&amp;quot;fill_parent&amp;quot; 
    android:layout_height=&amp;quot;wrap_content&amp;quot; 
    android:text=&amp;quot;This is a simple two button app. \r\n \r\n Tell your user what your app does here \r\n \r\n \r\n \r\n&amp;quot;
    android:padding=&amp;quot;10dp&amp;quot;
    android:textColor=&amp;quot;#FFFFFF&amp;quot;
    /&amp;gt;
&amp;lt;Button
 android:id=&amp;quot;@+id/buttonStart&amp;quot;
 android:layout_width=&amp;quot;fill_parent&amp;quot;
 android:layout_height=&amp;quot;wrap_content&amp;quot;
 android:text=&amp;quot;Start&amp;quot;/&amp;gt;
&amp;lt;Button
 android:id=&amp;quot;@+id/buttonStop&amp;quot;
 android:layout_width=&amp;quot;fill_parent&amp;quot;
 android:layout_height=&amp;quot;wrap_content&amp;quot;
 android:text=&amp;quot;Stop&amp;quot;/&amp;gt;
&amp;lt;/LinearLayout&amp;gt;

&lt;/pre&gt;

&lt;p&gt;If you run your project in the emulator it should look like this&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-VNxpujxNgkg/Tgp2AD_-ruI/AAAAAAAAADI/Q4ZD88AzCuY/s1600/02_first_peek.png" imageanchor="1" style=""&gt;&lt;img border="0" height="400" width="240" src="http://3.bp.blogspot.com/-VNxpujxNgkg/Tgp2AD_-ruI/AAAAAAAAADI/Q4ZD88AzCuY/s400/02_first_peek.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h4&gt;3) Adding onClickListeners to the buttons&lt;/h4&gt;

&lt;p&gt;In order for the buttons to actually do something useful, and to provide a template for where you can put future functionality, we'll need to define onClickListeners for each button.&lt;/p&gt;

&lt;p&gt;Let's update the TwoButtonApp.java main activiy with the following code:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.idleworx.android.twobuttonapp;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class TwoButtonApp extends Activity {
    
 private static String logtag = "TwoButtonApp";//for use as the tag when logging 
  
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button buttonStart = (Button)findViewById(R.id.buttonStart);        
     buttonStart.setOnClickListener(startListener); // Register the onClick listener with the implementation above
      
     Button buttonStop = (Button)findViewById(R.id.buttonStop);        
     buttonStop.setOnClickListener(stopListener); // Register the onClick listener with the implementation above
    }
    
    //Create an anonymous implementation of OnClickListener
    private OnClickListener startListener = new OnClickListener() {
        public void onClick(View v) {
          Log.d(logtag,"onClick() called - start button");              
          Toast.makeText(TwoButtonApp.this, "The Start button was clicked.", Toast.LENGTH_LONG).show();
          Log.d(logtag,"onClick() ended - start button");
        }
    };
    
    // Create an anonymous implementation of OnClickListener
    private OnClickListener stopListener = new OnClickListener() {
        public void onClick(View v) {
         Log.d(logtag,"onClick() called - stop button"); 
         Toast.makeText(TwoButtonApp.this, "The Stop button was clicked.", Toast.LENGTH_LONG).show();
          Log.d(logtag,"onClick() ended - stop button");
        } 
    };
    
    
    @Override
 protected void onStart() {//activity is started and visible to the user
  Log.d(logtag,"onStart() called");
  super.onStart();  
 }
 @Override
 protected void onResume() {//activity was resumed and is visible again
  Log.d(logtag,"onResume() called");
  super.onResume();
  
 }
 @Override
 protected void onPause() { //device goes to sleep or another activity appears
  Log.d(logtag,"onPause() called");//another activity is currently running (or user has pressed Home)
  super.onPause();
  
 }
 @Override
 protected void onStop() { //the activity is not visible anymore
  Log.d(logtag,"onStop() called");
  super.onStop();
  
 }
 @Override
 protected void onDestroy() {//android has killed this activity
   Log.d(logtag,"onDestroy() called");
   super.onDestroy();
 }
}

&lt;/pre&gt;



&lt;h2&gt;Notes&lt;/h2&gt; 

&lt;ul&gt;
&lt;li&gt;As you can see, each button (or any resource for that matter) can be retrieved by the id was associated with in the layout:
&lt;pre&gt;
@+id/buttonStart 

can be retreived with:

Button buttonStart = (Button)findViewById(R.id.buttonStart);  
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;We have attached two anonymous OnClickListeners() to each of our two buttons&lt;/li&gt;

&lt;li&gt;Each listener displays a simple Toast (a brief message to the user).&lt;/li&gt;

&lt;li&gt;Logging is very important especially during debugging, so make sure you use it where ever you need&lt;/li&gt;

&lt;li&gt;Not the &lt;b&gt;logtag&lt;/b&gt; variable defined in the very top. It's a quick shortcut to save time when logging statements in your app with the Log.X methods. I usually use the same name as the class name and use the Create Filter option in the LogCat view to filter my code out.&lt;/li&gt;

&lt;li&gt;For easier debugging I've added logging of all the other lifecycle methods in the Activity. When you do debugging of your apps it's very important to understand the &lt;a href="http://developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle" target="_blank"&gt;lifecycle of an android app&lt;/a&gt;, and even more important to see how it's called in relation to your code.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;So this is it, Introduction to Android 101. You should now have a very basic android app running. &lt;/p&gt;

&lt;p&gt;&lt;i&gt;For reference here is how your &lt;b&gt;AndroidManifest.xml&lt;/b&gt; file should look (you should not have had to modify this file so far if you have followed this tutorial):
&lt;/i&gt;&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;manifest xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;
      package=&amp;quot;com.idleworx.android.twobuttonapp&amp;quot;
      android:versionCode=&amp;quot;1&amp;quot;
      android:versionName=&amp;quot;1.0&amp;quot;&amp;gt;
    &amp;lt;uses-sdk android:minSdkVersion=&amp;quot;8&amp;quot; /&amp;gt;

    &amp;lt;application android:icon=&amp;quot;@drawable/icon&amp;quot; android:label=&amp;quot;@string/app_name&amp;quot;&amp;gt;
        &amp;lt;activity android:name=&amp;quot;.TwoButtonApp&amp;quot;
                  android:label=&amp;quot;@string/app_name&amp;quot;&amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name=&amp;quot;android.intent.action.MAIN&amp;quot; /&amp;gt;
                &amp;lt;category android:name=&amp;quot;android.intent.category.LAUNCHER&amp;quot; /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;
        &amp;lt;/activity&amp;gt;

    &amp;lt;/application&amp;gt;
&amp;lt;/manifest&amp;gt;

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-965972119421870947?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dyOXh1epPvJ7csxjpARvX5B4qn4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dyOXh1epPvJ7csxjpARvX5B4qn4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dyOXh1epPvJ7csxjpARvX5B4qn4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dyOXh1epPvJ7csxjpARvX5B4qn4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/O8li1NvuJjU/build-simple-android-app-2-button.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-93u87AJdFjc/Tgp00B7q__I/AAAAAAAAADA/XfLJnv12c-c/s72-c/01_create_project.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/06/build-simple-android-app-2-button.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-6058755465738657137</guid><pubDate>Mon, 20 Jun 2011 02:55:00 +0000</pubDate><atom:updated>2011-06-19T19:55:23.372-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><title>First Android App Goes Live</title><description>&lt;p&gt;I've taken an interest in Android App Development a few months ago, and tonight I decided to launch the first android app I created. &lt;/p&gt;

&lt;p&gt;It's a very simple taxi finder app targeted for people in Bucharest, Romania.&lt;/p&gt;
&lt;p&gt;
If you ever find yourself in Bucharest, Romania and you need a taxi, and you happen to have an android phone, make sure to install this app. It may just be what you need. From the Android market you can search for "vreau taxi" or check out the link below:&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://market.android.com/details?id=com.idleworx.vreautaxi&amp;feature=search_result" target="_blank"&gt;VreauTaxi&lt;/a&gt; 
&lt;/p&gt;

&lt;p&gt;The goal of this was to learn the whole process of android app development from top to bottom and I think it went rather well despite a few painful hours dealing with Windows 7 Android USB device installation issues. &lt;/p&gt;

&lt;p&gt;I will write more about Android soon, as some new blog post ideas have been rolling through my head.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-6058755465738657137?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JL1FEWW8jFopeJHBMieV1P1hbeo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JL1FEWW8jFopeJHBMieV1P1hbeo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JL1FEWW8jFopeJHBMieV1P1hbeo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JL1FEWW8jFopeJHBMieV1P1hbeo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/f-M4GCJdW88/bucharest-romania-taxi-app-android.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/06/bucharest-romania-taxi-app-android.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-7294767691331236424</guid><pubDate>Wed, 30 Mar 2011 20:33:00 +0000</pubDate><atom:updated>2011-03-30T13:34:44.728-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ruby</category><title>RubyNation 2011</title><description>Going to the RubyNation conference this weekend. Cool stuff.

&lt;a href="http://www.rubynation.org/" target="_blank"&gt;
  &lt;img src="http://www.rubynation.org/images/conference/badges/2011/webBadgesConference.png"/&gt;
&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-7294767691331236424?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/q0gyW8Zu4MzwbwtgJuZ0X4C184M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q0gyW8Zu4MzwbwtgJuZ0X4C184M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/q0gyW8Zu4MzwbwtgJuZ0X4C184M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q0gyW8Zu4MzwbwtgJuZ0X4C184M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/-cGx7H3CmYc/rubynation-2011.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/03/rubynation-2011.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-5814408525884501393</guid><pubDate>Fri, 04 Feb 2011 03:35:00 +0000</pubDate><atom:updated>2011-02-03T16:38:30.483-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">web applications</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>The IdleWorx Monster MyBatis Tutorial</title><description>&lt;h2&gt;Building an entire Java web application with MyBatis 3, Tomcat, MySQL and Eclipse (on Windows 7)&lt;/h2&gt;

&lt;p&gt;This is a multi part tutorial which will show you how to build a Servlet/JSP based web application from scratch, using MySQL, Tomcat and MyBatis (the new version of the iBatis framework) on a windows platform using Eclipse.&lt;/p&gt;

&lt;h3&gt;You will make the most of this tutorial if&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You have built at least a few small webapplications in the past.&lt;/li&gt;
&lt;li&gt;You know how to setup Tomcat 5.x or higher version&lt;/li&gt;
&lt;li&gt;You are somewhat familiar with the Eclipse IDE&lt;/li&gt;
&lt;li&gt;You are familiar with SQL. &lt;/li&gt;
&lt;li&gt;You know how to set-up MySQL on your development box and integrate it with your java web application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Let's get started&lt;/h3&gt;

&lt;p&gt;To see how Tomcat, MyBatis and MySQL work together we're going to create a tiny java web application in Eclipse, called &lt;b&gt;ModelingAgency&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;If you don't want to follow the whole tutorial, you can skip through to the different sections below and pick out the information you need, otherwise continue to &lt;a href="http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 1 - The Setup&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Table of Contents&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 1: The Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 2: The ModelingAgency Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 3: Creating the ModelingAgency project in Eclipse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part4-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 4: Creating a Test Servlet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part5-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 5: Setting up Logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part6-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 6: The Java POJO model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part7-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 7: Configuring MyBatis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part8-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 8: Testing MyBatis with jUnit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part9-idleworx-monster-mybatis-tutorial.html" target="_blank"&gt;Part 9: Creating the DAO Layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part10-idleworx-monster-mybatis.html" target="_blank"&gt;Part 10: Initializing MyBatis on Application Startup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.idleworx.com/2011/02/part11-idleworx-monster-mybatis.html" target="_blank"&gt;Part 11: Finalizing the Interface&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;At the end of this tutorial you will hopefully be able to create a basic Java JSP/Servlet based webapp with MyBatis, MySQL and Tomcat in an Eclipse environment.&lt;/p&gt;

&lt;p&gt;You can download a full version of finished ModelingAgency webapp &lt;a href="https://sites.google.com/site/idleworxblog/modelingagency.war?attredirects=0&amp;d=1" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;&lt;p&gt;This tutorial took me a long time to write, so if you found it useful in any way, if you found errors with it or you think something is missing, please let me know and I will do my best to improve it.&lt;/p&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-5814408525884501393?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/87qs_0xVRagj7INEgceENVPC_wQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/87qs_0xVRagj7INEgceENVPC_wQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/87qs_0xVRagj7INEgceENVPC_wQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/87qs_0xVRagj7INEgceENVPC_wQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/YcVI3wFqwQE/mybatis-3-tomcat-mysql-eclipse.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>4</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/mybatis-3-tomcat-mysql-eclipse.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-3499171989800946325</guid><pubDate>Fri, 04 Feb 2011 00:32:00 +0000</pubDate><atom:updated>2011-02-03T16:51:17.797-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 11: Finalizing the Interface</title><description>&lt;p&gt;If you have followed this tutorial so far, you will probably remember that in &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt; I had shown you how the GUI will look when we're done. Here it is again:

&lt;br&gt;&lt;br&gt;

&lt;a href="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrc2HIO4TI/AAAAAAAAACg/eHxP1zLTPyw/s1600/interface01.gif" imageanchor="1" &gt;&lt;img border="0" height="339" width="400" src="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrc2HIO4TI/AAAAAAAAACg/eHxP1zLTPyw/s400/interface01.gif" /&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;We have put together everything except our interface, so it's time to modify our &lt;b&gt;index.jsp&lt;/b&gt; to finalize the interface. Here's how your &lt;b&gt;index.jsp&lt;/b&gt; file should look right now:&lt;/p&gt;

&lt;pre class="brush: html; wrap-lines:false;"&gt;
&amp;lt;%@ taglib prefix=&amp;quot;c&amp;quot; uri=&amp;quot;http://java.sun.com/jsp/jstl/core&amp;quot; %&amp;gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
 &amp;lt;title&amp;gt;Modeling Agency Index&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;h1&amp;gt;The IdleWorx Modeling Agency&amp;lt;/h1&amp;gt;
&amp;lt;hr&amp;gt;

&amp;lt;div style=&amp;quot;width:300px;float:left;&amp;quot;&amp;gt;
 
 &amp;lt;h2&amp;gt;Available Clients&amp;lt;/h2&amp;gt;
 &amp;lt;c:forEach items=&amp;quot;${all_clients}&amp;quot; var=&amp;quot;client&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;client.do?id=${client.id}&amp;quot;&amp;gt;${client.name}&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;
 &amp;lt;/c:forEach&amp;gt; 
&amp;lt;/div&amp;gt;

&amp;lt;div style=&amp;quot;width:300px;float:left;&amp;quot;&amp;gt;
 &amp;lt;h2&amp;gt;Available Models&amp;lt;/h2&amp;gt;
 &amp;lt;c:forEach items=&amp;quot;${all_models}&amp;quot; var=&amp;quot;model&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;model.do?id=${model.id}&amp;quot;&amp;gt;${model.name}&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;
 &amp;lt;/c:forEach&amp;gt; 
&amp;lt;/div&amp;gt;

&amp;lt;div style=&amp;quot;clear:both;&amp;quot;&amp;gt;
 &amp;lt;h2&amp;gt;Bookings&amp;lt;/h2&amp;gt;
 &amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;
 &amp;lt;tr&amp;gt;
  &amp;lt;th&amp;gt;Client&amp;lt;/th&amp;gt;
  &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;
  &amp;lt;th&amp;gt;Time&amp;lt;/th&amp;gt;
  &amp;lt;th&amp;gt;Place&amp;lt;/th&amp;gt;
 &amp;lt;/tr&amp;gt;
 &amp;lt;c:forEach items=&amp;quot;${all_bookings}&amp;quot; var=&amp;quot;booking&amp;quot;&amp;gt;
 &amp;lt;tr&amp;gt;
  &amp;lt;td&amp;gt;${booking.client.name}&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;${booking.model.name}&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;${booking.time}&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;${booking.location}&amp;lt;/td&amp;gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
 &amp;lt;/c:forEach&amp;gt; 
 &amp;lt;/table&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Open up: &lt;a href="http://localhost:8080/ModelingAgency/test.do" target="_blank"&gt;http://localhost:8080/ModelingAgency/test.do&lt;/a&gt;. You should now have an interface very similar to the image above.&lt;/p&gt;

&lt;p&gt;You'll notice I used the JSTL and EL libraries to nicely write our output (please don't use scriptlets in your JSP classes).&lt;/p&gt;

&lt;p&gt;Also if you haven't noticed so far, in your ModelingAgency web application folder, you should have a file called &lt;b&gt;sql.log&lt;/b&gt; wich has logged all of the SQL statements that MyBatis generated. You may find it useful when debugging your MyBatis apps&lt;/p&gt;

&lt;h2&gt;Congrats&lt;/h2&gt;

&lt;p&gt;If you got this far, I hope you now feel more comfortable about MyBatis,Tomcat and MySQL. You should now have all the basics to get a very simple app started in Eclipse using these technologies.&lt;/p&gt;

&lt;p&gt;You can download a full version of the app &lt;a href="https://sites.google.com/site/idleworxblog/modelingagency.war?attredirects=0&amp;d=1"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;&lt;p&gt;This tutorial took me a long time to write, so if you found it useful in any way, if you found errors with it or you think something is missing, please let me know and I will do my best to improve it.&lt;/p&gt;&lt;/h4&gt;

&lt;p&gt;Go back to the &lt;a href="http://blog.idleworx.com/2011/02/mybatis-3-tomcat-mysql-eclipse.html"&gt;IdleWorx Monster MyBatis Tutorial&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-3499171989800946325?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BtOyU7Q4ViSsYtKWjQqumy6eK2E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BtOyU7Q4ViSsYtKWjQqumy6eK2E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BtOyU7Q4ViSsYtKWjQqumy6eK2E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BtOyU7Q4ViSsYtKWjQqumy6eK2E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/vnOlgSfQf6Q/part11-idleworx-monster-mybatis.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrc2HIO4TI/AAAAAAAAACg/eHxP1zLTPyw/s72-c/interface01.gif" height="72" width="72" /><thr:total>12</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part11-idleworx-monster-mybatis.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-4890871238098698640</guid><pubDate>Fri, 04 Feb 2011 00:30:00 +0000</pubDate><atom:updated>2011-02-03T16:49:41.735-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 10: Initializing MyBatis on Application Startup</title><description>&lt;p&gt;If you've been following &lt;a href="http://blog.idleworx.com/2011/02/part9-idleworx-monster-mybatis-tutorial.html"&gt;Part 9&lt;/a&gt; of this tutorial, we now need to make sure our application has an sqlSessionVariable available ready to go when the TestServlet is invoked.&lt;/p&gt;

&lt;p&gt;I had recently written a more detailed article about how to initialize MyBatis when a web application starts up. You can read that &lt;a href="http://blog.idleworx.com/2010/06/initialize-mybatis-servletcontextlisten.html" target="_blank"&gt;here&lt;/a&gt;.

&lt;p&gt;For this part of the tutorial, I'm just going to summarize what you need to do to get MyBatis to automatically initialize when the ModelingAgency webapp starts.&lt;/p&gt;  

&lt;h2&gt;Setting up a ServletContextListener&lt;/h2&gt;

&lt;p&gt;A ServletContextListener is useful when you want to do something when a java application starts up, more specifically, when a ServletContext is initalized.&lt;/p&gt;

&lt;p&gt;In our case, we're going to use a ServletContextListener to set a MyBatis SqlSessionan application scoped varible. This will allow us to instantiate our ModelingAgencyDAO object from our TestServlet. Here's how to do it: &lt;/p&gt;

&lt;h3&gt;1) Register the listener in web.xml&lt;/h3&gt;

&lt;p&gt;Add the following code to &lt;b&gt;web.xml&lt;/b&gt;&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;
&amp;lt;listener&amp;gt;
   &amp;lt;listener-class&amp;gt;
  com.modelingagency.listeners.CustomServletContextListener
   &amp;lt;/listener-class&amp;gt;
 &amp;lt;/listener&amp;gt;
&lt;/pre&gt;

&lt;h3&gt;2) Create the Listener class&lt;/h3&gt;

&lt;p&gt;Create the class &lt;b&gt;CustomServletContextListener.java&lt;/b&gt; under the &lt;b&gt;com.modelingagency.listeners&lt;/b&gt; package:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.modelingagency.listeners;
 
import java.io.Reader;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
public class CustomServletContextListener implements ServletContextListener
{
 public void contextInitialized(ServletContextEvent event)
 {  
  ServletContext ctx = event.getServletContext(); 
        
     String resource = "mybatis.config.xml";
     try{      
      Reader reader = Resources.getResourceAsReader(resource);     
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); //this will load the default environment configured in mybatis.config.xml
      ctx.setAttribute("sqlSessionFactory", sqlSessionFactory); //set the sqlSessionFactory as an application scoped variable
     }
     catch(Exception e){
      System.out.println("FATAL ERROR: myBatis could not be initialized");
      System.exit(1);
     }    
 }
 
 @Override
 public void contextDestroyed(ServletContextEvent event){
   //nothing to do here right now
 }
}

&lt;/pre&gt;

&lt;p&gt;If everything went well so far, you should be able to run the application again. Going to &lt;a href="http://localhost:8080/ModelingAgency/test.do" target="_blank"&gt;http://localhost:8080/ModelingAgency/test.do&lt;/a&gt; however will show the same things as before. So we need to finalize our interface. &lt;/p&gt;

&lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part11-idleworx-monster-mybatis.html"&gt;Part 11: Finalizing the Interface&lt;/a&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-4890871238098698640?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sGXOnK9wGZ0PEFL1nhZMk5x7wtc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sGXOnK9wGZ0PEFL1nhZMk5x7wtc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sGXOnK9wGZ0PEFL1nhZMk5x7wtc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sGXOnK9wGZ0PEFL1nhZMk5x7wtc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/doBa2BIYz28/part10-idleworx-monster-mybatis.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part10-idleworx-monster-mybatis.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-164456841571150782</guid><pubDate>Fri, 04 Feb 2011 00:26:00 +0000</pubDate><atom:updated>2011-09-23T18:11:17.345-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><category domain="http://www.blogger.com/atom/ns#">dao</category><title>Part 9: Creating the DAO Layer</title><description>&lt;p&gt;
Now that both our Java Data Model and our Database Model are connected through a MyBatis mapper file, we will add a Data Access Object class so we can abstract the calling of SQL statements, and keep our servlet clean of database related code. &lt;/p&gt;

&lt;p&gt;
I know it's not a 'pure' implementation of the DAO pattern however it serves the main purpose of decoupling servlet code from database related code.&lt;/p&gt;

&lt;p&gt;If you want to see a better way to integrate MyBatis and basic DAO classes, check out my other blog post &lt;a href="http://blog.idleworx.com/2011/09/mybatis-dao-example-code-tutorial.html"&gt;MyBatis DAO Example Code Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;ModelingAgencyDAO.java&lt;/h2&gt;

&lt;p&gt;ModelingAgencyDAO is going to be a Java class which encapsulates all the 'logical' database functionality we need, such as getting a list of all clients, models and bookings in our database. It will accomplish this by using the MyBatis framework.&lt;/p&gt;

&lt;p&gt;For now, create the file &lt;b&gt;ModelingAgencyDAO.java&lt;/b&gt; under the &lt;b&gt;com.modelingagency.db&lt;/b&gt; package, with the following content:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.modelingagency.db;

import java.util.ArrayList;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;

import com.modelingagency.objects.Booking;
import com.modelingagency.objects.Client;
import com.modelingagency.objects.Model;

public class ModelingAgencyDAO {

 private SqlSessionFactory sf;
 
 //constructor will receive a myBatis sessionFactory object
 public ModelingAgencyDAO(SqlSessionFactory containerSessionFactory) {
  if(containerSessionFactory==null)
   System.err.println(&amp;quot;Error: could not load myBatis sessionFactory&amp;quot;);  
  sf = containerSessionFactory;
 }
   
 public ArrayList&amp;lt;Client&amp;gt; getClients() throws PersistenceException{
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList&amp;lt;Client&amp;gt; clients = (ArrayList&amp;lt;Client&amp;gt;)session.selectList(&amp;quot;com.modelingagency.objects.SimpleMappers.allClients&amp;quot;);    
   return clients;  
  }
  finally
  {
   session.close();
  }
  
 }
  
 public ArrayList&amp;lt;Model&amp;gt; getModels() throws PersistenceException{
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList&amp;lt;Model&amp;gt; models = (ArrayList&amp;lt;Model&amp;gt;)session.selectList(&amp;quot;com.modelingagency.objects.SimpleMappers.allModels&amp;quot;);    
   return models;
  }
  finally
  {
   session.close();
  }
  
 }
 
 @Test
 public ArrayList&amp;lt;Booking&amp;gt; getBookings() throws PersistenceException{
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList&amp;lt;Booking&amp;gt; bookings = (ArrayList&amp;lt;Booking&amp;gt;)session.selectList(&amp;quot;com.modelingagency.objects.SimpleMappers.allBookings&amp;quot;);    
   return bookings;   
  }
  finally
  {
   session.close();
  }
  
 }
 
}

&lt;/pre&gt;

&lt;p&gt;You will notice the methods in this DAO class are very similar to the ones we defined in the MyBatisTest class in &lt;a href="http://blog.idleworx.com/2011/02/part8-idleworx-monster-mybatis-tutorial.html"&gt;Part 8&lt;/a&gt;. It's a good idea to have a test case setup for your DAO classes.&lt;/P&gt;

&lt;p&gt;Now in order to use the DAO from a servlet, all you have to do is create a new object and pass in a MyBatis SqlSessionFactory through the constructor. &lt;/p&gt;

&lt;p&gt;Let's modify our TestServlet so we can make use of our DAO class to retreive a list of all clients, a list of all models, and a list of all bookings. Your TestServlet.java class should now look like this:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.modelingagency.servlets;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.modelingagency.db.ModelingAgencyDAO;
import com.modelingagency.objects.*;

public class TestServlet  extends HttpServlet{
 
 private static Logger log = LoggerFactory.getLogger(TestServlet.class);
 
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
 {
  HttpSession session = request.getSession();   
  ServletContext sc = getServletContext();
  
  SqlSessionFactory sf = (SqlSessionFactory)getServletContext().getAttribute(&amp;quot;sqlSessionFactory&amp;quot;);
  ModelingAgencyDAO dao = new ModelingAgencyDAO(sf);
  
  try
  {
   ArrayList&amp;lt;Client&amp;gt; clients = dao.getClients();    
   ArrayList&amp;lt;Model&amp;gt; models = dao.getModels();    
   ArrayList&amp;lt;Booking&amp;gt; bookings = dao.getBookings();    
   
   request.setAttribute(&amp;quot;all_clients&amp;quot;, clients); 
   request.setAttribute(&amp;quot;all_models&amp;quot;, models);
   request.setAttribute(&amp;quot;all_bookings&amp;quot;, bookings);
       
  }
  catch(PersistenceException p)
  {
   p.printStackTrace();  
  }
  finally
  {
   request.setAttribute(&amp;quot;message&amp;quot;,&amp;quot;Welcome to the modeling agency MyBatis tutorial&amp;quot;);
   log.info(&amp;quot;The message attribute has been set&amp;quot;);
  } 
                
  RequestDispatcher view = request.getRequestDispatcher(&amp;quot;index.jsp&amp;quot;);
  view.forward(request, response);
 }
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request,response);
 }
 
}

&lt;/pre&gt;

&lt;p&gt;But before you can run the web application, you'll need to make sure that MyBatis has been initalized and available to the ModelingAgency app. &lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part10-idleworx-monster-mybatis.html"&gt;Part 10: Initializing MyBatis on application startup&lt;/a&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-164456841571150782?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t4M8daBr8d0UrPb8DyD0r8OQtAc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t4M8daBr8d0UrPb8DyD0r8OQtAc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t4M8daBr8d0UrPb8DyD0r8OQtAc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t4M8daBr8d0UrPb8DyD0r8OQtAc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/NHKVNxc89rw/part9-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>2</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part9-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-2425245755924263058</guid><pubDate>Fri, 04 Feb 2011 00:24:00 +0000</pubDate><atom:updated>2011-02-03T16:48:30.470-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">junit</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 8: Testing MyBatis with jUnit</title><description>&lt;p&gt;To be certain that the MyBatis configuration and Mapper files you setup in &lt;a href="http://blog.idleworx.com/2011/02/part7-idleworx-monster-mybatis-tutorial.html"&gt;Part 7&lt;/a&gt; are working properly, let's create a jUnit test to make sure.&lt;/p&gt;

&lt;p&gt;First, you will need to add the jUnit library to your Eclipse project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Right Click on the ModelingAgency project in Project Explorer&lt;/li&gt;
&lt;li&gt;Go to Properties -&gt; Java Build Path -&gt; Libraries Tab -&gt; Add Library (button)&lt;/li&gt;
&lt;li&gt;Select jUnit4 and click Finish&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Second, create a new package under your webapp called &lt;b&gt;com.modelingagency.tests&lt;/b&gt;. &lt;br&gt;We will keep our jUnit test classes in here.&lt;/p&gt;

&lt;p&gt;Third, add the file &lt;b&gt;MyBatisTest.java&lt;/b&gt; to the &lt;b&gt;com.modelingagency.tests&lt;/b&gt; package:&lt;/p&gt; 

&lt;pre class="brush: java; wrap-lines:false;"&gt;
package com.modelingagency.tests;

import static org.junit.Assert.*;

import java.io.Reader;
import java.util.ArrayList;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.modelingagency.objects.Booking;
import com.modelingagency.objects.Client;
import com.modelingagency.objects.Model;

public class MyBatisTest {
 
 private static Logger log = LoggerFactory.getLogger(MyBatisTest.class);
 private static SqlSessionFactory sf;
 
  
 @BeforeClass
 public static void setUp() throws Exception {
  log.info("starting up myBatis tests");
  String resource = "mybatis.config.xml";
  Reader reader = Resources.getResourceAsReader(resource);  
  sf = new SqlSessionFactoryBuilder().build(reader,"testing"); //we're using the 

'testing' 
 }
 
 @AfterClass
 public static void tearDown() throws Exception {  
  log.info("closing down myBatis tests");
 }
 
 @Test
 public void getClients(){
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList&lt;Client&gt; client = (ArrayList&lt;Client&gt;)session.selectList

("com.modelingagency.objects.SimpleMappers.allClients");    
   assertNotNull("Client list is null",client);   
  }
  finally
  {
   session.close();
  }
  
 }
  
 @Test
 public void getModels(){
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList&lt;Model&gt; model = (ArrayList&lt;Model&gt;)session.selectList

("com.modelingagency.objects.SimpleMappers.allModels");    
   assertNotNull("Model list is null",model);
  }
  finally
  {
   session.close();
  }
  
 }
 
 @Test
 public void getBookings(){
    
  SqlSession session = sf.openSession();
  try
  {   
   ArrayList&lt;Booking&gt; bookings = (ArrayList&lt;Booking&gt;)session.selectList

("com.modelingagency.objects.SimpleMappers.allBookings");    
   assertNotNull("Booking is null",bookings);   
  }
  finally
  {
   session.close();
  }
  
 }
 
 
}
&lt;/pre&gt;

&lt;p&gt;I'm not going into detail into what the MyBatisTest class does, but it should be self explanatory. It loads the MyBatis configuration we have defined, using the 'test' environment, and then runs some test methods against the queries we have defined in the &lt;b&gt;SimpleMappers.xml&lt;/b&gt; mapper file.&lt;/p&gt;  
  
&lt;p&gt;To run the test, right click on the MyBatisTest.java, and select &lt;br&gt;Run As -&gt; jUnit Test&lt;/p&gt;

&lt;p&gt;If everything went well, you should see the following output in the jUnit window: &lt;br&gt;&lt;br&gt;

&lt;a href="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrvFetlVZI/AAAAAAAAACo/Ea2VAq78rJw/s1600/junittest01.gif" imageanchor="1" &gt;&lt;img border="0" height="132" width="400" src="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrvFetlVZI/AAAAAAAAACo/Ea2VAq78rJw/s400/junittest01.gif" /&gt;&lt;/a&gt;

&lt;/p&gt;


&lt;p&gt;Now you're ready to move on. &lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part9-idleworx-monster-mybatis-tutorial.html"&gt;Part 9: Creating the DAO Layer&lt;/a&gt;&lt;/h4&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-2425245755924263058?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ihX8Z6EKkunL8w3CI9Z2BuSgWhk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ihX8Z6EKkunL8w3CI9Z2BuSgWhk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ihX8Z6EKkunL8w3CI9Z2BuSgWhk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ihX8Z6EKkunL8w3CI9Z2BuSgWhk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/-qHVTNr4cG8/part8-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrvFetlVZI/AAAAAAAAACo/Ea2VAq78rJw/s72-c/junittest01.gif" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part8-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-5191425260512292352</guid><pubDate>Fri, 04 Feb 2011 00:18:00 +0000</pubDate><atom:updated>2011-02-03T16:47:55.511-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 7: Configuring MyBatis</title><description>&lt;p&gt;If you have followed the first parts of this tutorial &lt;a href="http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html"&gt;Part 1&lt;/a&gt; to &lt;a href="http://blog.idleworx.com/2011/02/part6-idleworx-monster-mybatis-tutorial.html"&gt;Part 6&lt;/a&gt; you should now have a very simple MySQL database setup and the java layer ready for the ModelingAgency web application.&lt;/p&gt;

&lt;p&gt;Now I'm going to show you how to integrate your database and java model layer with MyBatis 3&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up the MyBatis configuration file&lt;/li&gt;
&lt;li&gt;Configuring the mapper file&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;The MyBatis configuration file&lt;/h2&gt;

&lt;p&gt;First it's time to add the main MyBatis configuration file to your web application. You can call this file anything you want, but let's use &lt;b&gt;mybatis.config.xml&lt;/b&gt; for now.&lt;/p&gt;

&lt;p&gt;This file will hold all the MyBatis configuration info and references to all the other sql mapping files we will define.&lt;/p&gt;

&lt;p&gt;Create the following file &lt;b&gt;/src/mybatis.config.xml&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;
&amp;lt;!DOCTYPE configuration PUBLIC &amp;quot;-//mybatis.org//DTD Config 3.0//EN&amp;quot; 
 &amp;quot;http://mybatis.org/dtd/mybatis-3-config.dtd&amp;quot;&amp;gt;
&amp;lt;!-- Created by 2011: http://blog.idleworx.com http://www.idleworx.com --&amp;gt;
&amp;lt;configuration&amp;gt;
 
 &amp;lt;properties resource=&amp;quot;dbcp.properties&amp;quot;/&amp;gt;
  
 &amp;lt;settings&amp;gt;
  &amp;lt;setting name=&amp;quot;useGeneratedKeys&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;
 &amp;lt;/settings&amp;gt;
    
 &amp;lt;typeAliases&amp;gt;  
  &amp;lt;typeAlias alias=&amp;quot;Client&amp;quot; type=&amp;quot;com.modelingagency.objects.Client&amp;quot;/&amp;gt;
  &amp;lt;typeAlias alias=&amp;quot;Model&amp;quot; type=&amp;quot;com.modelingagency.objects.Model&amp;quot;/&amp;gt;
  &amp;lt;typeAlias alias=&amp;quot;Booking&amp;quot; type=&amp;quot;com.modelingagency.objects.Booking&amp;quot;/&amp;gt;  
 &amp;lt;/typeAliases&amp;gt;
  
 &amp;lt;environments default=&amp;quot;development&amp;quot;&amp;gt;
  
  &amp;lt;environment id=&amp;quot;development&amp;quot;&amp;gt;
   &amp;lt;transactionManager type=&amp;quot;JDBC&amp;quot;/&amp;gt;
   &amp;lt;dataSource type=&amp;quot;JNDI&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;initial_context&amp;quot; value=&amp;quot;java:comp/env&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;data_source&amp;quot; value=&amp;quot;/jdbc/mydb&amp;quot;/&amp;gt; 
   &amp;lt;/dataSource&amp;gt;
  &amp;lt;/environment&amp;gt;
  
  &amp;lt;environment id=&amp;quot;testing&amp;quot;&amp;gt;
   &amp;lt;transactionManager type=&amp;quot;JDBC&amp;quot;/&amp;gt;
   &amp;lt;dataSource type=&amp;quot;POOLED&amp;quot;&amp;gt;
    &amp;lt;property name=&amp;quot;driver&amp;quot; value=&amp;quot;${db.driver}&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;url&amp;quot; value=&amp;quot;${db.url}&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;username&amp;quot; value=&amp;quot;${db.user}&amp;quot;/&amp;gt;
    &amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;${db.pass}&amp;quot;/&amp;gt;
   &amp;lt;/dataSource&amp;gt;
  &amp;lt;/environment&amp;gt;
    
 &amp;lt;/environments&amp;gt;

 &amp;lt;mappers&amp;gt;
  &amp;lt;mapper resource=&amp;quot;com/modelingagency/objects/SimpleMappers.xml&amp;quot;/&amp;gt;
 &amp;lt;/mappers&amp;gt;

&amp;lt;/configuration&amp;gt;

&lt;/pre&gt;

&lt;p&gt;Also, create the following file &lt;b&gt;/src/dbcp.properties&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;
db.url=jdbc:mysql://localhost/modeling_agency
db.driver=com.mysql.jdbc.Driver
db.user=test
db.pass=test
&lt;/pre&gt;

&lt;h3&gt;Notes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You'll notice we have a 'testing' environment setup. We'll use that for testing our app with jUnit.&lt;/li&gt;
&lt;li&gt;Using the &lt;b&gt;useGeneratedKeys&lt;/b&gt; property will allow MyBatis to make use of the autogenerated row id values from the database, as we defined in the SQL in &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt;: &lt;i&gt;client_id INTEGER NOT NULL AUTO_INCREMENT&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;typeAliases&lt;/b&gt; will simplify things for you, by helping MyBatis identify fully qualified java class names. This way you won't have to type the fully qualified names of your objects in MyBatis mapper files&lt;/li&gt; 
&lt;li&gt;In a typical application there are usually many SQL mapper files, however for our simple application we only really need one, the SimpleMappers.xml file&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;mybatis.config.xml&lt;/b&gt; file should go under &lt;b&gt;/src/mybatis.config.xml&lt;/b&gt;   (this is because the file should be on the application's classpath)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Tip:&lt;/b&gt;If you're wondering how to setup multiple environments in MyBatis see my other blog posting: &lt;a href="http://blog.idleworx.com/2010/06/initialize-mybatis-servletcontextlisten.html" target="_blank"&gt;Initializing MyBatis Using a ServletContextListener&lt;/a&gt;&lt;/p&gt;        


&lt;h2&gt;Configuring the Mapper file&lt;/h2&gt;

&lt;p&gt;MyBatis SQL mappers allow us to map our java data model to our database model. &lt;/p&gt;

&lt;p&gt;The mapper file holds all the sql statments you need to interact with your database, so it's pretty important, and it also happens to be a critical element of the MyBatis framework, which will simplify your life a lot, once you pass the learning curve :)&lt;/p&gt;

&lt;p&gt;The mapper file also stores definitions of objects that will be used to retrieve data from the database. By doing this MyBatis abstracts most of the hard work of writing tons of sql statements, and most importantly jdbc code.&lt;/p&gt;

&lt;p&gt;Since we've configured this file's location (&lt;b&gt;com/modelingagency/objects/SimpleMappers.xml&lt;/b&gt;) in the &lt;b&gt;mybatis.config.xml&lt;/b&gt; file above, MyBatis now knows to load this resource whenever it is initialized.&lt;/p&gt;

&lt;br&gt;

&lt;p&gt;The main functionality we're going to need now in the SimpleMapper.xml file is this: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1) Getting a list of clients&lt;/li&gt;
&lt;li&gt;2) Getting a list of models&lt;/li&gt;
&lt;li&gt;3) Getting a list of all bookings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create the following file: &lt;b&gt;/src/com/modelingagency/objects/SimpleMappers.xml&lt;/b&gt;:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;
&amp;lt;!DOCTYPE mapper PUBLIC &amp;quot;-//mybatis.org//DTD Mapper 3.0//EN&amp;quot; &amp;quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&amp;quot;&amp;gt;
&amp;lt;!-- Created by: http://blog.idleworx.com, http://www.idleworx.com --&amp;gt;
&amp;lt;mapper namespace=&amp;quot;com.modelingagency.objects.SimpleMappers&amp;quot;&amp;gt;
 
 &amp;lt;resultMap id=&amp;quot;clientResultMap&amp;quot; type=&amp;quot;Client&amp;quot;&amp;gt;
  &amp;lt;id property=&amp;quot;id&amp;quot; column=&amp;quot;client_id&amp;quot; /&amp;gt;  
  &amp;lt;result property=&amp;quot;name&amp;quot; column=&amp;quot;client_name&amp;quot; /&amp;gt;  
 &amp;lt;/resultMap&amp;gt;
 
 &amp;lt;resultMap id=&amp;quot;modelResultMap&amp;quot; type=&amp;quot;Model&amp;quot;&amp;gt;
  &amp;lt;id property=&amp;quot;id&amp;quot; column=&amp;quot;model_id&amp;quot; /&amp;gt;  
  &amp;lt;result property=&amp;quot;name&amp;quot; column=&amp;quot;model_name&amp;quot; /&amp;gt; 
 &amp;lt;/resultMap&amp;gt;
  
 &amp;lt;resultMap id=&amp;quot;bookingResultMap&amp;quot; type=&amp;quot;Booking&amp;quot;&amp;gt;
  &amp;lt;id property=&amp;quot;id&amp;quot; column=&amp;quot;booking_id&amp;quot; /&amp;gt;  
  &amp;lt;result property=&amp;quot;time&amp;quot; column=&amp;quot;booking_time&amp;quot; /&amp;gt;    
  &amp;lt;result property=&amp;quot;location&amp;quot; column=&amp;quot;booking_location&amp;quot; /&amp;gt;
  &amp;lt;association property=&amp;quot;client&amp;quot; column=&amp;quot;booking_client_id&amp;quot; javaType=&amp;quot;Client&amp;quot; resultMap=&amp;quot;clientResultMap&amp;quot;/&amp;gt;
  &amp;lt;association property=&amp;quot;model&amp;quot; column=&amp;quot;booking_model_id&amp;quot; javaType=&amp;quot;Model&amp;quot; resultMap=&amp;quot;modelResultMap&amp;quot;/&amp;gt;
 &amp;lt;/resultMap&amp;gt; 
  
 &amp;lt;select id=&amp;quot;allClients&amp;quot; parameterType=&amp;quot;string&amp;quot; resultMap=&amp;quot;clientResultMap&amp;quot;&amp;gt;
  select  * from client order by 1  
 &amp;lt;/select&amp;gt;
 
 &amp;lt;select id=&amp;quot;allModels&amp;quot; parameterType=&amp;quot;string&amp;quot; resultMap=&amp;quot;modelResultMap&amp;quot;&amp;gt;
  select  * from model order by 1
 &amp;lt;/select&amp;gt;
 
 &amp;lt;select id=&amp;quot;allBookings&amp;quot; parameterType=&amp;quot;string&amp;quot; resultMap=&amp;quot;bookingResultMap&amp;quot;&amp;gt;
  select * from client, model, booking
  where booking_client_id = client_id and booking_model_id = model_id
  order by 1
 &amp;lt;/select&amp;gt;
 
&amp;lt;/mapper&amp;gt;

&lt;/pre&gt;

&lt;h3&gt;Notes&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The name of each query is identified by the 'id' parameter&lt;/li&gt;
&lt;li&gt;&lt;b&gt;parameterType&lt;/b&gt; indicates what type of parameter you will pass into the sql statement (for simple queries there is only one parameter or none), for queries which require multiple parameters you can use the 'hashmap' parameterType to pass in name value pairs. In our case the parameter is not actually used.&lt;/li&gt;
&lt;li&gt;By defining &lt;b&gt;result maps&lt;/b&gt; for each of our objects, MyBatis knows how to automatically map a column from the database table directly to the javabean property name (in our case the Client,Model and Booking classes)&lt;/li&gt;
&lt;li&gt;If you don't use Result Maps in your mapper files, you can use the &lt;b&gt;resultType&lt;/b&gt; attribute instead which specifies the Java Bean class name we want to map, and which is defined in &lt;b&gt;mybatis.config.xml&lt;/b&gt;. Normally you have to put a fully qualified class name here like com.modelingagency.objects.Model, but because if you defined the &lt;b&gt;typeAliases&lt;/b&gt; element in the &lt;b&gt;mybatis.config.xml&lt;/b&gt; you can just use the short name&lt;/li&gt;
&lt;li&gt;The &lt;b&gt;allBookings&lt;/b&gt; query makes use of MyBatis associations. 
Associations are what MyBatis uses to retrieve one-to-many relationships from your database into java objects. To learn more about this read: &lt;a href="http://blog.idleworx.com/2010/10/mybatis-multiple-table-joins.html" target="_blank"&gt;Understanding MyBatis' Multiple Table Joins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;To make sure the MyBatis configuration and mapper files are all setup correctly, before we create our DAO layer and use it from our Servlet, we need to do a quick test. &lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part8-idleworx-monster-mybatis-tutorial.html"&gt;Part 8: Testing MyBatis with jUnit&lt;/a&gt;&lt;/h4&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-5191425260512292352?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rPr5nrLmTeBKHTBG2KUrNjsDM34/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rPr5nrLmTeBKHTBG2KUrNjsDM34/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rPr5nrLmTeBKHTBG2KUrNjsDM34/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rPr5nrLmTeBKHTBG2KUrNjsDM34/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/MgmR8qcuLlM/part7-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part7-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-2303124149962791284</guid><pubDate>Fri, 04 Feb 2011 00:13:00 +0000</pubDate><atom:updated>2011-02-03T16:47:24.834-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">pojo</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 6: The Java POJO model</title><description>&lt;p&gt;If you've been following &lt;a href="http://blog.idleworx.com/2011/02/mybatis-3-tomcat-mysql-eclipse.html"&gt;IdleWorx's Tutorial on Building a Web Application with MyBatis,MySQL,Tomcat and Eclipse &lt;/a&gt;, you should be now ready to setup the database layer of the ModelingAgency webapp.&lt;/p&gt;

&lt;p&gt;In order to be able to interact with the database we setup in &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt; we will create a simple java model made of POJOs (simple JavaBeans that is).&lt;/p&gt;

&lt;p&gt;These Plain Old Java Objects (POJOs) will serve as the model, or in other words, a way to transfer data between the database and the ModelingAgency webapp.&lt;/p&gt;

&lt;p&gt;At this point we're not concerned about how we'll actually retrieve the data from the database into our model classes, that is where MyBatis will come in later on and take care of that for us.&lt;/p&gt;

&lt;p&gt;If you remember our database layout from &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt;, we have 3 business objects in our application that we need to model:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Client&lt;/li&gt;&lt;li&gt;Model&lt;/li&gt;&lt;li&gt;Booking&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;So let's add the following classes to the com.modelingagency.objects package:&lt;/p&gt;

&lt;p&gt;Client.java&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.modelingagency.objects;

/**
 * Copyright 2011: http://blog.idleworx.com, http://www.idleworx.com   
 */
public class Client {
 private Integer id;
 private String name;
 
 public Client(){}
 
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 @Override
 public String toString() {
  return "[client] " + "(" + id + ")" + " " + name;
 }
}

&lt;/pre&gt;

&lt;p&gt;Model.java&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;
package com.modelingagency.objects;

/**
 * Copyright 2011: http://blog.idleworx.com, http://www.idleworx.com   
 */
public class Model {

 private Integer id;
 private String name;
 
 public Model() {}
 
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 @Override
 public String toString() {
  return "[model] " + "(" + id + ")" + " " + name;
 }
}
&lt;/pre&gt;

&lt;p&gt;Booking.java&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;
package com.modelingagency.objects;

import java.sql.Timestamp;
import java.util.Date;

/**
 * Copyright 2011: http://blog.idleworx.com, http://www.idleworx.com   
 */
public class Booking {

 private Integer id;
 private Client client;
 private Model model;
 private Timestamp time;
 private String location;
 
 public Booking(){}
 
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public Client getClient() {
  return client;
 }
 public void setClient(Client client) {
  this.client = client;
 }
 public Model getModel() {
  return model;
 }
 public void setModel(Model model) {
  this.model = model;
 }
 public Timestamp getTime() {
  return time;
 }
 public void setTime(Timestamp time) {
  this.time = time;
 }
 public String getLocation() {
  return location;
 }
 public void setLocation(String location) {
  this.location = location;
 }
 
 @Override
 public String toString() {
  return "[booking] " + "(" + id + ")" + " where: " + location + " when: " + new Date(time.getTime());
 }
 
}

&lt;/pre&gt;

&lt;p&gt;Note that the Booking model class doesn't have getters for the booking_client_id and booking_model_id fields which are part of the booking table.&lt;/p&gt;

&lt;p&gt;We're not going to model each field directly into our java beans,
instead we're going to let MyBatis retrieve the actual Client and Model objects whenever a Booking object is returned from the database. And we're going to accomplish this through the use of MyBatis Result Maps, as you will shortly see.&lt;/p&gt; 

&lt;p&gt;Before we do that however, we need to setup MyBatis. &lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part7-idleworx-monster-mybatis-tutorial.html"&gt;Part 7: Configuring MyBatis&lt;/a&gt;&lt;/h4&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-2303124149962791284?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ivoLOjKuu2Shu0WVmiIweVjnicM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ivoLOjKuu2Shu0WVmiIweVjnicM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ivoLOjKuu2Shu0WVmiIweVjnicM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ivoLOjKuu2Shu0WVmiIweVjnicM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/APmnzGZ3O6o/part6-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part6-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-7768779678312135211</guid><pubDate>Fri, 04 Feb 2011 00:10:00 +0000</pubDate><atom:updated>2011-02-03T16:46:46.744-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">logback</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 5: Setting up Logging</title><description>&lt;p&gt;If you've followed &lt;a href="http://blog.idleworx.com/2011/02/part4-idleworx-monster-mybatis-tutorial.html"&gt;Part 4&lt;/a&gt; of this tutorial, we're about to setup logging for the ModelingAgency webapp in order to learn how to use MySQL, MyBatis and Tomcat togather.&lt;/p&gt;

&lt;p&gt;If you're familiar with Log4J you can use that library. However for the ModelingAgency webapp we're going to setup the Logback library, which is the new Log4J.&lt;/p&gt;

&lt;p&gt;You have probably already downloaded the Logback jars in &lt;a href="http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html"&gt;Part 1&lt;/a&gt;. If not, you can download all of the jars required for the ModelingAgency app &lt;a href="https://sites.google.com/site/idleworxblog/jar_files_modelingagency.zip?attredirects=0&amp;d=1"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Configuring Logback&lt;/h2&gt;

&lt;p&gt;Configuring Logback with a Java web application is relatively simple. Once you have the required jars in &lt;b&gt;/WEB-INF/lib&lt;/b&gt;, create a file called &lt;b&gt;logback.xml&lt;/b&gt; and put it under your project's &lt;b&gt;/src&lt;/b&gt; folder.&lt;/p&gt;&lt;p&gt;Here is the &lt;b&gt;logback.xml&lt;/b&gt; file we we will use for this project:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;configuration scan=&amp;quot;true&amp;quot; debug=&amp;quot;false&amp;quot; &amp;gt; &amp;lt;!-- set debug to true to dump logback status info when library is loaded --&amp;gt;
 
  &amp;lt;contextName&amp;gt;ModelingAgency&amp;lt;/contextName&amp;gt;
  
  &amp;lt;!-- APPENDERS --&amp;gt;
  
  &amp;lt;appender name=&amp;quot;STDOUT&amp;quot; class=&amp;quot;ch.qos.logback.core.ConsoleAppender&amp;quot;&amp;gt;    
    &amp;lt;!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --&amp;gt;
    &amp;lt;encoder&amp;gt; 
      &amp;lt;pattern&amp;gt;[%contextName] %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&amp;lt;/pattern&amp;gt;
    &amp;lt;/encoder&amp;gt;
  &amp;lt;/appender&amp;gt;
  
  &amp;lt;appender name=&amp;quot;SQLDUMP&amp;quot; class=&amp;quot;ch.qos.logback.core.FileAppender&amp;quot;&amp;gt;
    &amp;lt;file&amp;gt;sql.log&amp;lt;/file&amp;gt;
    &amp;lt;append&amp;gt;false&amp;lt;/append&amp;gt;
    &amp;lt;encoder&amp;gt;
      &amp;lt;!-- &amp;lt;pattern&amp;gt;%date %level [%thread] %logger{10} [%file:%line] %msg%n&amp;lt;/pattern&amp;gt; --&amp;gt;
      &amp;lt;pattern&amp;gt;[%contextName] [%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n&amp;lt;/pattern&amp;gt;      
    &amp;lt;/encoder&amp;gt;
  &amp;lt;/appender&amp;gt;
  
  &amp;lt;appender name=&amp;quot;FILE&amp;quot; class=&amp;quot;ch.qos.logback.core.FileAppender&amp;quot;&amp;gt;
    &amp;lt;file&amp;gt;application.log&amp;lt;/file&amp;gt;
    &amp;lt;encoder&amp;gt;
      &amp;lt;!-- &amp;lt;pattern&amp;gt;%date %level [%thread] %logger{10} [%file:%line] %msg%n&amp;lt;/pattern&amp;gt; --&amp;gt;
      &amp;lt;pattern&amp;gt;[%contextName] [%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n&amp;lt;/pattern&amp;gt;      
    &amp;lt;/encoder&amp;gt;
  &amp;lt;/appender&amp;gt;
  
  &amp;lt;appender name=&amp;quot;OUT&amp;quot; class=&amp;quot;ch.qos.logback.core.ConsoleAppender&amp;quot;&amp;gt;    
    &amp;lt;encoder&amp;gt;
    &amp;lt;pattern&amp;gt;[%contextName] [%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n&amp;lt;/pattern&amp;gt;        
    &amp;lt;/encoder&amp;gt;
  &amp;lt;/appender&amp;gt;
  
   &amp;lt;appender name=&amp;quot;OUT_SIMPLE&amp;quot; class=&amp;quot;ch.qos.logback.core.ConsoleAppender&amp;quot;&amp;gt;    
    &amp;lt;encoder&amp;gt;
    &amp;lt;pattern&amp;gt;[%c] %5p - %m %n&amp;lt;/pattern&amp;gt;        
    &amp;lt;/encoder&amp;gt;
  &amp;lt;/appender&amp;gt;
        
  &amp;lt;!-- LOGGERS --&amp;gt;  
    
  &amp;lt;!--  loggers inherit the appender from their parent ( the root logger ) --&amp;gt;
  &amp;lt;logger name=&amp;quot;java.sql&amp;quot; level=&amp;quot;DEBUG&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt; 
   &amp;lt;appender-ref ref=&amp;quot;SQLDUMP&amp;quot; /&amp;gt; 
  &amp;lt;/logger&amp;gt;
   
  &amp;lt;logger name=&amp;quot;org.apache.ibatis.datasource&amp;quot; level=&amp;quot;WARN&amp;quot;/&amp;gt; &amp;lt;!-- removes datasoure debug info from logs --&amp;gt; 
       
  &amp;lt;root level=&amp;quot;debug&amp;quot;&amp;gt; &amp;lt;!-- can set level to OFF--&amp;gt;
    &amp;lt;appender-ref ref=&amp;quot;OUT&amp;quot; /&amp;gt;
  &amp;lt;/root&amp;gt;
  
&amp;lt;/configuration&amp;gt;

&lt;/pre&gt;



&lt;h2&gt;Adding logging to TestServlet&lt;/h2&gt;

&lt;p&gt;To make sure logback works properly, let's add some simple logging code to the TestServlet we created in &lt;a href="http://blog.idleworx.com/2011/02/part4-idleworx-monster-mybatis-tutorial.html"&gt;Part 4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following logging code to the TestServlet.java file:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.modelingagency.servlets;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestServlet  extends HttpServlet{
 
 private static Logger log = LoggerFactory.getLogger(TestServlet.class);
 
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
 {
  HttpSession session = request.getSession();   
  ServletContext sc = getServletContext();
  
  request.setAttribute("message","This is a message from the TestServlet. It works!");
  log.info("The message attribute has been set");
             
  RequestDispatcher view = request.getRequestDispatcher("index.jsp");
  view.forward(request, response); 
 }
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request,response);
 }
 
}

&lt;/pre&gt;


&lt;p&gt;Restart your project now, by right clicking on the &lt;b&gt;index.jsp&lt;/b&gt; file and selecting &lt;b&gt;Run on server&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;If you access the TestServlet's url on your local server now, &lt;a href="http://localhost:8080/ModelingAgency/test.do"&gt;http://localhost:8080/ModelingAgency/test.do&lt;/a&gt; you should get an output like this: &lt;/p&gt;

&lt;p&gt;&lt;b&gt;[ModelingAgency] [com.modelingagency.servlets.TestServlet] [03 Feb 2011 - 10:38:26]  INFO - The message attribute has been set &lt;/b&gt;&lt;/p&gt;


&lt;p&gt;If you got this far, it means you have setup Logback logging for the ModelingAgency webapp.&lt;/p&gt;

&lt;p&gt;Now the fun part, &lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part6-idleworx-monster-mybatis-tutorial.html"&gt;Part 6: Creating the java pojo model&lt;/a&gt;&lt;/p&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-7768779678312135211?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Gc_Mwa0aTgyitzQcfQeo6kNtv28/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gc_Mwa0aTgyitzQcfQeo6kNtv28/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Gc_Mwa0aTgyitzQcfQeo6kNtv28/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gc_Mwa0aTgyitzQcfQeo6kNtv28/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/WB1xIAzzEnA/part5-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part5-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-4993179989698272976</guid><pubDate>Thu, 03 Feb 2011 23:33:00 +0000</pubDate><atom:updated>2011-02-03T16:46:05.834-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 4: Creating a Test Servlet</title><description>&lt;p&gt;If you've been following &lt;a href="http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html"&gt;Part 3&lt;/a&gt; of this tutorial, you are on your way to creating a Java Web Application using MyBatis,MySQL and Tomcat in Eclipse.&lt;/p&gt;

&lt;h2&gt;Creating a test Servlet&lt;/h2&gt;

&lt;p&gt;So far we have created the MySQL database for the ModelingAgency application in &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt; and we have setup the ModelingAgency project in Eclipse in &lt;a href="http://blog.idleworx.com/2011/02/part4-idleworx-monster-mybatis-tutorial.html"&gt;Part 4&lt;/a&gt;, but we haven't used any Servlets yet.&lt;/p&gt; 

&lt;p&gt;Even if you're not familiar with the MVC model (which you should be if you're reading this tutorial), if you're using plain old Servlets these days it's typical to use them as a Controller.&lt;/p&gt;&lt;p&gt; In other words as a java classes responsible for reading request parameters, performing business logic, and passing on the necessary data to a view (eg. a jsp file) in the form of request parameters.&lt;/p&gt;

&lt;p&gt;If all this sounds confusing to you, and you're considering learning Java Web Application Development, I would strongly recommend grabbing a copy of &lt;a href="http://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/B002VKPV6K/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1296776180&amp;sr=8-2" target="_blank"&gt;Head 1st Servlets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To take our application to the next level, and help you understand servlets better, we're going to create a test servlet.&lt;/p&gt;


&lt;h2&gt;The Servlet&lt;/h2&gt;

&lt;p&gt;Create a new java class called &lt;b&gt;TestServlet.java&lt;/b&gt; under the &lt;b&gt;com.modelingagency.servlets&lt;/b&gt; package:&lt;/p&gt;

&lt;pre class="brush: java; wrap-lines:false;"&gt;

package com.modelingagency.servlets;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class TestServlet  extends HttpServlet{

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
 {
  HttpSession session = request.getSession();   
  ServletContext sc = getServletContext();
  
  request.setAttribute("message","This is a message from the TestServlet. It works!"); 
             
  RequestDispatcher view = request.getRequestDispatcher("index.jsp");
  view.forward(request, response); 
 }
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request,response);
 }
 
}
&lt;/pre&gt;

&lt;p&gt;We're going to use this servlet to display a simple text string to make sure things are working, before moving forward.&lt;/p&gt;

&lt;p&gt;Don't forget to configure your servlet in the deployment descriptor, so the webapp knows how to 'serve' it. &lt;br&gt;&lt;br&gt;Your &lt;b&gt;web.xml&lt;/b&gt; file should now look like this:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;web-app id=&amp;quot;WebApp_ID&amp;quot; version=&amp;quot;2.4&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&amp;gt;
 
 &amp;lt;display-name&amp;gt;ModelingAgency&amp;lt;/display-name&amp;gt;
 
 &amp;lt;welcome-file-list&amp;gt;
  &amp;lt;welcome-file&amp;gt;index.html&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;index.htm&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;default.html&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;default.htm&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;default.jsp&amp;lt;/welcome-file&amp;gt;
 &amp;lt;/welcome-file-list&amp;gt;
 
 &amp;lt;resource-ref&amp;gt;
      &amp;lt;description&amp;gt;DB Connection&amp;lt;/description&amp;gt;
      &amp;lt;res-ref-name&amp;gt;jdbc/mydb&amp;lt;/res-ref-name&amp;gt;
      &amp;lt;res-type&amp;gt;javax.sql.DataSource&amp;lt;/res-type&amp;gt;
      &amp;lt;res-auth&amp;gt;Container&amp;lt;/res-auth&amp;gt;
  &amp;lt;/resource-ref&amp;gt;
  
  &amp;lt;servlet&amp;gt;
  &amp;lt;servlet-name&amp;gt;test&amp;lt;/servlet-name&amp;gt;
  &amp;lt;servlet-class&amp;gt;com.modelingagency.servlets.TestServlet&amp;lt;/servlet-class&amp;gt;  
 &amp;lt;/servlet&amp;gt;
 
 &amp;lt;servlet-mapping&amp;gt;
  &amp;lt;servlet-name&amp;gt;test&amp;lt;/servlet-name&amp;gt;
  &amp;lt;url-pattern&amp;gt;/test.do&amp;lt;/url-pattern&amp;gt;
 &amp;lt;/servlet-mapping&amp;gt; 
  
&amp;lt;/web-app&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;index.jsp&lt;/h2&gt;

&lt;p&gt;Before we re-start our server and run our application again to see if all this works, don't forget to modify &lt;b&gt;index.jsp&lt;/b&gt; so it will display the attribute you set in the servlet&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;index.jsp&lt;/b&gt; file should now look like this:&lt;/p&gt;

&lt;pre class="brush: html; wrap-lines:false;"&gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
 &amp;lt;title&amp;gt;Modeling Agency Index&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

Things are looking good.
&amp;lt;br&amp;gt;
${requestScope.message}

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;

&lt;p&gt;If you run the application again, and go the the servlet url that we setup in the deployment descriptor, &lt;a href="http://localhost:8080/ModelingAgency/test.do" target="_blank"&gt;http://localhost:8080/ModelingAgency/test.do&lt;/a&gt; you should see the output:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;
Things are looking good. 
&lt;br&gt;
This is a message from the TestServlet. It works! 
&lt;/b&gt;
&lt;/p&gt;

&lt;h2&gt;What next&lt;/h2&gt;

&lt;p&gt;If you got so far, you are well on your way to setting up a web application using MySQL,MyBatis and Tomcat using Eclipse. Before we get to the MyBatis part, lets see how to setup logging for the ModelingAgency web application (or any java web application for that matter).&lt;/p&gt;

&lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part5-idleworx-monster-mybatis-tutorial.html"&gt;Part 5: Setting up Logging&lt;/a&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-4993179989698272976?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t1cgWh1Kp4hyobaOn9OH12wHD8Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t1cgWh1Kp4hyobaOn9OH12wHD8Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t1cgWh1Kp4hyobaOn9OH12wHD8Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t1cgWh1Kp4hyobaOn9OH12wHD8Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/snPv5NEnCjw/part4-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part4-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-5545317999207305062</guid><pubDate>Thu, 03 Feb 2011 23:29:00 +0000</pubDate><atom:updated>2011-02-03T16:45:31.783-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 3: Creating the ModelingAgency project in Eclipse</title><description>&lt;p&gt;If you've followed the previous tutorials &lt;a href="http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html"&gt;Part 1&lt;/a&gt; and &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt; you should now be ready to create a simple java web application called ModelingAgency in Eclipse, in order to learn how MySQL, MyBatis and Tomcat work together.&lt;/p&gt;

&lt;h2&gt;Creating a new project&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open up Eclipse. Under the Project Explorer tab right click and select New -&gt; Project&lt;/li&gt;
&lt;li&gt;Select the Dynamic Web Project and click Next &lt;br&gt;

&lt;a href="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn8XVsTajI/AAAAAAAAAB0/7YryGR9eiZ4/s1600/eclipse_new_project.png" imageanchor="1" &gt;&lt;img border="0" height="400" width="400" src="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn8XVsTajI/AAAAAAAAAB0/7YryGR9eiZ4/s400/eclipse_new_project.png" /&gt;&lt;/a&gt;
&lt;/li&gt;

&lt;li&gt;Enter the project properties. For this project we will use the 2.4 Dynamic Web Module version, and the Tomcat 6.0 Runtime (which you may have to configure manually)&lt;br&gt;

&lt;a href="http://2.bp.blogspot.com/_uwTR1dSr5Co/TUn99hfoLqI/AAAAAAAAAB8/9-0CfiHL1M0/s1600/eclipse_new_project02.gif" imageanchor="1" &gt;&lt;img border="0" height="400" width="333" src="http://2.bp.blogspot.com/_uwTR1dSr5Co/TUn99hfoLqI/AAAAAAAAAB8/9-0CfiHL1M0/s400/eclipse_new_project02.gif" /&gt;&lt;/a&gt;

&lt;/li&gt;

&lt;li&gt;
Click Finish. You should now have a project that looks like this: &lt;br&gt;

&lt;a href="http://1.bp.blogspot.com/_uwTR1dSr5Co/TUn-5NMtMWI/AAAAAAAAACE/usLNwrRnXJU/s1600/eclipse_new_project03.gif" imageanchor="1" &gt;&lt;img border="0" height="400" width="395" src="http://1.bp.blogspot.com/_uwTR1dSr5Co/TUn-5NMtMWI/AAAAAAAAACE/usLNwrRnXJU/s400/eclipse_new_project03.gif" /&gt;&lt;/a&gt;
&lt;/li&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Setup the java packages&lt;/h2&gt;

&lt;p&gt;To organize our code a little, let's create the following packages under our /src directory&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;com.modelingagency.db&lt;/li&gt;
&lt;li&gt;com.modelingagency.listeners&lt;/li&gt;
&lt;li&gt;com.modelingagency.objects&lt;/li&gt;
&lt;li&gt;com.modelingagency.servlets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click on &lt;b&gt;Java Resources: src&lt;/b&gt; -&gt; New -&gt; Package and create the packages above&lt;/p&gt;

&lt;h2&gt;External jar files&lt;/h2&gt;

&lt;p&gt;Remember all those jar files you downloaded in Part 1 (the mybatis jar, standard.jar,jstl.jar,etc). Now it's time to make them available to the webapp by placing them under the &lt;b&gt;/WEB-INF/lib&lt;/b&gt; folder.&lt;/p&gt;

&lt;p&gt;You can download all the jar files you need to place in this folder &lt;a href="https://sites.google.com/site/idleworxblog/jar_files_modelingagency.zip?attredirects=0&amp;d=1" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;Configuring the database connection&lt;/h2&gt;

&lt;p&gt;In order to connect to the database we have setup in &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt;, we have to add a &lt;b&gt;context.xml&lt;/b&gt; file under the &lt;b&gt;/META-INF&lt;/b&gt; folder.&lt;/p&gt;

&lt;p&gt;There are other was to setup a database connection from Tomcat, but placing it in &lt;b&gt;/META-INF/context.xml&lt;/b&gt; allows each webapp to be bundled with its database configuration, and is easier to manage in my experience.&lt;/p&gt;

&lt;h2&gt;context.xml&lt;/h2&gt;
&lt;p&gt;Create the following file and place it under &lt;b&gt;/META-INF/context.xml&lt;/b&gt;&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;Context docBase=&amp;quot;ModelingAgency&amp;quot; path=&amp;quot;/ModelingAgency&amp;quot; reloadable=&amp;quot;true&amp;quot; &amp;gt;
                        
      &amp;lt;!-- http://commons.apache.org/dbcp/configuration.html --&amp;gt;      
      &amp;lt;Resource name=&amp;quot;jdbc/mydb&amp;quot; auth=&amp;quot;Container&amp;quot; type=&amp;quot;javax.sql.DataSource&amp;quot;
               maxActive=&amp;quot;100&amp;quot; 
               maxIdle=&amp;quot;5&amp;quot; 
               maxWait=&amp;quot;10000&amp;quot;
               
               username=&amp;quot;test&amp;quot; password=&amp;quot;test&amp;quot; 
               driverClassName=&amp;quot;com.mysql.jdbc.Driver&amp;quot;
               url=&amp;quot;jdbc:mysql://localhost/modeling_agency&amp;quot; 
               
               removeAbandoned=&amp;quot;true&amp;quot;
               removeAbandonedTimeout=&amp;quot;10&amp;quot;
      logAbandoned=&amp;quot;true&amp;quot;
      validationQuery=&amp;quot;SELECT 1&amp;quot; /&amp;gt; 
             
&amp;lt;/Context&amp;gt;

&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt;The docBase attribute and path map to the same name as your Eclipse project name. Also, If you have a different username or password that you created in &lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2&lt;/a&gt;, other than 'test' make sure to use it instead.&lt;/p&gt;

&lt;h2&gt;web.xml&lt;/h2&gt;

&lt;p&gt;The deployment descriptor, web.xml, is the most important piece in any Java webapp (but I'm sure you know that already). &lt;/p&gt;

&lt;p&gt;In order to make the database connection we defined in &lt;b&gt;context.xml&lt;/b&gt; known to your webapp, you should also add a resource entry in &lt;b&gt;web.xml&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Edit your &lt;b&gt;web.xml&lt;/b&gt; file so it looks like this:&lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;

&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;web-app id=&amp;quot;WebApp_ID&amp;quot; version=&amp;quot;2.4&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&amp;gt;
 
 &amp;lt;display-name&amp;gt;ModelingAgency&amp;lt;/display-name&amp;gt;
 
 &amp;lt;welcome-file-list&amp;gt;
  &amp;lt;welcome-file&amp;gt;index.html&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;index.htm&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;default.html&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;default.htm&amp;lt;/welcome-file&amp;gt;
  &amp;lt;welcome-file&amp;gt;default.jsp&amp;lt;/welcome-file&amp;gt;
 &amp;lt;/welcome-file-list&amp;gt;
 
 &amp;lt;resource-ref&amp;gt;
      &amp;lt;description&amp;gt;DB Connection&amp;lt;/description&amp;gt;
      &amp;lt;res-ref-name&amp;gt;jdbc/mydb&amp;lt;/res-ref-name&amp;gt;
      &amp;lt;res-type&amp;gt;javax.sql.DataSource&amp;lt;/res-type&amp;gt;
      &amp;lt;res-auth&amp;gt;Container&amp;lt;/res-auth&amp;gt;
  &amp;lt;/resource-ref&amp;gt;
  
&amp;lt;/web-app&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;Starting the app&lt;/h2&gt;

&lt;p&gt;Just to make sure we're on the right track and things are working fine, let's create an index page and start our server:&lt;/p&gt;

&lt;p&gt;First, create the following &lt;b&gt;index.jsp&lt;/b&gt; file under the &lt;b&gt;/WebContent&lt;/b&gt; folder.&lt;/p&gt;

&lt;pre class="brush: html; wrap-lines:false;"&gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
 &amp;lt;title&amp;gt;Modeling Agency Index&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

Things are looking good.

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Now to start the ModelingAgency web application on a tomcat server, &lt;br&gt;&lt;b&gt;right click&lt;/b&gt; the index.jsp file, select &lt;b&gt;Run As&lt;/b&gt; -&gt; &lt;b&gt;Run on server&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Make sure the &lt;b&gt;Server's host name&lt;/b&gt; is &lt;b&gt;localhost&lt;/b&gt; and the &lt;b&gt;Server runtime environment&lt;/b&gt; is associated with your Tomcat 6.0 installation. Click Finish.&lt;/p&gt;

&lt;p&gt;If all is well, the server should be running in Eclipse and you will see this: &lt;br&gt;
&lt;a href="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUoHmV7qQeI/AAAAAAAAACM/1cBe4MVzCYU/s1600/server_start01.gif" imageanchor="1" &gt;&lt;img border="0" height="285" width="400" src="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUoHmV7qQeI/AAAAAAAAACM/1cBe4MVzCYU/s400/server_start01.gif" /&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;Your project layout at this point should be looking like this: &lt;br&gt;

&lt;a href="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUoH7t2cOdI/AAAAAAAAACU/1mcWGlwjn2Q/s1600/project_layout02.gif" imageanchor="1" &gt;&lt;img border="0" height="400" width="378" src="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUoH7t2cOdI/AAAAAAAAACU/1mcWGlwjn2Q/s400/project_layout02.gif" /&gt;&lt;/a&gt;

&lt;/p&gt;


&lt;p&gt;Now you are ready to move on to &lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part4-idleworx-monster-mybatis-tutorial.html"&gt;Part 4: Creating a Test Servlet&lt;/a&gt;&lt;/h4&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-5545317999207305062?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/719ds1jnIzin8v8g8RGSZUU7plY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/719ds1jnIzin8v8g8RGSZUU7plY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/719ds1jnIzin8v8g8RGSZUU7plY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/719ds1jnIzin8v8g8RGSZUU7plY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/Kr-QPEcWWOE/part3-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn8XVsTajI/AAAAAAAAAB0/7YryGR9eiZ4/s72-c/eclipse_new_project.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-1036176692116126230</guid><pubDate>Thu, 03 Feb 2011 23:22:00 +0000</pubDate><atom:updated>2011-02-03T16:44:14.248-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 2: The ModelingAgency Application</title><description>&lt;p&gt;
&lt;a href="http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html"&gt;Part 1: The Setup&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;To see how Tomcat, MyBatis and MySQL work together, we're going to create a small Java web application in Eclipse called ModelingAgency. 

&lt;p&gt;The Modeling Agency web app does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It lets a photographer (a client object) book a model (a model object) for a photography shoot at a particular place and time (a booking object).&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;The Interface&lt;/h2&gt;

&lt;p&gt;Our interface is going to look something like this when we're done: &lt;br&gt;

&lt;a href="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrc2HIO4TI/AAAAAAAAACg/eHxP1zLTPyw/s1600/interface01.gif" imageanchor="1" &gt;&lt;img border="0" height="339" width="400" src="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrc2HIO4TI/AAAAAAAAACg/eHxP1zLTPyw/s400/interface01.gif" /&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;You can think of the application as an appointment organizer for photographers. I'm sure this will make more sense when you see the actual tables.&lt;/p&gt;

&lt;h2&gt;The Tables&lt;/h2&gt;

&lt;p&gt;The client table&lt;/p&gt;
&lt;a href="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn2qzwZBfI/AAAAAAAAABk/0PPzJ_6zulw/s1600/client_table.gif" imageanchor="1" &gt;&lt;img border="0" height="154" width="285" src="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn2qzwZBfI/AAAAAAAAABk/0PPzJ_6zulw/s400/client_table.gif" /&gt;&lt;/a&gt;

&lt;p&gt;The model table&lt;/p&gt;
&lt;a href="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn28YVTCUI/AAAAAAAAABs/wRNeX3s35Co/s1600/model_table.gif" imageanchor="1" &gt;&lt;img border="0" height="152" width="265" src="http://4.bp.blogspot.com/_uwTR1dSr5Co/TUn28YVTCUI/AAAAAAAAABs/wRNeX3s35Co/s400/model_table.gif" /&gt;&lt;/a&gt;

&lt;p&gt;The booking table&lt;/p&gt;
&lt;a href="http://1.bp.blogspot.com/_uwTR1dSr5Co/TUn2D91WWQI/AAAAAAAAABc/ZxmhBUHJgZ0/s1600/booking_table.gif" imageanchor="1" &gt;&lt;img border="0" height="44" width="320" src="http://1.bp.blogspot.com/_uwTR1dSr5Co/TUn2D91WWQI/AAAAAAAAABc/ZxmhBUHJgZ0/s320/booking_table.gif" /&gt;&lt;/a&gt;

&lt;h2&gt;The SQL&lt;/h2&gt;

&lt;p&gt;Here is the sql to create the MySQL database for our ModelingAgency, and populate with the data above:&lt;/p&gt;

&lt;pre class="brush: sql; wrap-lines:false;"&gt;

create database modeling_agency;
use modeling_agency;
grant all on modeling_agency.* to 'test'@'localhost' identified by 'test' #feel free to rename this to whatever you want

CREATE TABLE modeling_agency.client
(
  client_id INTEGER NOT NULL AUTO_INCREMENT,
  client_name VARCHAR(45) NOT NULL DEFAULT '',
  PRIMARY KEY(client_id)
);

CREATE TABLE modeling_agency.model
(
  model_id INTEGER NOT NULL AUTO_INCREMENT,
  model_name VARCHAR(45) NOT NULL DEFAULT '',
  PRIMARY KEY(model_id)
);

CREATE TABLE modeling_agency.booking
(
 booking_id INTEGER NOT NULL AUTO_INCREMENT,
 booking_client_id INTEGER,
 booking_model_id INTEGER,
 booking_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
 booking_location VARCHAR(100) NOT NULL DEFAULT '##NO LOCATION SELECTED##', 
 PRIMARY KEY (booking_id),
 CONSTRAINT `FK_booking_client` FOREIGN KEY (booking_client_id)
  REFERENCES modeling_agency.client (client_id),
 CONSTRAINT `FK_booking_model` FOREIGN KEY (booking_model_id)
  REFERENCES modeling_agency.model (model_id) 
);

insert into modeling_agency.client (client_name) values ("Michelangelo");
insert into modeling_agency.client (client_name) values ("Rafaelo");
insert into modeling_agency.client (client_name) values ("Leonardo");
insert into modeling_agency.client (client_name) values ("Donatello");

insert into modeling_agency.model (model_name) values ("Monalisa");
insert into modeling_agency.model (model_name) values ("Plain Jane");
insert into modeling_agency.model (model_name) values ("Funky Susan");
insert into modeling_agency.model (model_name) values ("Mary");

insert into booking (booking_client_id,booking_model_id,booking_location) values ((select client_id from client where client_name = 'Michelangelo'),(select model_id from model where model_name = 'Monalisa'),"Somewhere in Italy");
insert into booking (booking_client_id,booking_model_id,booking_location) values ((select client_id from client where client_name = 'Leonardo'),(select model_id from model where model_name = 'Plain Jane'),"Near the river");
insert into booking (booking_client_id,booking_model_id,booking_location) values ((select client_id from client where client_name = 'Donatello'),(select model_id from model where model_name = 'Mary'),"On the beach");

&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt;Keep in mind the mysql test user we setup in the SQL above, as it will be the same you will use when you configure how Tomcat will work with your database&lt;/p&gt;

&lt;p&gt;Now we're ready to setup the ModelingAgency project as a DynamicWeb project in eclipse.&lt;/p&gt;

&lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html"&gt;Part 3: Creating the ModelingAgency project in Eclipse&lt;/a&gt;&lt;/h4&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-1036176692116126230?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AKGH04Xh-C3NLjYZJriQawD-GAM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AKGH04Xh-C3NLjYZJriQawD-GAM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AKGH04Xh-C3NLjYZJriQawD-GAM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AKGH04Xh-C3NLjYZJriQawD-GAM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/ahfIOdAduL0/part2-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_uwTR1dSr5Co/TUrc2HIO4TI/AAAAAAAAACg/eHxP1zLTPyw/s72-c/interface01.gif" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-830579932230401415</guid><pubDate>Thu, 03 Feb 2011 23:12:00 +0000</pubDate><atom:updated>2011-02-03T16:42:51.996-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mybatis</category><category domain="http://www.blogger.com/atom/ns#">mysql</category><category domain="http://www.blogger.com/atom/ns#">jstl</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">logback</category><category domain="http://www.blogger.com/atom/ns#">tomcat</category><title>Part 1: The Setup</title><description>&lt;h2&gt;Installing Eclipse&lt;/h2&gt;

&lt;p&gt;
Chances are you already have Eclipse installed by now. Just make sure you have the Java EE version of Eclipse or at least the Web Tools Project installed.
&lt;/p&gt;

&lt;p&gt;For this tutorial I used Java EE Eclipse (Helios) SR1&lt;/p&gt;

&lt;p&gt;If you are installing eclipse for the first time use this link: 
&lt;a href="http://eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/heliossr1" target="_blank"&gt;Download Java EE Eclipse Helios&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;Installing Tomcat 6&lt;/h2&gt;

&lt;p&gt;Go to: &lt;a href="http://tomcat.apache.org/index.html" target="_blank"&gt;http://tomcat.apache.org/index.html&lt;/a&gt; and download the appropriate Tomcat distribution you need. &lt;br&gt;Tomcat 5.5 or 6 should both work with this tutorial.&lt;/p&gt;

&lt;p&gt;For this tutorial I used Tomcat 6.0.29. &lt;br&gt;You can download this version &lt;a href="http://apache.tradebit.com/pub//tomcat/tomcat-6/v6.0.29/bin/apache-tomcat-6.0.29.exe" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Installing MySQL&lt;/h2&gt;

&lt;p&gt;It's assumed at this point that you have a working MySQL database instance setup already. Ideally MySQL version 5.1 or above. If you already have the MySQL driver setup with your Tomcat server you can skip this section, if not, read on.&lt;/p&gt;

&lt;p&gt;To use MySQL from your Java web application you will first need to download 
the MySQL Java Driver, also known as the &lt;b&gt;JDBC Driver for MySQL (Connector/J)&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;1) Go to: &lt;a href="http://www.mysql.com/downloads/connector/j/" target="_blank"&gt;http://www.mysql.com/downloads/connector/j/&lt;/a&gt; and download &lt;b&gt;JDBC Driver for MySQL (Connector/J)&lt;/b&gt; zip archive.&lt;/p&gt;

&lt;p&gt;2) Extract the driver .jar file into your Tomcat installation: &lt;br&gt;&lt;br&gt;
&lt;b&gt;CATALINA_HOME/common/lib&lt;/b&gt; folder (Tomcat 5) or &lt;b&gt;CATALINA_HOME/lib&lt;/b&gt; (Tomcat 6)&lt;/p&gt;

&lt;p&gt;For this tutorial I used the &lt;b&gt;mysql-connector-java-5.1.13-bin.jar&lt;/b&gt; but any version above that should also work.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Tip:&lt;/b&gt; Avoid putting your MySQL driver jar under &lt;b&gt;WEB-INF/lib&lt;/b&gt; as it may cause issues down the road when you want to use mysql with other webapps. You'll probably forget about it and it will cause class path conflicts. So the best bet is to leave it in the shared libraries folder of your Tomcat server. That way all webapps will have access to it.&lt;/p&gt;

&lt;h2&gt;Jar libraries for this tutorial&lt;/h2&gt;

&lt;p&gt;To make things quicker for you, you can download all the jar files you will need for this tutorial &lt;a href="https://sites.google.com/site/idleworxblog/jar_files_modelingagency.zip?attredirects=0&amp;d=1"&gt;here&lt;/a&gt;. Once we setup the eclipse project in &lt;a href="http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html"&gt;Part 3: Creating the ModelingAgency project in Eclipse&lt;/a&gt;, you can just extract all the jars here under the &lt;b&gt;/WEB-INF/lib folder&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;However if you want to do it manually follow the rest of this tutorial.&lt;/p&gt;

&lt;h2&gt;Installing MyBatis&lt;/h2&gt;

&lt;p&gt;Go to: &lt;a href="http://www.mybatis.org/java.html" target="_blank"&gt;http://www.mybatis.org/java.html&lt;/a&gt;. &lt;br&gt;Click on &lt;a href="http://code.google.com/p/mybatis/downloads/list?can=3&amp;q=%22mybatis-3%22+-migrations" target="_blank"&gt;Download the Persistence Framework&lt;/a&gt; and download the zipped archive &lt;a href="http://mybatis.googlecode.com/files/mybatis-3.0.4-bundle.zip" target="_blank"&gt;&lt;b&gt;mybatis-3.0.4-bundle.zip&lt;/b&gt; (direct link)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we have setup the ModelingAgency web application in Eclipse in &lt;a href="http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html"&gt;Part 3: Creating the ModelingAgency project in Eclipse&lt;/a&gt;, you will extract the &lt;b&gt;mybatis-3.0.4.jar&lt;/b&gt; to the &lt;b&gt;/WEB-INF/lib folder&lt;/b&gt; of your application. &lt;i&gt;Don't worry, I'll remind you about that later.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Tip:&lt;/b&gt;Before you go any futher, I would strongly suggest you go through the very well written MyBatis documentation before you continue with this tutorial (Especially if you've never used iBatis or MyBatis). It will take about 30 minutes to skim through it, and will give you an excellent foundation of the basics.&lt;/p&gt;

&lt;a href="http://mybatis.googlecode.com/files/MyBatis-3.0.3-User-Guide.pdf" target="_blank"&gt;download the documentation&lt;/a&gt;

&lt;h2&gt;Installing JSTL/EL&lt;/h2&gt;

&lt;p&gt;One last thing. In our project we are going to use the JSTL library to make things easier a bit. With a combination of the JSP Expression Language and the JSTL library you should almost never need to write 'java' code inside your jsp files anymore. To learn more about this read &lt;a href="http://blog.idleworx.com/2010/04/evolution-of-servlets-and-jsp.html" target="_blank"&gt;The Evolution of Servlets and JSP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
To make use of Java's JSTL library and the JSP Expression Language in our project, you will need to download &lt;b&gt;jstl.jar&lt;/b&gt; and &lt;b&gt;standard.jar&lt;/b&gt; from the Jakarta Taglibs Project extract them to the &lt;b&gt;/WEB-INF/lib folder&lt;/b&gt; of your application. &lt;i&gt;Don't worry, I'll remind you about this later as well.&lt;/i&gt;. &lt;br&gt;&lt;/p&gt;
&lt;p&gt;These jars can be found here:&lt;/p&gt;

&lt;p&gt;Go to: &lt;a href="http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi" target="_blank"&gt;http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi&lt;/a&gt; and download the 1.1.2.zip binary. &lt;br&gt;For direct link &lt;a href="http://www.reverse.net/pub/apache//jakarta/taglibs/standard/binaries/jakarta-taglibs-standard-1.1.2.zip" target="_blank"&gt;click here&lt;/a&gt;.&lt;/p&gt; 

&lt;h2&gt;Installing LogBack (the new Log4j)&lt;/h2&gt;

&lt;p&gt;If you want to be able to log things to the console for this project you should also install LogBack, the successor of Log4J&lt;/p&gt;

&lt;p&gt;Download &lt;a href="http://logback.qos.ch/dist/logback-0.9.28.zip" target="_blank"&gt;logback-0.9.28.zip&lt;/a&gt;. You will need to extract the following files to the &lt;b&gt;/WEB-INF/lib&lt;/b&gt; folder of the webapp we will setup in &lt;a href="http://blog.idleworx.com/2011/02/part3-idleworx-monster-mybatis-tutorial.html"&gt;Part 3: Creating the ModelingAgency project in Eclipse&lt;/a&gt;.
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logback-core-0.9.28.jar&lt;/li&gt;
&lt;li&gt;logback-classic-0.9.28.jar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also an additional depndency which logback needs, which you can download from here: &lt;a href="http://www.slf4j.org/dist/slf4j-1.6.1.zip" target="_blank"&gt;slf4j-api-1.6.1.jar&lt;/a&gt;&lt;/p&gt;


&lt;/p&gt;



&lt;p&gt;If you feel like everything here is setup correctly, let's move on to &lt;br&gt;&lt;h4&gt;&lt;a href="http://blog.idleworx.com/2011/02/part2-idleworx-monster-mybatis-tutorial.html"&gt;Part 2: The ModelingAgency Application&lt;/a&gt;&lt;/h4&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-830579932230401415?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/INFXzcA1UkV7x7xXo6Eatj9pgoo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/INFXzcA1UkV7x7xXo6Eatj9pgoo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/INFXzcA1UkV7x7xXo6Eatj9pgoo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/INFXzcA1UkV7x7xXo6Eatj9pgoo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/_iJu-Qf8czU/part1-idleworx-monster-mybatis-tutorial.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/part1-idleworx-monster-mybatis-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-5485811080619633302</guid><pubDate>Tue, 01 Feb 2011 22:21:00 +0000</pubDate><atom:updated>2011-02-01T14:21:24.751-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">rails</category><title>Problems with Foundation Rails 2 by Eldon Almeda</title><description>&lt;p&gt;
If you've been going through the Foundation Rails 2 book and ran into some problems with the sample rails apps, you're not alone.
Here's some common errors I ran into and some solutions I found digging around the web.&lt;/p&gt;
&lt;p&gt;
If you have any version other than rails 2.1.0 installed, I would suggest uninstalling rails and all it's dependencies and reinstalling this version, as rails 2.1.0 seems to work best with the exercises in this book. The solutions described here apply to ruby 1.9.1 [1.9.1p430] and rails 2.1.0&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;If however, you do have a version of Rails &gt; 2.1.0 [not reccomended], and you're trying to get it to work, try updating the &lt;b&gt;config/environment.rb&lt;/b&gt; rails version to whatever of Rails you are using: &lt;/i&gt;&lt;br&gt;&lt;br&gt;
&lt;b&gt;RAILS_GEM_VERSION = 'x.x.x' unless defined? RAILS_GEM_VERSION&lt;/b&gt;
&lt;br&gt; but in this case, some of the solutions in this post may not work for you.&lt;/p&gt;

&lt;h3&gt;Problems&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
 &lt;p&gt;&lt;b&gt;PROBLEM:&lt;/b&gt; Problems related to sqlite or sqlite3.dll.&lt;/p&gt;
 &lt;p&gt;&lt;b&gt;Possible solution:&lt;/b&gt; 
 &lt;ul&gt;
  &lt;li&gt;
   &lt;p&gt;First, make sure you have installed the &lt;b&gt;sqlite3-ruby&lt;/b&gt; library: 'gem install sqlite3-ruby'&lt;/p&gt;
   &lt;p&gt;And place the sqlite.dll into &lt;b&gt;ruby_installation_directory/bin&lt;/b&gt; folder prior to running any of the example apps&lt;/p&gt;
  &lt;/li&gt;
 &lt;/ul&gt;
 
&lt;/li&gt;


&lt;li&gt;
 &lt;p&gt;&lt;b&gt;PROBLEM:&lt;/b&gt; You run ruby script/server and get the following&lt;/p&gt;
 &lt;p&gt;&lt;span style="color:red"&gt;boot.rb:86:in `load_rubygems': undefined method `&gt;=' for nil:NilClass (NoMethodError)&lt;/span&gt;&lt;/p&gt;
 &lt;p&gt;&lt;b&gt;Possible solution:&lt;/b&gt; 
 &lt;ul&gt;
  &lt;li&gt;In confing/boot.rb, inside the load_rubygems method replace: &lt;br&gt; 
   &lt;b&gt;unless (rubygems_version) = 'x.x.x'&lt;/b&gt; &lt;br&gt; with
   &lt;br&gt;  
   &lt;b&gt;unless (rubygems_version || Gem::RubyGemsVersion) &gt;= '1.3.7'   #or whatever gems version you have.&lt;/b&gt;
  &lt;/li&gt;
 &lt;/ul&gt;
&lt;/li&gt;


&lt;li&gt;
 &lt;p&gt;&lt;b&gt;PROBLEM:&lt;/b&gt; You run ruby script/server and get the following &lt;br&gt;&lt;br&gt;
 &lt;span style="color:red"&gt;no such file to load -- test/unit/error (MissingSourceFile) &lt;/span&gt;&lt;br&gt;
 
 &lt;p&gt;&lt;b&gt;Possible solution:&lt;/b&gt; 
 &lt;ul&gt;
  &lt;li&gt;
   Make sure you have the &lt;b&gt;test-unit&lt;/b&gt; library installed: 'gem install test-unit'
  &lt;/li&gt;
  &lt;li&gt;
   You might also want to try 'gem clean'
  &lt;/li&gt;
 &lt;/ul&gt;
&lt;/li&gt;
 

 &lt;li&gt;
 &lt;p&gt;&lt;b&gt;PROBLEM:&lt;/b&gt; You are trying to use the &lt;br&gt;&lt;b&gt;&lt;%= error_messages_for :post %&gt;&lt;/b&gt; or a similar helper&lt;br&gt;&lt;br&gt;
 And you get the following message:&lt;br&gt;&lt;br&gt; 
&lt;span style="color:red"&gt;{{count}} errors prohibited this {{model}} from being saved &lt;/span&gt;&lt;br&gt;
 
 &lt;p&gt;&lt;b&gt;Possible solution:&lt;/b&gt; 
 &lt;ul&gt;
  &lt;li&gt;
   It seems that the i18n library version 0.5.0 might cause problems. Try uninstalling it (gem uninstall i18n -v=0.5.0) and install the 0.4.2 version (gem install i18n -v=0.4.2). &lt;br&gt;&lt;br&gt;
   &lt;i&gt;
    If you already installed Rails 2.1.0 it might complain that another library depends on i18n version 0.5.0, so in that case re-install rails 2.1.0 and all its dependencies.
   &lt;/i&gt;
  &lt;/li&gt;
  &lt;li&gt;
   You might also want to try 'gem clean'
  &lt;/li&gt;
 &lt;/ul&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;b&gt;My current 'gem list' command, dumps this:&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;
actionmailer (2.1.0)
actionpack (2.1.0)
activerecord (2.1.0)
activeresource (2.1.0)
activesupport (2.1.0)
archive-tar-minitar (0.5.2)
arel (2.0.6)
builder (2.1.2)
columnize (0.3.2)
i18n (0.4.2)
ibm_db (2.5.5 mswin32)
nokogiri (1.4.4.1 x86-mingw32)
rack (1.1.0)
rails (2.1.0)
rake (0.8.7)
ruby_core_source (0.1.4)
sqlite3 (1.3.3 x86-mingw32)
sqlite3-ruby (1.3.3)
test-unit (2.1.2)
tzinfo (0.3.23)
&lt;/pre&gt;

&lt;p&gt;So if you have something similar, you should hopefully be able to resolve the issues described in this post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-5485811080619633302?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XCK_dTPLacgju1AYLPlUCdd0tbs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XCK_dTPLacgju1AYLPlUCdd0tbs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XCK_dTPLacgju1AYLPlUCdd0tbs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XCK_dTPLacgju1AYLPlUCdd0tbs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/L9zwmkwwg1Y/problems-foundation-rails-2-by-eldon.html</link><author>noreply@blogger.com (IdleWorx)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.idleworx.com/2011/02/problems-foundation-rails-2-by-eldon.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4368777317649012081.post-4754392786938336073</guid><pubDate>Sun, 28 Nov 2010 17:48:00 +0000</pubDate><atom:updated>2010-11-28T09:53:10.199-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>Friendly CSS Error Messages for Java Web Applications</title><description>&lt;p&gt;
A while ago I had discovered Richard O'Neil's article on 
&lt;a href="http://richardoneill.com.au/2007/05/designing-message-boxes/" target="_blank"&gt;Designing Message Boxes&lt;/a&gt;.  I highly recommend reading the article first.
&lt;/p&gt;

&lt;p&gt;
It's a great tutorial for adding a simple but really nice styles to your web application's error messages using CSS and the now ubiquitous &lt;a href="http://www.famfamfam.com/" target="_blank"&gt;FamFamFam Silk Icons&lt;/a&gt;  pack.
&lt;/p&gt;

&lt;p&gt;Here is how it looks&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_uwTR1dSr5Co/TPKWdcoX3MI/AAAAAAAAABU/SrjxjD4QDKI/s1600/css_alerts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="64" src="http://4.bp.blogspot.com/_uwTR1dSr5Co/TPKWdcoX3MI/AAAAAAAAABU/SrjxjD4QDKI/s320/css_alerts.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
Recently however I decided to improve upon it a little for use in my own applications. So here are the modifications I made:
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Added better color/display of fonts&lt;/li&gt;
  &lt;li&gt;Added onclick dismissal/hiding of alerts using jQuery&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Installation&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
1. Download the following images from the &lt;a href="http://www.famfamfam.com/" target="_blank"&gt;FamFamFam Silk Icons&lt;/a&gt; pack and save them in your &lt;b&gt;/images&lt;/b&gt; folder or something similar: &lt;ul&gt;
&lt;li&gt;msg_ok.png&lt;/li&gt;&lt;li&gt;msg_info.png&lt;/li&gt;&lt;li&gt;msg_warning.png&lt;/li&gt;&lt;li&gt;msg_error.png&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;

2. Save the following CSS file as alerts.css and put it in your application's directory structure

&lt;pre class="brush: css; wrap-lines:false;"&gt;
/* Friendly CSS Error Messages
   Original idea by http://www.richardoneill.com.au/tags/web_design 
   Improved by IdleWorx @ http://blog.idleworx.com
   http://blog.idleworx.com/2010/11/friendly-css-error-messages-for-java.html
*/

.msgOK{
 color:#69A150;
 font-size:1.2em;
 font-family: 'helvetica', Georgia, arial, sans-serif;
 font-weight:bold; 
}

.msgInfo{
 color:#5C7CA0;
 font-size:1.2em;
 font-family: 'helvetica', Georgia, arial, sans-serif;
 font-weight:bold; 
}

.msgWarn{
 color:#BF9E1B;
 font-size:1.2em;
 font-family: 'helvetica', Georgia, arial, sans-serif;
 font-weight:bold; 
}

.msgError{
 color:#AD5E5C; 
 font-size:1.2em;
 font-family: 'helvetica', Georgia, arial, sans-serif;
 font-weight:bold; 
}

.msgOK{
   cursor:pointer;
   cursor:hand;
   background: #E7FFD6 url('../images/msg_ok.png') center no-repeat;
   background-position: 15px 50%;
   text-align: left;
   padding: 5px 5px 5px 45px;
   border-top: 2px solid #8CD76B;
   border-bottom: 2px solid #8CD76B;
   border:2px solid #8CD76B;
   overflow:auto;
   font-size:1.4em;
   font-family:Verdana;
}

.msgInfo{
   cursor:pointer;
   cursor:hand;
   background: #E7F3FF url('../images/msg_info.png') center no-repeat;
   background-position: 15px 50%;
   text-align: left;
   padding: 5px 5px 5px 45px;
   border-top: 2px solid #7BA6D6;
   border-bottom: 2px solid #7BA6D6;
   border:2px solid #7BA6D6;
   overflow:auto;
   font-size:1.4em;
   font-family:Verdana;
}

.msgWarn {
   cursor:pointer;
   cursor:hand;
   background: #fff6bf url('../images/msg_warning.png') center no-repeat;
   background-position: 15px 50%;
   text-align: left;
   padding: 5px 5px 5px 45px;
   border-top: 2px solid #ffd324;
   border-bottom: 2px solid #ffd324;
   border:2px solid #ffd324;
   overflow:auto;   
   font-size:1.4em;
   font-family:Verdana;
}

.msgError {
   cursor:pointer;
   cursor:hand;
   background: #FFE7E7 url('../images/msg_error.png') center no-repeat;
   background-position: 15px 50%;
   text-align: left;
   padding: 5px 5px 5px 45px;
   border-top: 2px solid #E77D7B;
   border-bottom: 2px solid #E77D7B;
   border:2px solid #E77D7B;
   overflow:auto;
   font-size:1.4em;
   font-family:Verdana;
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
3. Update the CSS file to use the location of the images you saved in step 1 (based on your applications folder structure)
&lt;/li&gt;
&lt;li&gt;
4. Use the following html code anywhere you want to display these messages (client side)

&lt;pre class="brush: html; wrap-lines:false;"&gt;
&lt;div class="messages"&gt; 
 &lt;div class="msgOK" title="Click to close"&gt;
  OK message
 &lt;/div&gt; 
 
 &lt;div class="msgError" title="Click to close"&gt;
  Error Message
 &lt;/div&gt;
 
 &lt;div class="msgWarn" title="Click to close"&gt;
  Warning Message
 &lt;/div&gt;
 
 &lt;div class="msgInfo" title="Click to close"&gt;
  Info Message
 &lt;/div&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
If you did everything correctly you should now see something like this:&lt;br&gt;
[image here]
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;For Java Web Applications&lt;/h3&gt;

&lt;p&gt;To simplify things a little if you're dealing with a Java Web Application do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract the html code into a jsp file called alerts.jsp:

&lt;pre class="brush: html; wrap-lines:false;"&gt;
&lt;div class="messages"&gt; 
 &lt;div class="msgOK" title="Click to close"&gt;
  OK message
 &lt;/div&gt; 
 
 &lt;div class="msgError" title="Click to close"&gt;
  Error Message
 &lt;/div&gt;
 
 &lt;div class="msgWarn" title="Click to close"&gt;
  Warning Message
 &lt;/div&gt;
 
 &lt;div class="msgInfo" title="Click to close"&gt;
  Info Message
 &lt;/div&gt;
&lt;/div&gt;
&lt;/pre&gt;

&lt;/li&gt;

&lt;li&gt;
Include alerts.jsp into any other jsp where you need alert messages

&lt;pre class="brush: html; wrap-lines:false;"&gt;
&lt;jsp:include page="include/alerts.jsp"/&gt;
&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This code however won't be too useful in a Java Web Application unless you only display the appropriate messages as needed. To do that here is an improved version of the &lt;b&gt;alerts.jsp&lt;/b&gt; file above that only displays the appropriate messages based on request or session attributes set on the server side (eg. in a servlet). You can modify it as needed based on your setup. &lt;/p&gt;

&lt;pre class="brush: html; wrap-lines:false;"&gt;

&lt;div class="messages"&gt; 
 &lt;c:if test="${not empty okMessage}"&gt;
  &lt;div class="msgOK" title="Click to close"&gt;
   ${okMessage}
  &lt;/div&gt; 
 &lt;/c:if&gt;
 
 &lt;c:if test="${not empty errorMessage}"&gt;
  &lt;div class="msgError" title="Click to close"&gt;
   ${errorMessage}
  &lt;/div&gt;
 &lt;/c:if&gt;
 
 &lt;c:if test="${not empty warningMessage}"&gt;
  &lt;div class="msgWarn" title="Click to close"&gt;
   ${warningMessage}
  &lt;/div&gt;
 &lt;/c:if&gt;
 
 &lt;c:if test="${not empty infoMessage}"&gt;
  &lt;div class="msgInfo" title="Click to close"&gt;
   ${infoMessage}
  &lt;/div&gt;
 &lt;/c:if&gt;
&lt;/div&gt;

&lt;/pre&gt;

&lt;p&gt;If you plan to use this approach don't forget to include the appropriate JSTL taglib directive: &lt;/p&gt;

&lt;pre class="brush: xml; wrap-lines:false;"&gt;
&lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
&lt;/pre&gt;

&lt;h3&gt;Hiding alerts on click with jQuery&lt;/h3&gt;

&lt;p&gt;Displaying the alerts is ok, but sometimes you want to hide them once the user has seen the message. If you are using jQuery in your application here's how to hide messages (alerts,errors,info or ok messages) by clicking on them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Save the following script in &lt;b&gt;alerts.js&lt;/b&gt;
&lt;pre class="brush: javascript; wrap-lines:false;"&gt;
function enableClickableAlerts(){
 $(".msgOK").click(function(){
    $(this).hide();
 });
 $(".msgInfo").click(function(){
    $(this).hide();
 });
 $(".msgWarn").click(function(){
    $(this).hide();
 });
 $(".msgError").click(function(){
    $(this).hide();
 });
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;2. Add the following script tag to the header element

&lt;pre class="brush: xml; wrap-lines:false;"&gt;
&lt;script src="/scripts/alerts.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
3. Add the following code to jQuery's ready() method (placed in a script tag inside the header element)
&lt;pre class="brush: javascript; wrap-lines:false;"&gt;
$(document).ready(function() 
     { 
   enableClickableAlerts();
   ...
  }
 ); 
&lt;/pre&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You can also adapt the code to be more fancy, like only display each message for 3-5 seconds and then automatically hiding it. You know better what you need for your webapp. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4368777317649012081-4754392786938336073?l=blog.idleworx.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yAAwzZ3GAgxr6W-r0cD4DF2AJTU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yAAwzZ3GAgxr6W-r0cD4DF2AJTU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yAAwzZ3GAgxr6W-r0cD4DF2AJTU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yAAwzZ3GAgxr6W-r0cD4DF2AJTU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/idleworxblog/~3/EtA16491HeA/friendly-css-error-messages-for-java.html</link><author>noreply@blogger.com (IdleWorx)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_uwTR1dSr5Co/TPKWdcoX3MI/AAAAAAAAABU/SrjxjD4QDKI/s72-c/css_alerts.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.idleworx.com/2010/11/friendly-css-error-messages-for-java.html</feedburner:origLink></item></channel></rss>

