两个人一起翘课啊
真是青春啊
-----《虞美人盛开的山坡》
1.持久层提示未绑定参数异常
org.apache.ibatis.binding.BindingException: Parameter 'username' not found
场景描述:在与别人对接的时候,之前我习惯根据对方发来的json串来建立pojo,然后直接用这个实体类(也就是Bean对象)来接收对方发来的数据,直接把数据库查询到的数据return给对方。有一次我需要拿其中两个条件传入持久层,也就是多参传入,但是后台一直提示如上属性未绑定,明明实体类里我加上了,原因是因为如果只是传入一个实体类到持久层完全没有问题,但对于多参传入,mybatis不会自动帮你匹配,需要在Dao层接口处加@Param("username"),
这个@Param不是引用spring的,而是org.apache.ibatis包下的,注意下;
比如:
User selectUsername(@Param("username")String username,
@Param("password")String password);
然后持久层是这样的
<select id=" selectUser" resultMap="BaseResultMap">
select * from tableName where user_name = #{username} and user_password=#{password}
</select>
那如果我写成这样呢?
User selectUsername(@Param("name")String username,@Param("pwd")String password);
那么持久层则为:
<select id=" selectUser" resultMap="BaseResultMap">
select * from tableName where user_name = #{name} and user_password=#{pwd}
</select>
对于单一属性的传入,注意:采用#{}的方式把@Param注解括号内的参数进行引用(括号内参数对应的是形参如 name对应的是username)
2.在MyBatis中的特殊符号对应写法
常用的如下(其中的分号不可缺少)
第一种写法:
原符号 < <= > >= & ' "
替换符号 < <= > >= & ' "
例如:sql如下:
create_date_time >= #{startTime} and create_date_time <= #{endTime}
第二种写法
大于等于 小于等于
<![CDATA[ >= ]]> <![CDATA[ <= ]]>
例如:sql如下:
create_date_time <![CDATA[ >= ]]> #{startTime} and create_date_time <![CDATA[ <= ]]> #{endTime}
3.java.lang.IllegalStateException: Failed to load property source from location ‘classpath:/application.yml
说明是application.yml文件与项目的编码格式不匹配
yml文件的编码格式在右下角,
项目的编码格式在File-Settings,
两边编码一致后就不会报错了。
4.关于一个事务里插入数据后如何立即引用的问题
一次工作中,在上一行代码中执行了插入的java代码,其中的userId在数据库是使用序列来生成,然后立即引用该userId来给下一行代码查询使用的业务问题处理方法。
场景一:简单insert
keyProperty对应插入实体类的某一个属性名字,不是库表的字段名。
service层:
public void saveTempInfo(TempItem tempItem){
testMapper.addTempInfo(tempItem);
}
xml层:
<insert id="addTempInfo" parameterType="...">
<selectKey resultType"string" keyProperty="itemId" order="BEFORE">
select SEQ_TEST_INTO.nextval from dual
<selectKey>
insert into tableName(...) values(...)
</insert>
场景二:Insert后立即获取使用
service层:
TestInfo model = new TestInfo();
model.set();
...
sysUserMapper.insertUserInfo(model);
String userId = model.getUserId();
xml:
<insert id="insertUserInfo">
<selectKey resultType="string" keyProperty="userId" order="BEFORE">
select ...nextval from dual
<selectKey>
insert...
</insert>
这里执行insert后需要立即获取到新生成的序列值userId来给后面代码使用,直接继续用该类的get方法拿即可,相当于执行了insert后将生成的usreId立即赋值给了model这个类,这种业务也是比较常见的。
5.merge循环插入
对于一个集合,如果不用java循环插入,可以直接用merge函数,此处不讨论数据库压力,这个方式在实际工作中很常见
集合名:
List<TestInfo> params;
service层:
int result = testLineMapper.updateTestInfo(params);
int updateTestInfo(List<TestInfo> params);
<update id="updateTestInfo" parameterType="...TestInfo">
merge into TestName A1
using
(
<foreach collection="list" index="index" item="item" separator="union all">
select
#{item.orgNo} as orgNo,
#{item.orgName} as orgName
from dual
</foreach>
) A2
on (A1.org_No=A2.orgNo and ...)
when matched then
update set
A1.org_No = A2.orgNo,
A1.orgName = A2.orgName
when not matched then
insert(org_No,orgName)values(A2.orgNo,A2.orgName)
</update>