how to enum in a if with mybatis annotation - mybatis

I have a problem to write the syntax using an enum in a if in MyBatis annotation.
#Delete("<script>DELETE FROM tb_a WHERE "
+ "<if test='context.name().equals(ALBUM)'>"
+ " album_id = #{id}"
+ "</if>"
+ "<if test='context.name().equals(VIDEOLIBRARY)'>"
+ " videolibrary_id = #{id}"
+ "</if>"
+ "</script>")
boolean delete(#Param("id") int id, #Param("context") EContext context);
Enum
public enum EContext {
ALBUM,
VIDEOLIBRARY,
IMAGE,
VIDEO,
}
the correct syntax as fare I know is like this <if test="context.name().equals('ALBUM')">
But I don't know how to write it with annotation.
I get this error message
Thanks for your help
Edited to show more about the code

name() method returns a java.lang.String and in OGNL, a string literal should be enclosed in single or double quotes.
So, the if element should be written as..
+ "<if test=\"context.name().equals('ALBUM')\">"
or
+ "<if test='context.name().equals(\"ALBUM\")'>"

Related

getting null for #PathParam using springboot

i am new in web services, am using spring-boot for creating web services, whereas, while giving the request with http://localhost:8085/user/30?name=abc, I am getting null for the id property.`
#GetMapping(value="{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getUser(#PathParam("id") Long id,
#QueryParam("name") String name){
System.out.println(" Got id by path param : "+ id + " And Got name using Query Param " +name);
return " Got id by path param : "+ id + " And Got name using Query Param " +name;
}
edited to add screenshot.
screenshot taken from Postman
Thanks in advance.
You need to use #PathVariable because you are using spring-rest not #PathParam that is a JAX-RS annotation
#GetMapping(value="{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getUser(#PathVariable("id") Long id,
#QueryParam("name") String name){
System.out.println(" Got id by path param : "+ id + " And Got name using Query Param " +name);
return " Got id by path param : "+ id + " And Got name using Query Param " +name;
}
I noticed you are mixing Jax-RS annotation with Spring annotation
Try this and it will fix your problem
#GetMapping(value="{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getUser(#PathVariable("id") Long id,
#RequestParam("name") String name){
System.out.println(" Got id by path param : "+ id + " And Got name using Query Param " +name);
return " Got id by path param : "+ id + " And Got name using Query Param " +name;
}
For the id variable you must use #PathVariable annotation and for the name parameter use #RequestParam.
Here is a full working solution:
#RestController
#RequestMapping("/user")
public class UserController {
#GetMapping("/{id}")
public String getUser(#PathVariable Long id, #RequestParam String name) {
System.out.println(" Got id by path param : " + id + " And Got name using Query Param " + name);
return " Got id by path param : " + id + " And Got name using Query Param " + name;
}
}
See here for more details.
Now when you make a request
$ curl http://localhost:8085/user/30?name=abc
you get a response:
Got id by path param : 30 And Got name using Query Param abc

Making raw SQL safe in Entity Framework

var retval = db.TestTable.SqlQuery("SELECT * FROM dbo.TestTable WHERE " + aColumn + " = '" + passedInValue + "'");
// normally when using parameters I would do something like this:
var valueParam = SqlParameter("aValue", passedInValues);
var retval = db.TestTable.SqlQuery("SELECT * FROM dbo.TestTable WHERE Column1 = #aValue", valueParam);
// NOTE: I would not do this at all. I know to use LINQ. But for this question, I'm concentrating on the issue of passing variables to a raw sql string.
But since both the column and value are "parameters" in:
var retval = db.TestTable.SqlQuery("SELECT * FROM dbo.TestTable WHERE " + aColumn + " = '" + passedInValue + "'");
, is there to prevent sql injection for both?
First: whilelist aColumn: this has to be added via string concatenation but you know what columns are in your database (or you can check using schema views).
Second: In entity framework – as you show – you can use parameters for values in the query. However, rather than creating SqlParameter instances you can pass the values and use #p0, #p1, ….
Right way to prevent SQL injection is to use SqlParameter and SqlQuery<T>:
var parameter = new SqlParameter("#title", value);
var result = context.Database.SqlQuery<Book>("SELECT * FROM Books WHERE Title LIKE #title", parameter);
http://ignoringthevoices.blogspot.ru/2013/07/sql-injection-with-entity-framework-5.html

table not created

