本文核心内容:1⃣️:MyBatis实现Sql复用、通用查询、高效修改、模糊查询、插入数据返回记录ID。2⃣️MyBatis的批量操作如批量删除、批量插入、批量更新。3⃣️:MyBatis执行DDL语言。
一:高效的、动态的SQL
1⃣️:共性SQL【Sql的复用】
2⃣️:通用查询
当where元素里面的条件成立时,才会加入where这个SQL关键字组装到SQL里,否则就不加入。
3⃣️:高效修改
细节:set元素遇到了逗号,它会把对应的逗号去掉。
4⃣️:模糊查询
想解决模糊查询
首先分清MyBatis中#{}与${}的差别。#{}是预编译处理,${}是字符串替换。
#{}采用站位符的方式绑定数据
${}采用字符拼接的方式绑定数据(这种不能防止SQL注入)
补充:bind元素【18年-6月-10日】
bind元素的作用是通过OGNL表达式去自定义一个上下文变量,这样更方便使用。有了bind元素,就不必使用数据库的语言【屏蔽数据库模糊查询的差异,如oracle和MySql】,而是使用MyBatis的动态SQL完成模糊查询。
MyBatis发送的sql语句:
Mapper源码
<select id="selectByKeyWord" resultType="Users">
<bind name="keyWord" value="'%'+ keyWord + '%'"/>
select * from users where
name like #{keyWord} or usersid like #{keyWord} or address like #{keyWord}
</select>
同时bind元素还支持多参。即一个SQL语句中可以有多个bind元素。
5⃣️插入数据返回记录ID 【补充 2018年9月7日 14:34:00】
<!--增添新用户 并返回ID-->
<insert id="addUser" parameterType="User" keyProperty="userId" useGeneratedKeys="true">
insert into t_user (user_account,user_pwd,user_name,user_salt)
values (#{userAccount},#{userPwd},#{userName},#{userSalt})
</insert>
数据库的主键Id是自增的,另外需要设置的两个属性为:
---------------------
keyProperty="userID" ->对应Java实体类的userID属性
useGeneratedKeys="true"
---------------------
我们在插入数据之后,就可以得到插入数据之后的对象,然后通过该对象获取该对象的id。
我们来写一个测试方法测试一下
@Test
public void method()throws Exception{
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/application-context.xml");
UserDao userDao=(UserDao)ctx.getBean("userDao");
User user = new User(null, "123456@qq.com", "123456", "Sugar", null);
Integer number = userDao.addUser(user);
if (number>0) {
System.out.println(user.getUserId());
}else {
System.out.println("插入失败!!!");
}
}
如果插入数据成功的话,则可以找到数据库中对应的key。
二:批量操作
6⃣️:批量删除
批量删除有两种方式:
1:这一种效率低下,但是实现简单。
for(String id:list){
deleteById(id);
}
2:foreach遍历
7⃣️:批量插入基于长SQL 补充【18年7月8日 10:45】
Dao接口方法
Integer insertBatchMaster(@Param("masters") List<Master> masters);
Mapper源码
<!--长Sql解决普通批量插入 1w条数据1秒,10w条数据跑不动-->
<insert id="insertBatchMaster" >
insert into master (master_Name,master_Summary)
<foreach collection="masters" item="master" open="values"
separator="," close=";">
(#{master.masterName},#{master.masterSummary})
</foreach>
</insert>
测试方法【基于读取EasyPOI读取 Excel表格模拟批量数据,实际就两条】
@Test
public void methodInput()throws Exception{
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
List<Master> list= ExcelImportUtil.importExcel(new File("D:/test.xlsx"),
Master.class,params);
ApplicationContext ctx=new ClassPathXmlApplicationContext("appliation-context.xml");
MasterService masterService=(MasterService)ctx.getBean("masterServiceImpl");
Integer number=masterService.addBatchMaster(list);
System.out.println(number);
}
查看运行日志可以看出MyBatis发送的Sql语句。
8⃣️:批量更新
1:用for循环通过循环传过来的参数集合,循环出N条sql语句
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update table
<set>
column=${item.name}
</set>
where id = ${item.id}
</foreach>
</update>
Mybatis映射文件中的sql语句默认是不支持以" ; " 结尾的,也就是不支持多条sql语句的执行。所以需要在连接mysql的url上加 &allowMultiQueries=true 这个才可以执行。
2:mysql数据库中CASE WHEN语句。
<update id="updateBatch" parameterType="java.util.List">
update table
<trim prefix="set" suffixOverrides=",">
<trim prefix="column =case(" suffix="end),">
<foreach collection="list" item="item">
<if test="item.name != null">
when id=#{item.id} then #{item.name}
</if>
</foreach>
</trim>
</trim>
<where>
id in
<foreach collection="list" separator="," opent="(" close=")" item="item">
#{item.id}
</foreach>
</where>
</update>
9⃣️:执行DDL语言 补充【20年1月12日 23:45】
DDL使用update即可
<update id="alterTable">
alter table ${tableName} allocate extent
</update>
<update id="truncateTable">
truncate table ${tableName}
</update>
<update id="createNewTableAndInsertData">
create table ${newTableName} as select * from ${originalTableName}
</update>