文章目录
- 一、什么是动态SQL + 重要性
- 二、动态SQL的编写 ---注解
- 三、动态SQL的编写 ---xml
- 3.1 增加场景 if标签
- 3.2 处理代码块内容 --- trim 标签
- 3.3 查询场景 where标签
- 3.4 更新场景 set标签
- 3.5 删除场景 <foreach> 循环标签
- 3.6 include、sql标签 代码重复度问题
- 四、数据库连接池
一、什么是动态SQL + 重要性
- 什么是动态SQL:根据需求(),去动态地拼接SQL
- 重要性:
- 编写方式的选择:根据个人喜好和企业中的其他人用什么来选择
- 推荐:简单SQL用注解,动态SQL用xml
- 动态SQL,语句会比较复杂,此时使用xml更易读,而且因为本身支持标签,书写还会有提示
- 简单SQL,使用注解会更简单,xml还需要另外写文件(当然,也有例如MybatisGenerator之类的插件可以帮我们去生成)
二、动态SQL的编写 —注解
- 编写方法:可以在xml文件格式下写好后,复制上来
- 使用script标签让标签生效:使用注解编写SQL,需要将 SQL 放到 script标签 下
- 因为注解里如果使用 if之类的标签,字符串里就混杂了标签,为了让标签生效,需要加上 script标签
- 单双引号问题:
- 因为注解整个是要用字符串,即要用双引号(java里单引号表示字符),所以 if标签里面的判断条件等内容需要用单引号来区分
- 如果用了双引号,需要转义
- 原理:关于里面一些标签的使用,是和xml方式一样的
@Mapper
public interface UserInfoMapper {@Insert("<script>" +"insert into userinfo (username,password,age," +"<if test='gender!=null' >" +"gender,</if>" +"phone) " +"values(#{username},#{password},#{age}," +"<if test='gender!=null'>#{gender},</if>" +"#{phone})" +"</script>")Integer insert(UserInfo userInfo);
}
@Select("<script>+" +"select * from userinfo" +" <where>" +" <if test=\"username!=null\">" +" username = #{username}" +" </if>" +" <if test=\"password!=null\">" + " and password = #{password}" +" </if>\n" +" <if test=\"age!=null\">" +" and age = #{age}" +" </if>" +" </where>"+"</script>")
List<UserInfo> select2(UserInfo userInfo);
三、动态SQL的编写 —xml
3.1 增加场景 if标签
- 示例场景:根据用户的输入情况,拼接SQL,实现动态插入
- insert into userinfo (username, password, age) values(?,?,?)中,这个SQL语句是被写死的,用户必须要全部输入username、password、age这三个信息,才可以完成数据插入的操作。但有些场景下,我们是不需要把所有的信息都写完的
- 代码
- 关于 script 标签:不需要加上,因为xml本身就是支持标签的,不需要该标签来让写的if等标签生效
- 引号:判断条件里,单双引号都可以使用
- 关于标签:if、where这类标签,是MyBatis借助xml的方式去实现的。如if标签表示这里面是个if语句,where标签表示这里面是where语句。
<?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.example.demo.mapper.UserinfoMapper"><insert id="insert"> insert into userinfo(username, password,<if test="age!=null"> age </if>)values (#{username}, #{password},<if test="age!=null">#{age}</if>)</insert>
</mapper>
3.2 处理代码块内容 — trim 标签
- 问题描述:
- 解决后的代码:
- < trim suffixOverrides=“,” prefix=“(” suffix=“)”>:
- 去除trim标签代码块最后面的 “,” 字符
- 在trim标签代码块最前面和最后面,分别加上 “(” 和 “)”。即我们没必要再自己写括号了
<?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.example.demo.mapper.UserinfoMapper"><insert id="insert">insert into userinfo<trim suffixOverrides="," prefix="(" suffix=")"><if test="username!=null">username,</if><if test="password!=null">password,</if><if test="age!=null">age,</if><if test="gender!=null">gender</if></trim>values <trim suffixOverrides="," prefix="(" suffix=")"><if test="username!=null">#{username},</if><if test="password!=null">#{password},</if><if test="age!=null">#{age}</if><if test="gender!=null">#{gender}</if></trim></insert>
</mapper>
3.3 查询场景 where标签
- 方式一:使用trim标签:
- < trim prefixOverrides=“and”>:避免【当输入的值只有最后一个(此处指只查age)】,SQL语句前面会多一个and的情况
- 问题:
- 一个参数都不给,就会多一个where
- 如果把where放进trim标签里,那【删除最前面的and】的需求就无法实现
<?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.example.demo.mapper.UserinfoMapper"><select id="select" resultType="com.example.demo.model.UserInfo">select * from userinfowhere<trim prefixOverrides="and"><if test="username!=null">username = #{username}</if><if test="password!=null">and password = #{password}</if><if test="age!=null">and age = #{age}</if></trim></select>
</mapper>
- 方式二:使用where 1=1:
- where 1=1:当搜寻条件一个都没有时,相当于【查询所有】
- and username = #{username}:相比于方式一,第一个搜寻条件需要加上and
<?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.example.demo.mapper.UserinfoMapper"><select id="select" resultType="com.example.demo.model.UserInfo">select * from userinfowhere 1=1<trim prefixOverrides="and"><if test="username!=null">and username = #{username}</if><if test="password!=null">and password = #{password}</if><if test="age!=null">and age = #{age}</if></trim></select>
</mapper>
- 方式三:使用where标签:该标签由Mybatis提供
- where标签的作用:
- 当查询条件都为空时,where标签会自动去除where关键字
- 当只查询最后一个条件时,可以帮我们去除最前面的 and字符
<?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.example.demo.mapper.UserinfoMapper"><select id="select" resultType="com.example.demo.model.UserInfo">select * from userinfo<where><if test="username!=null">username = #{username}</if><if test="password!=null">and password = #{password}</if><if test="age!=null">and age = #{age}</if></where></select>
</mapper>
3.4 更新场景 set标签
- 写法一:set + trim:
<?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.example.demo.mapper.UserinfoMapper"><update id="update">update userinfoset<trim suffixOverrides=","><if test="username != null">username = #{username},</if><if test="age != null">age = #{age},</if><if test="gender != null">gender = #{gender}</if></trim>where age = 21</update>
</mapper>
- 方式二:使用set标签:相当于方式一
- 如果一个要修改的值都没有:没有值时会把set去掉,但又因为如果要执行更新的SQL,必须要有set,所以这种情况会报错
- 解决方法:无法解决,因为没有【你一方面要执行更新操作,另一方面什么都不修改】的需求
<?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.example.demo.mapper.UserinfoMapper"><update id="update">update userinfo<set><if test="username != null">username = #{username},</if><if test="age != null">age = #{age},</if><if test="gender != null">gender = #{gender}</if></set>where username = 'zhangliu'</update>
</mapper>
3.5 删除场景 循环标签
- 示例场景:批量,如批量删除
- 理解:delete from userInfo where id in(xx, xx, xx):我们需要一个集合,遍历该集合,把其中的每个数都输出来
3.6 include、sql标签 代码重复度问题
- 示例场景:在执行查询操作时,我们一般不支持使用*,推荐把要查的列列出来,哪怕是全部。但此时,代码重复度就会很高
- 解决方法:对重复的代码片段进行抽取,将其通过sql标签封装成一个SQL片段,然后再通过include标签进行引用
- 使用方法:
<?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.example.demo.mapper.UserinfoMapper"><sql id="selectTable"> select username, password, gender from userinfo</sql><select id="selectAll" resultType="com.example.sp20240607.model.UserInfo"><include refid="selectTable"></include> where id = 1</select>
</mapper>
四、数据库连接池
- 池化的概念:把需要的东西放到池子里,后续如果需要,直接拿出来用,省略了自己常见的过程
- 线程池也是这样,提前创建好很多线程,我们需要用线程的时候就直接去这个池子里拿
- 有无数据库连接池的情况:
- 常用的数据库连接池:C3P0、DBCP、Druid、Hikarl
- 目前比较流行的是Druid和Hikarl,功能上前者更优,性能上Hikarl更好,我们需要根据需求进行选择。
- 数据库连接池的使用:Mybatis已经封装了数据库连接池
- 更改数据库连接池:SpringBoot默认使用的数据库连接池是Hikarl,如果我们要使用其他的,直接引入需要的数据库连接池的依赖即可
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.21</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.21</version>
</dependency>