- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习如何使用 MyBatis .老实说,我非常喜欢这个框架。它易于使用,我对它很满意,因为我可以用它来使用我的 sql 命令:) 我使用 MyBatis 3.4.2 和 PostgreSQL 数据库。
例如,我喜欢在使用 @SelectKey
插入之前执行查询是多么容易注解。如果我在接口(interface)方法之前添加一些注释,数据映射就像这样:@Results({ @Result(property = "javaField", column = "database_field", javaType = TypeHandler.class)
.
我不喜欢的(希望您能引导我走向正确的方向)如下:
(问题 1) 我有一些查询允许我使用空值和正常值,而无需任何额外的“if”java 语句来检查变量是否包含空值。它们看起来像这样:
SELECT * FROM table
WHERE key_name = ? AND ((? IS NULL AND user_id IS NULL) OR User_id = ?)
对于 JDBC,我需要执行以下操作:
stmt = connection.prepareStatement(query);
stmt.setString(1, "key");
stmt.setString(2, userId);
stmt.setString(3, userId);
如您所见,我需要传递两次 userId,因为这是 JDBC 的工作方式。老实说,我的期望是下面的代码可以与 MyBatis 一起使用,但不幸的是它不起作用。第三个参数还需要定义。
不知是否可以将此功能添加到MyBatis中。如果 MyBatis 可以自动绑定(bind)两次 userId 应该没问题,像这样:
@Select("SELECT * FROM table key_name = #{key} and ((#{userId} is null and user_id is null) OR user_id = #{userId})
SomeClass findByKeyAndUserId(String key, Long userId);
我实际做的解决方法如下。我讨厌它,因为它很棘手并且需要额外的 java“if”语句:
@Select("SELECT * FROM table WHERE key_name = #{key} AND COALESCE(user_id, -1) = #{userId}")
SomeClass findByKeyAndUserId(String key, Long userId);
userId = (userId == null) ? -1 : userId;
SomeClass abc = mapper.findByKeyAndUserId(key, userId);
我不知道用 MyBatis 管理这种情况的最佳实践是什么。请指导我。
(问题 2) @Select
情况下的映射.在映射具有相同结果类型的查询结果时,有什么方法可以避免重复代码?
第一个查询:
@Select("SELECT * FROM table WHERE ...")
@Results({
@Result(property = "key", column = "key_name", javaType = String.class),
@Result(property = "value", column = "key_value", javaType = String.class),
@Result(property = "userId", column = "user_id", javaType = Long.class),
@Result(property = "interval", column = "interval", javaType = Long.class),
@Result(property = "description", column = "description", javaType = String.class),
@Result(property = "status", column = "status", typeHandler = StatusTypeHandler.class)
})
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
第二个查询:
@Select("SELECT * FROM table WHERE <different conditions then before>")
@Results({
<I need to add here the exact same code then before in query 1>
})
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
我能以某种方式重用与映射相关的代码吗?我需要添加映射,因为我对状态字段使用了特殊类型的处理程序。我使用基于注释的配置。
(第三期) @Param
注解我在文档中看不到任何关于 @Param
的内容注解。很难弄清楚为什么我的 java 参数没有正确绑定(bind)。最后我意识到 @Param
我的代码中缺少注释。为什么官方文档中没有提到这一点?我做错了事@Param
没必要用?
该代码工作正常:
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
这不起作用:
SomeClass findByKeyAndUserId(String key, Long userId);
更新(第 1 期)
我的第一个想法与 @blackwizard 提到的类似:“Mybatis 确实通过名称绑定(bind)参数,然后一次、两次、N 次,可能会被引用,它起作用了。 "
但这实际上并不能正常工作。如果 userId 不为空,它会起作用。如果它为空,我会得到一个从数据库返回的异常。我猜想 MyBatis 以错误的方式绑定(bind)了 null 值。也许这是一个错误。我不知道:(
异常(exception):
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $2
### The error may exist in com/.../dao/TableDao.java (best guess)
### The error may involve ....dao.Table.findByKeyAndUserId-Inline
### The error occurred while setting parameters
### SQL: SELECT * FROM table WHERE key_name = ? AND (? IS NULL AND user_id IS NULL) OR user_id = ? AND status = 1
### Cause: org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $2
最后我找到了三种不同的解决方案。
(问题1:解决方案1)
我遵循了@blackwizard 提到的内容,我能够移动条件 userId = (userId == null) ? -1 : userId
从java到MyBatis级别。而且还不错!正确的语法是:<if test='userId==null'><bind name='userId' value='-1'/></if>
.
(问题 1:解决方案 2)我回来的原因could not determine data type of parameter $2
来自 postgres 的错误是因为在 null 值的情况下,JDBC 驱动程序无法确定参数的类型。因此,让我们手动定义它。
@Select("SELECT * FROM table "
+ "WHERE key_name = #{key} AND ((#{userId}::BIGINT IS NULL AND user_id IS NULL) OR user_id = #{userId})")
})
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
(问题 1:解决方案 3)第二个解决方案取决于 PortgreSQL。以下解决方案完全独立于数据库。感谢@blackwizard 的精彩评论。
@Select("SELECT * FROM table "
+ "WHERE key_name = #{key} AND ((#{userId, jdbcType=BIGINT} IS NULL AND user_id IS NULL) OR user_id = #{userId})")
})
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
我个人更喜欢方案 3。它包含的附加代码较少。
最佳答案
问题 1:
命名参数:
@Select("SELECT * FROM table key_name = #{key} and ((#{userId} is null and user_id is null) OR user_id = #{userId}")
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
Mybatis 确实是按名称绑定(bind)参数,然后一次,两次,N 次,可能会被引用,就可以了。
您可以在 Mybatis 中执行 if:使用 XML 标记,虽然它并不是真的更好......无论如何,这是一个很好的技巧,您可能有一天会为其他目的重用。要在注释值中使用 XML 标记,该值必须嵌入到 <script>
中标记恰好位于字符串的开头和结尾。
@Select({"<script>",
"<if 'userId==null'><bind name='userId' value='1'/></if>",
"SELECT * FROM table WHERE key_name = #{key} ",
"AND COALESCE(user_id, -1) = #{userId}",
"</script>"})
SomeClass findByKeyAndUserId(@Param("key") String key, @Param("userId") Long userId);
您也可以使用 typeHandler 设置默认值,只需将其与参数一起使用:#{userId, typeHandler=CustomDefaultValueTypeHandler}
Edit: reply to additional question: 如果你想允许传递 null 值而不是处理默认值替换那么你必须给 Mybatis 一些关于假定的绑定(bind)参数类型的提示,因为它无法解析null 的实际类型,因为它不知道/看不到 Mapper 接口(interface)中的变量声明。所以:#{userId, javaType=int,jdbcType=NUMERIC}
.这两个属性中只有一个可能就足够了。
Like the rest of MyBatis, the javaType can almost always be determined from the parameter object, unless that object is a HashMap. Then the javaType should be specified to ensure the correct TypeHandler is used.
NOTE The JDBC Type is required by JDBC for all nullable columns, if null is passed as a value. You can investigate this yourself by reading the JavaDocs for the PreparedStatement.setNull() method.
问题 2:您绝对不能重用/相互化您在注解中定义的内容。这不是因为Mybatis,而是注解。您必须在使用 @ResultMap 引用它们的 XML 中定义结果映射。 Documentation状态:
ResultMap Method N/A This annotation is used to provide the id of a <resultMap> element in an XML mapper to a @Select or @SelectProvider annotation. This allows annotated selects to reuse resultmaps that are defined in XML. This annotation will override any @Results or @ConstructorArgs annotation if both are specified on an annotated select.
问题 3:我已经知道了 answered in your other question , @Param 注解具有将方便的参数列表转换为映射的效果,例如:
Map<String, Object> params = new HashMap<String, Object>();
params.put("key", key);
params.put("userId", userId);
我同意 Mybatis 文档可以做得更好,您会找到更多资源,例如 here .
然而,Mybatis documentation声明以下关于@Param注解
@Param Parameter N/A If your mapper method takes multiple parameters, this annotation can be applied to a mapper method parameter to give each of them a name. Otherwise, multiple parameters will be named by their position prefixed with "param" (not including any RowBounds parameters). For example #{param1}, #{param2} etc. is the default. With @Param("person"), the parameter would be named
#{person}.
关于java - 使用 MyBatis 映射输入和输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42350984/
我有一个测试即将进行,我想澄清两个有关参数的问题。 在我的笔记中指出,将参数传递给函数的推荐方法是使用“按引用传递” const type& x; // for "in" parameters
当我通过 OMG 2.5(Beta)推广的 UML 规范阅读以下概念时: in: Indicates that Parameter values are passed in by the caller
我试图在用户按下 Enter 时触发一个函数。我将此输入设置为只读的原因是限制用户在填充值后修改输入中的值。 该值来自将在点击属性中触发的弹出窗口。问题是 keyup.enter 没有触发该输入。 代
我在jQuery中使用模式弹出窗口控件,该弹出窗口具有由jQuery Tokenize输入插件提供动力的输入文本。问题是,当我在模式弹出文本框中键入内容时, token 化插件的搜索结果显示为隐藏在弹
我有一个问题。当我选中复选框时,系统工作正常,总值发生变化,但一旦我修改文本输入,它就会变为 0。我需要将此文本框输入排除在更改值之外。 这是 html: $15000 $
我正在努力让它发挥作用,但还是有些不对劲。 我想用 CSS 设置提交按钮的样式以匹配我已有的按钮。 风格: input[type="button"], input[type="submit"], b
import java.util.*;; public class selection { Scanner in=new Scanner(System.in); private
这可能是一个非常菜鸟的问题。假设我有一个带宽限制为 100MB/s 的网卡,那么输入/输出带宽是否有可能达到该限制 同时 ?或者我会在任何时候遇到这个不等式:in bandwidth + out ba
看着这个问题,Fill immutable map with for loop upon creation ,我很好奇是什么this表示在 Map(1 -> this) . scala> Map(1
我有这样的东西 一个 乙 问? 是或否 数字 数字或零 我想做的是: 如果 B1 = “Y”,则让用户在 B2 中输入一个数字。 如果 B1 = “N”,则将 B2 中的值更改为零,并且不允许用户在
我有一个包含许多列的表,我想添加 input标题单元格内的字段,但我希望输入适合根据正文内容的宽度。 这是没有 input 的样子领域: 这就是 input 的样子领域: 可以看出,像“index”和
关于为 FTP 客户端设置传出和传入文件夹,您遵循哪些最佳实践(如果有)?我们通常使用“outgoing”和“incoming”,但无论你如何表述方向,它都可以有两种解释方式,具体取决于名称相对于哪一
我正在尝试“求解”给定 d 的 Pell 方程:x^2 - d * y^2 = 1,或者至少我想得到最小的 x > 0 来求解方程。到目前为止,一切都很好。这是我的 Haskell 代码 minX :
我是VS Code的新手,可以使用Ctrl + Enter将代码运行到python交互式窗口中。我希望光标自动移动到下一行,因此我可以逐行浏览代码。 能做到吗? 最佳答案 如this blog pos
我正在创建一个 bool 值矩阵/二维数组,并且我想为 dategrid 推断一种不仅仅是“ANY”的类型。 let yearRange = [2000,2001,2002,2003,2004]; l
我有两个排序的列表,例如 a = [1, 4, 7, 8] b = [1, 2, 3, 4, 5, 6] 我想知道a中的每个项目是否在b中。对于上面的示例,我想找到 a_in_b = [True, T
菜鸟警报 这很奇怪 - 当我编写以下代码时,尝试在 AngularJS 中创建自定义指令: myModule.directive('myTab', function(){ console.lo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
假设我正在使用 gdscript 静态类型,并且对于一个函数参数,我事先不知道我会得到什么。这就是 python 中 typing.Any 的作用。如何使用 gdscript 做到这一点? 似乎 Va
我使用 dropzone 上传多个图像,并且工作正常,直到我想为每个图像插入品牌和网址。 我遇到的唯一问题是,当我要从输入字段获取值时,我会从服务器获取来自字段(品牌、网址)的未定义值,但如果我使用静
我是一名优秀的程序员,十分优秀!