The project executes but table is not created. My codes
{
public HelperData(Context context) {
super(context, database_name, null, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
String creat = "Create table " + Table_name + "(" + KEY_ID
+ " Integer primary key autoincrement," + KEY_FNAME + "TEXT,"
+ KEY_LNAME + "TEXT" + ");";
Log.d("Tag", "==table created" + creat);
db.execSQL(creat);
}
}
What might be the issue?
I can't see what the content of those Strings (like KEY_FNAME or KEY_LNAME) is but it appears you don't have a space between the strings that define the column names and their data types.
E.g.:
If String KEY_LNAME = "something",
KEY_LNAME + "TEXT" can result in something like "somethingTEXT" instead of "something TEXT".
If that is the case, you can either add a space to the end of the column name string (e.g. String KEY_LNAME = "something ") or add the space before the column data type (... KEY_LNAME + " TEXT" ...).
Also, look at Logcat, there may be some Exceptions being thrown.
I may be wrong, as I don't know what those strings of yours contain, but that's my guess.

Entity Framework - Table-Valued Functions - Parameter Already Exists

I am using table-valued functions with Entity Framework 5. I just received this error:
A parameter named 'EffectiveDate' already exists in the parameter collection. Parameter names must be unique in the parameter collection. Parameter name: parameter
It is being caused by me joining the calls to table-valued functions taking the same parameter.
Is this a bug/limitation with EF? Is there a workaround? Right now I am auto-generating the code (.edmx file).
It would be really nice if Microsoft would make parameter names unique, at least on a per-context basis.
I've created an issue for this here.
In the meantime, I was able to get this to work by tweaking a few functions in the .Context.tt file, so that it adds a GUID to each parameter name at runtime:
private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) {
if (typeMapper.IsComposable(edmFunction))
{
#>
[EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
<#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
{ var guid = Guid.NewGuid().ToString("N"); <#+
codeStringGenerator.WriteFunctionParameters(edmFunction, " + guid", WriteFunctionParameter);
#>
<#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
} <#+
}
else
{
#>
<#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
{ <#+
codeStringGenerator.WriteFunctionParameters(edmFunction, "", WriteFunctionParameter);
#>
<#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
} <#+
if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
{
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
}
} }
...
public void WriteFunctionParameters(EdmFunction edmFunction, string nameSuffix, Action<string, string, string, string> writeParameter)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
{
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\"" + nameSuffix + ", " + parameter.FunctionParameterName + ")";
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\"" + nameSuffix + ", typeof(" + parameter.RawClrTypeName + "))";
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
}
}
...
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
edmFunction.NamespaceName,
edmFunction.Name,
string.Join(", ", parameters.Select(p => "#" + p.EsqlParameterName + "\" + guid + \"").ToArray()),
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
}
Not a bug. Maybe a limitation or an omission. Apparently this use case has never been taken into account. EF could use auto-created parameter names, but, yeah, it just doesn't.
You'll have to resort to calling one of the functions with .AsEnumerable(). For some reason, this must be the first function in the join (as I have experienced). If you call the second function with .AsEnumerable() it is still translated to SQL and the name collision still occurs.

Template to show method name and parameter values in Eclipse

Is there any way to have a template (Java -> Editor -> Templates) in Eclipse that generate something like this
debug("methodName arg1=" + arg1 + " arg2=" + arg2 + " arg3=" + arg3);
When used in a method. For instance:
public void setImage(long rowId, long contactId, String thinggy) {
// invoking the template here, produces this:
debug("setImage rowId=" + rowId + " contactId=" + contactId + " thinggy=" + thinggy);
}
I couldn't find a way to do that with the standard template UI, maybe there exists a plugin to do this kinds of things?
This is a start:
debug("${enclosing_method_arguments}: ", ${enclosing_method_arguments});
which produces the following:
debug("arg1, arg2, arg3: ", arg1, arg2, arg3);
I haven't found a way to separate out each argument. I found this page that ran into the same problem.
For other Eclipse template stuff, look at this question.
I guess it's probably a bit too late to answer this question but maybe my answer will help someone :
System.out.println(String.format("%tH:% %s", java.util.Calendar.getInstance(), "${enclosing_package}.${enclosing_type}.${enclosing_method}(${enclosing_method_arguments})"));
String[] lArgsNames = new String("${enclosing_method_arguments}").split(", ");
Object[] lArgsValues = new Object[] {${enclosing_method_arguments}};
for (int i = 0; i < lArgsValues.length; i++) {
System.out.println("\t" + (lArgsValues[i] != null ? ("(" + lArgsValues[i].getClass().getSimpleName() + ") \"" + lArgsNames[i] + "\" = \"" + lArgsValues[i] + "\"") : "\"" + lArgsNames[i] + "\" is null"));
}
For this method :
public void foo(boolean arg){
// ...
}
the output would be:
18:43:43:076 > any.package.AnyClass.foo(arg)
(Boolean) "arg" = "true"
This code seems to be able to handle any object, primitive type and null value. And yes it's a little bit complicated for the purpose!
I've made small plugin that adds nicely formatted variable:
https://github.com/dernasherbrezon/eclipse-log-param
Eclipse doesnt provide any information about parameter type, so there is no Arrays.toString(...)
or template=
if (aLog.isDebugEnabled()) {
aLog.debug(String.format("${enclosing_method}:${enclosing_method_arguments}".replaceAll(", ", "=%s, ")+"=%s", ${enclosing_method_arguments}));
}
gives
public static void hesteFras(boolean connect, Object ged, String frans, int cykel) {
if (aLog.isDebugEnabled()) {
aLog.debug(String.format("hesteFras: connect, ged, frans, cykel".replaceAll(", ", "=%s, ") + "=%s",
connect, ged, frans, cykel));
}
which for
hesteFras(false, null, "sur", 89);
gives a log statement:
hesteFras: connect=false, ged=null, frans=sur, cykel=89
The eclipse-log-param plugin is useful to avoid having to type the logging line manually. However, it would be even nicer to have the line added automatically for all new methods.
Is this even possible? It looks like in Windows->Preferences->Code Style->Code Templates->Code there are ways to configure automatically added code like auto-generated methods ("Method body" template, which has an "Auto-generated method stub" comment). But there's no way to configure new methods which are not generated.
Furthermore, the variable formatted_method_parameters is not available when editing the template for "Method body".