MyBatis XML access to incoming array without casting from string - mybatis

In below code I get PgArray as an array of PrimaryKeys to template table, from another select query (<collection ... select='selectTemplate'/>). But the solution below seems like a little messy way of doing it. isn't there a way to access the array directly, so I wouldn't need to cast?
Hint: Having #{_parameter} doesn't work.
<select id="selectTemplate" parameterType="org.postgresql.jdbc.PgArray" resultMap="templateResultMap">
SELECT *
FROM template
WHERE template.id = ANY ('${_parameter}'::int[])
</select>

Related

MyBatis: How to map underscore result to camelcase for one specific statement only?

I have a statement in the mybatis mapper.xml file:
<select id="queryCorpAndDept" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT ORGAN_NAME, ORGAN_ID FROM PUB_ORGAN
</select>
The statement above will return a list of HashMap. The keys of the hashmap will be ORGAN_NAME, ORGAN_ID. I know MyBatis has a setting named mapUnderscoreToCamelCase to map undercase to camelcase.
But is there another way to map underscore to camelcase without defining a JAVA Bean ?
Sorry for my english.
You can use column aliases to be able to do selective camelCasing as shown below:
<select id="queryCorpAndDept" parameterType="java.util.HashMap"
resultType="java.util.HashMap">
SELECT ORGAN_NAME "organName", ORGAN_ID "organId" FROM PUB_ORGAN
</select>

How can I pull data in a controller and form for one model that is in a different model with out a foreign key relationship?

