Mybatis3
1.模糊查询的用法
mysql中常用条件连接符
-- 查询条件
-- 条件连接符 and or in
-- < > <= >= != <>
-- BETWEEN '2024-11-01 00:00:00' and '2024-11-02 00:00:00'
-- like 模糊匹配符 _ %
模糊查询在业务场景中非常常用
select * from user
where username like CONCAT('%','老','%')
mybatis映射文件
<select id="listUser" resultMap="UserBaseMap">
select * from user
where username like CONCAT('%',#{username},'%')
</select>
2.排序用法
排序时 需要拼语法结构 不能用#{} 需要用${} 做语法拼接
@Test
public void listUserBySortTest(){
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
//List<User> users = mapper.listUserBySort("desc");
List<User> users = mapper.listUserBySort("asc");
System.out.println(JSON.toJSONString(users));
MyBatisHealper.backAndSaveSqlSession(sqlSession);
}
<select id="listUserBySort" resultMap="UserBaseMap">
select * from user
order by balance ${sort}
</select>
#{} 传参使用
${} 拼语法使用 没有使用占位符(不要让用户自己输入,可能会SQL注入)
3.sql标签公用字段标签
查询数据时 不要*(做全表扫描 查询较慢) 可读性比较差 会把需要的字段标记出来
标记公共字段
<!-- sql标签 公用sql语句部分 一般用来放查询的字段 -->
<sql id="UserFileds">
id,username,age,`password`,image,balance,create_time,update_time,rid,deptno
</sql>
查询时引用公共字段
<select id="listUser" resultMap="UserBaseMap">
select
<include refid="UserFileds"></include>
from user
where username like CONCAT('%',#{username},'%')
</select>
4.动态sql
通过java代码根据不同的查询情况 拼接出不同的sql语句
mybats提供了动态sql标签 通过标签配置 生成对应动态sql语句
1.查询场景
1.1动态查询条件 根据用户选填条件不同 生成不同的条件语句
<select id="listUserByCondition" resultMap="UserBaseMap">
select
<include refid="UserFileds"></include>
from user
<where>
<if test="username!=null and username!=''">
and username like CONCAT('%',#{username},'%')
</if>
<if test="deptno!=null">
and deptno = #{deptno}
</if>
<if test ="age!=null">
and age=#{age}
</if>
</where>
</select>
注意:
test条件中 通过java实体类属性判断
字符串 null ""
其他类型 null
测试代码
@Test
public void listUserByConditionTest(){
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
//List<User> users = mapper.listUserBySort("desc");
User user = new User();
// user.setAge(30);
// user.setDeptno(10l);
user.setUsername("老");
List<User> users = mapper.listUserByCondition(user);
System.out.println(JSON.toJSONString(users));
MyBatisHealper.backAndSaveSqlSession(sqlSession);
}
1.2动态查询多条数据
接口文件
//List<Long> listId; 标准做法
//String listIdStr 简化做法 需要使用${}拼接语法 不能防注入
// 所以参数:1,2,3,4,5 不是从页面传的时候 才可以使用
//通过@Param封装map 指定list的key 方便映射文件使用
List<User> listUserByListId(@Param("listId") List<Long> listId);
映射文件
<select id="listUserByListId" resultMap="UserBaseMap">
select
<include refid="UserFileds"></include>
from user
where id in
集合的key 每次遍历到的元素 分割符
<foreach collection="listId" item="userid" separator=","
open="(" close=")">
#{userid} //对应item
</foreach>
</select>
测试代码:
@Test
public void listUserByListIdTest(){
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<Long> listId = new ArrayList<>();
listId.add(1l);
//listId 需要有数据 没数据会报错 执行前需要检测是否有数据
List<User> users = mapper.listUserByListId(listId);
System.out.println(JSON.toJSONString(users));
MyBatisHealper.backAndSaveSqlSession(sqlSession);
}
2.删除场景
多条删除
配合in语句 通过forEach遍历集合数据 多条删除
接口文件
//List<Long> listId;
//String listIdStr 1,2,3,4,5 不是从页面传的
int deleteUserByListId(@Param("listId") List<Long> listId);
映射文件
<delete id="deleteUserByListId">
delete from user
where id in
<foreach collection="listId" item="id" separator="," //最后一个,会自动删除
open="(" close=")">
#{id}
</foreach>
</delete>
测试案例
@Test
public void deleteUserByListIdTest(){
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<Long> listId = new ArrayList<>();
listId.add(29l);
listId.add(30l);
listId.add(31l);
//listId 需要有数据 没数据会报错 执行前需要检测是否有数据
int resNum = mapper.deleteUserByListId(listId);
System.out.println(resNum);
MyBatisHealper.backAndSaveSqlSession(sqlSession);
}
3.添加场景 多条添加
批量从文件导入数据时使用
接口文件
//List<User> addUserList; 传入对象集合
int addUserByUserList(@Param("addUserList")List<User> addUserList);
映射文件
<insert id="addUserByUserList">
insert into user(username,`password`,age) VALUES
<foreach collection="addUserList" item="user" separator=",">
(#{user.username},#{user.password},#{user.age})
</foreach>
<!-- 通过对象找到实际属性
('444','333',15) ,('555','333',15),('666','333',15)-->
</insert>
测试案例
@Test
public void addUserByUserListTest(){
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> addUserList = new ArrayList<>();
addUserList.add(new User("aaa1", 13, "aaa"));
addUserList.add(new User("aaa2", 13, "aaa"));
addUserList.add(new User("aaa3", 13, "aaa"));
//listId 需要有数据 没数据会报错 执行前需要检测是否有数据
int resNum = mapper.addUserByUserList(addUserList);
System.out.println(resNum);
MyBatisHealper.backAndSaveSqlSession(sqlSession);
}
4.动态修改 根据条件不同执行的修改不同
给多模块公共修改语句时使用
接口文件
int UpdateUserByCondition(User inputUser);
映射文件
<update id="UpdateUserByCondition">
update user
<set>
<if test="username!=null and username!=''">
username = #{username} , //set标签会自动去除多余的,
</if>
<if test="age!=null ">
age = #{age} ,
</if>
</set>
where id = 38
<!-- set username = '888888' ,age = 15 -->
</update>
测试案例
@Test
public void updateUserByConditionTest(){
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
// User user = new User("aaa2", 13, "aaa");
User user = new User();
user.setAge(99);
user.setId(38l);
//listId 需要有数据 没数据会报错 执行前需要检测是否有数据
int resNum = mapper.UpdateUserByCondition(user);
System.out.println(resNum);
MyBatisHealper.backAndSaveSqlSession(sqlSession);
}
5mybatis缓存
* mybatis缓存
* 一级缓存(sqlSession级别) 查询数据时 如果是相同的数据 会自动存入缓存(不多次查询数据库)
* 在一次sqlSession中生效
*
* 二级缓存(SqlSessionFactory) 可以跨sqlSession共享数据
*
*
* redis (类似 内存数据库) 可以替代java中的自带缓存
@Test
public void listUserCacheTest(){
/*
* mybatis缓存
* 一级缓存(sqlSession级别) 查询数据时 如果是相同的数据 会自动存入缓存(不多次查询数据库)
* 在一次sqlSession中生效
*
* 二级缓存(SqlSessionFactory) 可以跨sqlSession共享数据
*
*
* redis (类似 内存数据库) 可以替代java中的自带缓存
*
*
* */
SqlSession sqlSession = MyBatisHealper.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
//在一次事务控制中 如果使用了相同的数据 直接从缓存加载
List<User> users = mapper.listUser("老");
System.out.println("第一次查询的数据"+JSON.toJSONString(users));
MyBatisHealper.backAndSaveSqlSession(sqlSession);
SqlSession sqlSession2 = MyBatisHealper.getSqlSession();
UserDao mapper2 = sqlSession2.getMapper(UserDao.class);
//在一次事务控制中 如果使用了相同的数据 直接从缓存加载
List<User> users2 = mapper2.listUser("老");
System.out.println("第二次查询的数据"+JSON.toJSONString(users2));
MyBatisHealper.backAndSaveSqlSession(sqlSession2);
}
6.mybatis注解配置
mybatis可以不使用配置文件 使用注解配置 注解不适合复杂配置