动态SQl
动态SQL的好处
-
提高代码的可读性和可维护性:使用动态SQL可以让开发者更加清晰地表达SQL语句,避免了重复编写相同的SQL语句,同时也方便了代码的维护和修改。
-
提高代码的复用性:动态SQL可以根据不同的业务场景和数据类型生成不同的SQL语句,从而提高了代码的复用性,减少了代码的冗余和重复。
-
提高系统的性能:动态SQL可以根据不同的业务场景和数据类型生成不同的SQL语句,从而提高了系统的性能,减少了不必要的数据库访问和数据传输。
-
支持复杂的业务逻辑:动态SQL可以根据不同的业务场景和数据类型生成不同的SQL语句,从而支持复杂的业务逻辑,例如多表关联查询、分页查询等。
if标签
为了简化上面where 1=1的条件拼装,我们可以使用where标签将if标签代码块包起来,将1=1条件去掉。
mapper
public interface UserDao {
//复杂条件查询
public List<User> findByUser(User user);
}
注意:在只用if标签去执行动态SQL时,要注意一个情况如果所有字段的条件不满足时我们应该查询的是所有信息,所有我们应该多加一个肯定为真的条件并列(eg,1=1)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.dao.UserDao">
<!--使用别名-->
<select id="findByUser" resultType="User">
select * from user where 1=1
<if test="username!=null and username != ''">
and username=#{username}
</if>
<if test="birthday!=null">
and birthday=#{birthday}
</if>
<if test="sex!=null and sex != ''">
and sex=#{sex}
</if>
<if test="address!=null and address != ''">
and address=#{address}
</if>
</select>
</mapper>
测试
@Test
public void testFindAll(){
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setSex("男");
user.setAddress("香港");
List<User> userList = userDao.findByUser(user);
for(User u : userList){
System.out.println(u);
}
}
where标签
若查询条件的开头为 “AND” 或 “OR”,where 标签会将它们去除。我们根据实体类的不同取值,使用不同的SQL语句来进行查询。比如在id如果不为空时可以根据 id查询,如果username不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
mapper映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.dao.UserDao">
<select id="findByUser" resultType="User">
select * from user
<!--where标签将if标签代码块包起来去掉开头 “AND” 或 “OR”-->
<where>
<if test="username!=null and username != ''">
and username=#{username}
</if>
<if test="birthday!=null">
and birthday=#{birthday}
</if>
<if test="sex!=null and sex != ''">
and sex=#{sex}
</if>
<if test="address!=null and address != ''">
and address=#{address}
</if>
</where>
</select>
</mapper>
set标签
用法 :set标签用于动态包含需要更新的列,并会删掉额外的逗号
适用于:修改的SQL语句
mapper
public void updateByUser(User user);
<update id="updateByUser" parameterType="user">
update user
<set>
<if test="username!=null and username != '' ">
username=#{username},
</if>
<if test="birthday!=null">
birthday=#{birthday},
</if>
<if test="sex!=null and sex != '' ">
sex=#{sex},
</if>
<if test="address!=null and address != '' ">
address=#{address},
</if>
</set>
where id=#{id}
</update>
测试
@Test
public void testUpdateByUser(){
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setId(50);
user.setBirthday(new Date());
user.setAddress("加拿大");
userDao.updateByUser(user);
}
trim标签
常用于插入语句,其包含四个属性
- prefix 加入前缀
- suffix 加入后缀
- prefixOverrides 去掉前缀(像进行条件限制where中连接的and)
- suffixOverrides去掉后缀(像进行修改字段set中连接的“,”)
mapper
//利用trim插入
void addUser(User user);
<insert id="addUser" parameterType="user">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username!=null and username!=''">username,</if>
<if test="password!=null and password!=''">password,</if>
<if test="birthday!=null">birthday,</if>
<if test="sex!=null and sex!=''">sex,</if>
<if test="address!=null and address!=''">address,</if>
</trim>
<trim prefix="values(" suffix=")" suffixOverrides=",">
<if test="username!=null and username!=''">#{username},</if>
<if test="password!=null and password!=''">#{password},</if>
<if test="birthday!=null">#{birthday},</if>
<if test="sex!=null and sex!=''">#{sex},</if>
<if test="address!=null and address!=''">#{address},</if>
</trim>
</insert>
测试
@Test
public void testInsertUser(){
UserMapper userMapper = ss.getMapper(UserMapper.class);
User userParam= new User();
userParam.setUsername("张二丰");
userMapper.addUser(userParam);
}
foreach标签
常用于进行批量操作,批量查找,添加,删除,将每一个操作的值放入集合或数组中,再将集合整体进行sql操作
mapper
//批量删除
public void deleteUserByIds(@Param("ids") List<Integer> ids);
//批量添加
public void insertUsers(@Param("userList") List<User> userList);
<delete id="deleteUserByIds" parameterType="list">
delete from user where id in
<!--
collection:取值list、array、map、@Param("keyName")、对象的属性名
item:循环取出的具体对象
open:起始符
separator:分隔符
close:结束符
-->
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
<insert id="insertUsers" parameterType="list">
INSERT INTO user(username,password,birthday,sex,address)
VALUES
<foreach collection ="userList" item="user" separator =",">
(#{user.username},#{user.password},#{user.birthday},
#{user.sex},#{user.address})
</foreach>
</insert>
测试
@Test
public void testDeleteUserByIds(){
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<Integer> ids = new ArrayList();
ids.add(50);
ids.add(64);
ids.add(67);
userDao.deleteUserByIds(ids);
}
@Test
public void testInsertUsers(){
UserDao userDao = sqlSession.getMapper(UserDao.class);
long start = System.currentTimeMillis();
List<User> userList = new ArrayList<>();
for(int i = 0 ;i < 10000; i++) {
User user = new User();
user.setUsername("刘德华");
user.setPassword("111");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("香港");
//userDao.insertUser(user);
userList.add(user);
}
userDao.insertUsers(userList);
long end = System.currentTimeMillis();
System.out.println("一万条数据总耗时:" + (end-start) + "ms" );
sqlSession.commit();
}
sql标签
用处在于提取出经常会用到的slq代码
mapper
//复杂条件查询
public List<User> findByUser3(User user);
<!-- 定义SQL片段 -->
<sql id="query_user_where">
<if test="username!=null and username != ''">
and username=#{username}
</if>
<if test="birthday!=null">
and birthday=#{birthday}
</if>
<if test="sex!=null and sex != ''">
and sex=#{sex}
</if>
<if test="address!=null and address != ''">
and address=#{address}
</if>
</sql>
<select id="findByUser3" resultType="User">
select * from user
<where>
<include refid="query_user_where"></include>
</where>
</select>
测试
@Test
public void testFindAll3(){
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setAddress("香港");
user.setUsername("刘德华");
List<User> userList = userDao.findByUser3(user);
for(User u : userList){
System.out.println(u);
}
}