I am new to rails and haven't really done to much with data outside of the model.
I have a form that references a table controller for files. I want to add an dropdown that will display a list of projects from a project table for the user to assign a the file to a project if they want too. Assigning a project is not a requirement. The file can be unassigned to a project. I do have a project_id column in the file table for those projects assigned but it is allowed to be null and I did not build a relationship because I need to have cases where there are none.
Can someone please tell me how to do this?
When they evaluate the file, the screen posts back with a save or update button depending if it has already been saved in the database.
At the same time as the save and update pop up on the right I want to display a list box of the projects with an assign project button. If new just a list, if update either just a list because not assigned or display the selected value in the list if already assigned, while allowing them to change it from the list if desired.
In the file controller method that posts back to the UI I have this code:
#file_alias_filedata = FileAliasFiledata.all
#projects = Project.all
for update
#projects = Project.find(params[:id])
In the form I have this code:
<p> <label> Select Project to Assign:</label> <br />
<%= select_tag 'projects', (#projects.present? ? options_for_select(#projects, #selected_project) : []) %> </p>
The form runs but I get this in the dropdown box:
#<Project:0x))7ff531ab4518>
Can someone please help me figure out how to accomplish my task and why I see the strange box value?
What am I doing wrong?
Thank you for your help!
Assigning a project is not a requirement. The file can be unassigned
to a project. I do have a project_id column in the file table for
those projects assigned but it is allowed to be null
From the docs:
belongs_to(name, scope = nil, options = {}) public
Specifies a
one-to-one association with another class. This method should only be
used if this class contains the foreign key. If the other class
contains the foreign key, then you should use has_one instead. See
also ActiveRecord::Associations::ClassMethods’s overview on when to
use has_one and when to use belongs_to.
Methods will be added for retrieval and query for a single associated
object, for which this object holds an id:
association(force_reload = false)
Returns the associated object. nil is returned if none is found.
Likewise,
has_many(name, scope = nil, options = {}, &extension) public
Specifies
a one-to-many association. The following methods for retrieval and
query of collections of associated objects will be added:
collection(force_reload = false) Returns an array of all the
associated objects. An empty array is returned if none are found.
But belongs_to() and has_many() are supposed to make things more convenient for you. You certainly do not have to use them.
Next,
and why I see the strange box value? What am I doing wrong?
You see the strange value for the same reason the following two loops display different things:
class Dog
attr_reader :name
def initialize(name)
#name = name
end
end
#dogs = [
Dog.new("Sam"),
Dog.new("Betty"),
Dog.new("Pete"),
]
#dogs.each {|dog| puts dog}
#dog_names = #dogs.map {|dog| dog.name }
#dog_names.each {|dog_name| puts dog_name}
--output:--
#<Dog:0x0000010099a308>
#<Dog:0x0000010099a2b8>
#<Dog:0x0000010099a268>
Sam
Betty
Pete
You will see the same result if you do something like the following in a view:
<div>
<%= select_tag "dog", options_for_select(#dogs) %>
</div>
<div>
<%= select_tag "dog_name", options_for_select(#dog_names) %>
</div>
If you read the docs here:
http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select
...you will see several examples, which should make it clear that options_for_select() takes an argument that is:
An array of Strings.
A Hash where both the keys and values are Strings.
An enumerable that iterates over some Strings.
etc.
Do you see a pattern? It's Strings! options_for_select() needs an argument that consists of Strings. If the argument is not a collection of Strings, e.g. an array of project objects, then options_for_select() tries to convert the objects to strings by calling to_s() on the objects. And the default to_s() method is Object#to_s() which is inherited by all objects and produces a string containing the class name and the object_id.
I am also new to rails, but I think you can try using the options_from_collection_for_select method.
<%= select_tag :search_state, options_from_collection_for_select(State.find(:all, :select => :name), :name, :name) %>
Hope this help. Cause it certainly helped me.

Form select method in Kohana includes "multiple" attribute in HTML if not NULL

I'm using the form::select helper in Kohana 3.2 to generate a select input with the following code (formatted for display here):
form::select('id_plyta', $plyta, $plyta_selected,
array('style' => 'width:300px', 'class' => 'sock_depend'));
This code generates the following HTML (formatted for display here):
<select name="id_plyta" class="sock_depend" style="width:300px"
multiple="multiple">
...
</select>
The problem is that it is outputting with an extra multiple="multiple" attribute in the HTML. I don't want that to be a part of it.
If I put a NULL instead of $plyta_selected then it works fine.
How do I get rid of multiple="multiple" and why is it even there?
When you check out the list of parameters it accepts, pay attention to the third:
* #param string input name
* #param array available options
* #param mixed selected option string, or an array of selected options
* #param array html attributes
When sending the paramters to the select method of the Form class, if the third parameter is an array, the helper will automatically include the multiple="multiple" to allow it to pre-select more than one option in the drop down select.
If you only send a string value, then it will not create a multibox, will not include the multiple HTML input attribute and it will only pre-select the single value.

How to apply a method to a parameter in MyBatis

After reading about Mapper XMLs I can't help to wonder how one might go about appling some common transforms to a parameter. For example...
<select id="selectPerson" parameterType="String" resultType="hashmap">
<!-- #{name} should always be upper case and have a trailing % -->
SELECT * FROM PERSON WHERE FIRST_NAME like #{name}
</select>
After reading this and this I can make some observations.
Using SQL functions such as upper or concat or '||' or '+' to do transforms kills performance in DB2
I could always wrap the the mapper or expose the details in the service layer but that seems messy
What I want is to be able to do something like...
<select id="selectPerson" parameterType="String" resultType="hashmap">
<!-- #{name} should always be upper case and have a trailing % -->
SELECT * FROM PERSON WHERE FIRST_NAME like #{name.upperCase() + '%'}
</select>
Is something like this possible or what is the second best solution?
Update: it appears that MyBatis uses OGNL for some expression evaluation. For example, if and ${} expressions use OGNL but #{} does NOT appear to unless there is some way to trick it.
Bind
MyBatis allows for creating values from method and properties in the context using <bind/>.
Bind creates a new variable in the scope of the current statement. The OGNL statement that binds the value can use the passed in _parameter object to compute a new bound value that can then used by MyBatis to construct the prepared statement.
Example
Your example using bind:
<select id="selectPerson" parameterType="String" resultType="hashmap">
<!-- #{name} should always be upper case and have a trailing % -->
<bind name="nameStartsWith" value="_parameter.getName().upperCase() + '%'"/>
SELECT * FROM PERSON WHERE FIRST_NAME like #{nameStartsWith}
</select>
Source
MyBatis Dynamic SQL Documentation
I ran through the same problem too. But I didn't find any solution for this. So I had to preprocess the #{name} parameter from the calling function.

How to add Count of child table in EntityDataSource

I have an EntityDataSource that works to get row data from tblOrderFile as follows:
<asp:EntityDataSource ID="entityDataSourcePreorder" runat="server"
ConnectionString="name=iDBEntities"
DefaultContainerName="iDBEntities" EnableFlattening="False"
EntitySetName="tblOrderFiles"
Select="it.[pkOrderFileID], it.[fkOrderFileStatusID], it.[Filename], it.[CreateDate], it.[UserId]"
AutoGenerateWhereClause="True" EntityTypeFilter="" Where="">
I would now like to modify it to also return back the number of rows in child table tblOrderFileItem (with Entity Set Name tblOrderFileItems).
I found a way to get the Count to work by adding an Include directive as follows:
<asp:EntityDataSource ID="entityDataSourcePreorder" runat="server"
ConnectionString="name=iDBEntities"
DefaultContainerName="iDBEntities" EnableFlattening="False"
EntitySetName="tblOrderFiles" Include="tblOrderFileItems"
AutoGenerateWhereClause="True" EntityTypeFilter="" Where="" >
</asp:EntityDataSource>
but I believe this is returning the all the columns of all the rows for each Order Item. I only really want the Count and do not want to deliver the rest of the data to the web page.
I also tried simply adding it.tblOrderFileItems.Count to the Select statement but get an error saying
'Count' is not a member of 'Transient.collection[MyDBModel.tblOrderFileItem(Nullable=True,DefaultValue=)]'. To extract a property of a collection element, use a subquery to iterate over the collection.
Select="ANYELEMENT(SELECT VALUE Count(c.ItemId) FROM it.tblOrderFileItems AS c) as ChildCount"