You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-java@ibatis.apache.org by Collin Peters <ca...@gmail.com> on 2007/07/05 02:54:28 UTC

Re: I18N best practices with iBatis

On 6/29/07, Larry Meadors <lm...@apache.org> wrote:
> So you have a field for each locale?

Yes, a column for each locale in the i18n table

> I'd think it would be easier to if that were a compound key instead:
>
> SELECT a.activity_id, i.name as name
> FROM  activities a
> JOIN  i18n i ON (a.name_i18n_id = i.i18n_id and i.i18n_locale = #locale#)
>
> But.. I guess you'd still have to pass it to each query...

Yup, same question for iBatis

> How about this - if you don't have a ton of locales to support, you
> could do this:
>
> SELECT a.activity_id, i.${locale} as name
> FROM  activities a
> JOIN  i18n i ON (a.name_i18n_id = i.i18n_id)
>
> Then pass in the locale when you create the sqlmap client - each
> locale would have it's own sql map client that you could put in a Map,
> then put on the thread (use a ThreadLocale) and get from there when
> needed. That could be a pretty clean solution if done well.

Can you expand on this idea a bit?  I'm not sure what you mean with
the Thread idea.  In the end all I want is a way to abstract having to
send the locale as a variable to *every* single call in my iBatis
code.

Re: I18N best practices with iBatis

Posted by Larry Meadors <lm...@apache.org>.
OK, so here's what I'd do.

Initialize one sqlmapclient instance per locale, pass in the locale as
a property when you initialize it, and use the property notation
${locale} in your sql maps to substitute the value when the sql map is
created.

Create a ThreadLocalSqlMapFactory:
===
public class ThreadLocalSqlMapFactory {
	private static ThreadLocal<SqlMapClient> threadLocal = new
ThreadLocal<SqlMapClient>();
	public static SqlMapClient getClient(){
		return threadLocal.get();
	}
	public static void setClient(SqlMapClient client){
		threadLocal.set(client);
	}
}
===

Create a Filter that looks at the current user's session, if there is
no locale there, set it to the default. If there is a locale there,
get it. In either case, at this point the user's session has a locale
on it. Use that to look up the sqlmapclient for that locale and set it
on the ThreadLocalSqlMapFactory (above). Call the filter chain in a
try block, and in the finally, set the ThreadLocalSqlMapFactory's
SqlMapClient property to null.

Now, anywhere in your code that you need a SqlMapClient, you can call
the static method to get the one that is stored on the current thread.

You could probably use a proxy to make it even more transparent (and I
think you could even plug it in with Spring), but you'd have to hire
me for a few hours to get me to write that code for you.

Email me off-list if you are interested in doing that. :-D

Larry


On 7/5/07, Collin Peters <ca...@gmail.com> wrote:
> web app.  Frontend is built in Flex.
>
> On 7/5/07, Larry Meadors <lm...@apache.org> wrote:
> > Is this a web app or a desktop app?
> >
> > Larry
> >
> >
> > On 7/4/07, Collin Peters <ca...@gmail.com> wrote:
> > > On 6/29/07, Larry Meadors <lm...@apache.org> wrote:
> > > > So you have a field for each locale?
> > >
> > > Yes, a column for each locale in the i18n table
> > >
> > > > I'd think it would be easier to if that were a compound key instead:
> > > >
> > > > SELECT a.activity_id, i.name as name
> > > > FROM  activities a
> > > > JOIN  i18n i ON (a.name_i18n_id = i.i18n_id and i.i18n_locale = #locale#)
> > > >
> > > > But.. I guess you'd still have to pass it to each query...
> > >
> > > Yup, same question for iBatis
> > >
> > > > How about this - if you don't have a ton of locales to support, you
> > > > could do this:
> > > >
> > > > SELECT a.activity_id, i.${locale} as name
> > > > FROM  activities a
> > > > JOIN  i18n i ON (a.name_i18n_id = i.i18n_id)
> > > >
> > > > Then pass in the locale when you create the sqlmap client - each
> > > > locale would have it's own sql map client that you could put in a Map,
> > > > then put on the thread (use a ThreadLocale) and get from there when
> > > > needed. That could be a pretty clean solution if done well.
> > >
> > > Can you expand on this idea a bit?  I'm not sure what you mean with
> > > the Thread idea.  In the end all I want is a way to abstract having to
> > > send the locale as a variable to *every* single call in my iBatis
> > > code.
> > >
> >
>

Re: I18N best practices with iBatis

Posted by Collin Peters <ca...@gmail.com>.
web app.  Frontend is built in Flex.

On 7/5/07, Larry Meadors <lm...@apache.org> wrote:
> Is this a web app or a desktop app?
>
> Larry
>
>
> On 7/4/07, Collin Peters <ca...@gmail.com> wrote:
> > On 6/29/07, Larry Meadors <lm...@apache.org> wrote:
> > > So you have a field for each locale?
> >
> > Yes, a column for each locale in the i18n table
> >
> > > I'd think it would be easier to if that were a compound key instead:
> > >
> > > SELECT a.activity_id, i.name as name
> > > FROM  activities a
> > > JOIN  i18n i ON (a.name_i18n_id = i.i18n_id and i.i18n_locale = #locale#)
> > >
> > > But.. I guess you'd still have to pass it to each query...
> >
> > Yup, same question for iBatis
> >
> > > How about this - if you don't have a ton of locales to support, you
> > > could do this:
> > >
> > > SELECT a.activity_id, i.${locale} as name
> > > FROM  activities a
> > > JOIN  i18n i ON (a.name_i18n_id = i.i18n_id)
> > >
> > > Then pass in the locale when you create the sqlmap client - each
> > > locale would have it's own sql map client that you could put in a Map,
> > > then put on the thread (use a ThreadLocale) and get from there when
> > > needed. That could be a pretty clean solution if done well.
> >
> > Can you expand on this idea a bit?  I'm not sure what you mean with
> > the Thread idea.  In the end all I want is a way to abstract having to
> > send the locale as a variable to *every* single call in my iBatis
> > code.
> >
>

Re: I18N best practices with iBatis

Posted by Larry Meadors <lm...@apache.org>.
Is this a web app or a desktop app?

Larry


On 7/4/07, Collin Peters <ca...@gmail.com> wrote:
> On 6/29/07, Larry Meadors <lm...@apache.org> wrote:
> > So you have a field for each locale?
>
> Yes, a column for each locale in the i18n table
>
> > I'd think it would be easier to if that were a compound key instead:
> >
> > SELECT a.activity_id, i.name as name
> > FROM  activities a
> > JOIN  i18n i ON (a.name_i18n_id = i.i18n_id and i.i18n_locale = #locale#)
> >
> > But.. I guess you'd still have to pass it to each query...
>
> Yup, same question for iBatis
>
> > How about this - if you don't have a ton of locales to support, you
> > could do this:
> >
> > SELECT a.activity_id, i.${locale} as name
> > FROM  activities a
> > JOIN  i18n i ON (a.name_i18n_id = i.i18n_id)
> >
> > Then pass in the locale when you create the sqlmap client - each
> > locale would have it's own sql map client that you could put in a Map,
> > then put on the thread (use a ThreadLocale) and get from there when
> > needed. That could be a pretty clean solution if done well.
>
> Can you expand on this idea a bit?  I'm not sure what you mean with
> the Thread idea.  In the end all I want is a way to abstract having to
> send the locale as a variable to *every* single call in my iBatis
> code.
>