Skip to content

includeColumns element for select #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

includeColumns element for select #136

wants to merge 1 commit into from

Conversation

litpho
Copy link

@litpho litpho commented Jan 27, 2014

Collections and assocations have the option to specify a columnPrefix, making resultMaps easier to reuse.
However, column lists such as the Base_Column_List generated by Mybatis Generator don't have that option.

I created a separate includeColumns element which takes a tableAlias and an optional columnAliasPrefix. I chose not to fold this functionality into the generic include element, because it's only useful for very specific cases.

If you have the following column list:

<sql> a, b, c</sql>

and you include it in the select statement as follows:

<select>
select
<includeColumns tableAlias="comment"/>
from tab comment
</select>

it will render (on one line to save space):

select comment.a as comment_a, comment.b as comment_b, comment.c as comment_c

with an optional columnAliasPrefix "c" it will render:

select comment.a as c_a, comment.b as c_b, comment.c as c_c

This functionality will make reuse of column lists much easier, especially when working with associations or when linking the same table more than once in the same query.

@harawata
Copy link
Member

Thank you for the suggestion!
But, as you mentioned, it would work only with a very simple column list.
Even a simple sql function like lower() could break it.

You should be able to achieve what you want by using the bind tag.
Please see the example below.

<sql id="cols">
${tbl}a as ${prefix}a, 
${tbl}b as ${prefix}b, 
${tbl}c as ${prefix}c
</sql>

<select>
<bind name="tbl" value="'comment.'" />
<bind name="prefix" value="'comment_'" />
select
<include refid="cols"/>
from tab comment
</select>

It's much more flexible, isn't it?

Regards,
Iwao

@litpho
Copy link
Author

litpho commented Jan 27, 2014

Thank you for your remark. I hadn't considered using the tag.

However, mapping all columns in the generated resultMap to the generated table objects is (I think) so common that I think it would warrant its own simple syntax.

Also, if I have more than one generated column list (because I map more than one table object), they will both be generated with ${tbl} and ${col} (which makes it impossible to set different values). We could generate a different tbl and col per table, but that doesn't solve the issue where you'd want to link the same table object more than once.

Greetings,
Jasper

@harawata
Copy link
Member

Hi Jasper,
Sorry about the late response!

if I have more than one generated column list (because I map more than one table object), they will both be generated with ${tbl} and ${col} (which makes it impossible to set different values).

I presumed that the column lists are generated using MyBatis Generator with a custom plugin, is that correct?
Then it would be possible to customize the plugin to generate unique table/alias variable names for each table (e.g. ${commentTbl}, ${commentAlias}, ${blogTbl}, ${blogAlias}, etc.).

that doesn't solve the issue where you'd want to link the same table object more than once.

True, but this use case would not be so common.

Adding a new tag is a big deal to MyBatis and the use case seems to be too limited as I already wrote.
And another reason I am hesitant to merge this PR is that it tries to auto-detect column names from a plain text (i.e. without placeholders like #{} or ${}) and that is something hardly be in the core implementation of MyBatis, in my opinion.
But other devs might disagree, so I will keep it open for further discussions.

And thank you again for your time!
Iwao

@mnesarco
Copy link
Member

Hi Guys,

I am not sure if this can help, but if you use mybatis-velocity you can
define your own directives. So you can do whatever you need.

Cheers,

Frank.

On Wed, Jan 29, 2014 at 8:20 PM, Iwao AVE! [email protected] wrote:

Hi Jasper,
Sorry about the late response!

if I have more than one generated column list (because I map more than one
table object), they will both be generated with ${tbl} and ${col} (which
makes it impossible to set different values).

I presumed that the column lists are generated using MyBatis Generator
with a custom plugin, is that correct?
Then it would be possible to customize the plugin to generate unique
table/alias variable names for each table (e.g. ${commentTbl},
${commentAlias}, ${blogTbl}, ${blogAlias}, etc.).

that doesn't solve the issue where you'd want to link the same table
object more than once.

True, but this use case would not be so common.

Adding a new tag is a big deal to MyBatis and the use case seems to be too
limited as I already wrote.
And another reason I am hesitant to merge this PR is that it tries to
auto-detect column names from a plain text (i.e. without placeholders
like #{} or ${}) and that is something hardly be in the core implementation
of MyBatis, in my opinion.
But other devs might disagree, so I will keep it open for further
discussions.

And thank you again for your time!
Iwao

Reply to this email directly or view it on GitHubhttps://github.com//pull/136#issuecomment-33651511
.

Frank D. Martínez M.

@harawata
Copy link
Member

Thank you @mnesarco for the hint!

@litpho, Have you tried Frank's idea?
I could finally test it myself and put the custom directive implementation to the Gist.
https://gist.github.com/harawata/9570954

The directive name is columnalias and it takes two parameters (tableAlias and prefix).
So, the statement would look like the below.

<sql id="cols">a, b, c</sql>

<select lang="velocity">
select
#columnalias("comment", "comment_")
<include refid="cols" />
#end
from tab comment
</select>

And it generates the following SQL:

select
comment.a AS comment_a, comment.b AS comment_b, comment.c AS comment_c
from tab comment

To use it,

  1. Add mybatis-velocity.jar to your project.
  2. Add the ColumnAliasDirective class to your project.
  3. Create a new file mybatis-velocity.properties with the following line and place it in the classpath root (adjust the package names if necessary). userdirective=org.mybatis.scripting.velocity.use.ColumnAliasDirective

Please see the mybatis-velocity doc for the details:
http://mybatis.github.io/velocity-scripting/

Let us know what you think!

Regards,
Iwao

@litpho
Copy link
Author

litpho commented Mar 17, 2014

Thank you all for your thoughts on this matter and my apologies for not getting back sooner.

I think the solution @harawata came up with will serve our needs very well, so as far as I'm concerned this pull request can be closed.

Once again, thanks for considering and I hope to be able to support Mybatis in the future again.

Greetings,
Jasper de Vries

@litpho litpho closed this Mar 17, 2014
@harawata
Copy link
Member

@litpho Thank you very much for the feedback! (and sorry for a late reply)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improve a feature or add a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants