详解MyBatis篇五
目录
数据库连接池
介绍
优点
使用
动态SQL
基本用法
注意事项
使用案例
存在的问题:符号有多余前缀和后缀
标签
使用案例
标签
使用案例
标签
使用案例
标签
属性
使用案例
编辑 标签
步骤
注意事项
使用案例
数据库连接池
介绍
数据库连接池负责分配、管理和释放数据库连接,它允许应⽤程序重复使⽤⼀个现有的数据库连接,⽽不是再重新建⽴⼀个.
没有使⽤数据库连接池的情况: 每次执⾏SQL语句, 要先创建⼀个新的连接对象, 然后执⾏SQL语句, SQL语句执⾏完, 再关闭连接对象释放资源. 这种重复的创建连接, 销毁连接⽐较消耗资源;
使⽤数据库连接池的情况: 程序启动时, 会在数据库连接池中创建⼀定数量的Connection对象, 当客⼾请求数据库连接池, 会从数据库连接池中获取Connection对象, 然后执⾏SQL, SQL语句执⾏完, 再把Connection归还给连接池.
优点
1.提高性能:
减少了建立连接和断开连接的开销。数据库连接的建立是一个相对耗时的过程,因为它涉及到网络通信、身份验证、权限验证等多个步骤。连接池通过预先创建并维护一定数量的数据库连接,减少了这些开销。
提高了数据库操作的响应速度。由于连接可以迅速从池中获取,应用程序可以更快地执行数据库查询和更新操作。
2.提高资源利用率:
数据库连接是昂贵的资源,特别是在高并发环境下。连接池通过限制同时存在的连接数量,避免了资源的过度消耗和浪费。
允许更有效的资源管理和分配。管理员可以根据应用的需求和数据库的性能,调整连接池的大小,以平衡资源利用和性能需求。
3.增强系统稳定性:
连接池通过限制连接数,可以防止因为过多连接而导致的数据库崩溃或性能下降。
提供了故障恢复机制。当连接池中的某个连接因为故障而失效时,连接池可以自动尝试重新建立连接,从而减少了应用程序因数据库连接问题而中断的风险。
4.简化数据库管理:
对于开发者而言,使用连接池可以简化数据库连接的管理。开发者不需要编写额外的代码来处理连接的创建、维护和释放,从而可以更加专注于业务逻辑的实现。
提供了灵活的连接配置选项。连接池允许开发者根据需要配置连接参数,如连接超时时间、最大连接数等,以适应不同的应用场景。
5.支持高并发:
在高并发环境下,连接池通过提供快速的连接复用,可以有效地降低系统的响应时间,提高系统的并发处理能力。
通过合理的连接池配置,可以确保在高并发场景下,数据库资源能够被公平、高效地利用。
使用
常⻅的数据库连接池:
• C3P0
• DBCP
• Druid
• Hikari
⽬前⽐较流⾏的是 Hikari, Druid
1. Hikari : SpringBoot默认使⽤的数据库连接池
2. Druid
如果我们想把默认的数据库连接池切换为Druid数据库连接池, 只需要引⼊相关依赖即可
< dependency > < groupId >com.alibaba</ groupId > < artifactId >druid-spring-boot-starter</ artifactId > < version >1.1.17</ version > </ dependency >
动态SQL
标签
在 MyBatis 中, 标签是动态 SQL 的一个重要组成部分,它允许你根据条件包含或排除 SQL 片段。这对于构建灵活的查询非常有用,尤其是当你需要根据不同的条件动态地构建 WHERE 子句时。
基本用法
标签通常与 test 属性一起使用,test 属性中的表达式用于评估是否应该包含 标签内的 SQL 片段。如果表达式的结果为 true,则 MyBatis 会包含 标签内的 SQL 片段;如果为 false,则忽略该片段。
注意事项
1.确保 test 属性中的表达式正确无误,并且与传递给 MyBatis 的参数类型相匹配。
2.使用 标签时,要考虑到 SQL 注入的风险,尤其是当条件中包含用户输入时。幸运的是,MyBatis 的参数替换机制(如 #{})可以有效防止 SQL 注入。
3.尽量避免在 标签内编写复杂的逻辑,以保持 SQL 映射的清晰和易于维护。
4.当多个 标签组合使用时,要注意它们之间的逻辑关系和 SQL 语句的语法正确性。
使用案例
mapper接口案例
@Mapperpublic interface UserInfoXmlMapper { Integer insertByCondtion(UserInfo userInfo);}
**Mapper.xml
insert into userinfo ( username, password, age, gender ) values ( #{username}, #{password}, #{age}, #{gender} )
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void insertByCondtion() { UserInfo userInfo = new UserInfo(); userInfo.setUsername(\"zhaoliu444\"); userInfo.setPassword(\"zhaoliu444\"); userInfo.setAge(12); userInfo.setGender(1); userInfoXmlMapper.insertByCondtion(userInfo); }}
运行结果:
存在的问题:符号有多余前缀和后缀
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void insertByCondtion() { UserInfo userInfo = new UserInfo(); userInfo.setUsername(\"xiaohua\"); userInfo.setPassword(\"xiaohua\"); userInfo.setAge(12);// userInfo.setGender(1); userInfoXmlMapper.insertByCondtion(userInfo); }}
运行结果:
原因来自于上面的**Mapper.xml代码中的:
当某个对象属性值为null时,可能会导致SQL语句出现多余前缀符号和后缀符号的情况,针对上面的例子,因为gender属性为null,导致SQL语句变成了 insert into userinfo ( username,password,age,) values ( #{username},#{password},#{age},) 显然这句SQL是存在语法问题的。
那么如何解决这个问题呢?就是接下来要讲解的标签。
标签
属性
标签中有如下属性:
• prefix:表⽰整个语句块,以prefix的值作为前缀
• suffix:表⽰整个语句块,以suffix的值作为后缀
• prefixOverrides:表⽰整个语句块要去除掉的前缀
• suffixOverrides:表⽰整个语句块要去除掉的后缀
使用案例
mapper接口
@Mapperpublic interface UserInfoXmlMapper { Integer insertByCondtion(UserInfo userInfo);}
**Mapper.xml
insert into userinfo username, password, age, gender values #{username}, #{password}, #{age}, #{gender}
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void insertByCondtion() { UserInfo userInfo = new UserInfo(); userInfo.setUsername(\"xiaohua\"); userInfo.setPassword(\"xiaohua\"); userInfo.setAge(12);// userInfo.setGender(1); userInfoXmlMapper.insertByCondtion(userInfo); }}
运行结果:
标签
标签: 它会自动在内部 SQL 片段前添加 \"WHERE\" 关键字(如果内部有内容的话),并且会智能地去除任何位于条件前的 \"AND\" 或 \"OR\" 关键字。
使用案例
mapper接口
@Mapperpublic interface UserInfoXmlMapper { List queryUserByCondition(UserInfo userInfo);}
**Mapper.xml
select * from userinfo age = #{age} and gender = #{gender} and delete_flag = #{deleteFlag}
UserInfo
package com.wmh.mybatisdemo.model;import lombok.Data;import java.util.Date;@Datapublic class UserInfo { private Integer id; private String username; private String password; private Integer age; private Integer gender; private String phone; private Integer deleteFlag; private Date createTime; private Date updateTime;}
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void queryUserByCondition() { UserInfo userInfo = new UserInfo(); userInfo.setAge(12); userInfo.setGender(1); userInfo.setDeleteFlag(0); System.out.println(userInfoXmlMapper.queryUserByCondition(userInfo)); }}
运行结果:
哪怕筛选条件为空,也是没有影响的,因为标签会判断内部是否有内容而添加where关键字:
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void queryUserByCondition() { UserInfo userInfo = new UserInfo(); System.out.println(userInfoXmlMapper.queryUserByCondition(userInfo)); }}
运行结果:
标签
标签:它会自动在内部SQL片段前添加\"SET\"关键字(如果内部有内容的话),并且会智能地去除任何位于字段值后的逗号。
使用案例
mapper接口
@Mapperpublic interface UserInfoXmlMapper { Integer updateByCondition(UserInfo userInfo);}
**Mapper.xml
update userinfo password = #{password}, age = #{age}, gender = #{gender} where id =#{id}
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void updateByCondition() { UserInfo userInfo = new UserInfo(); userInfo.setId(9); userInfo.setPassword(\"11223\"); userInfo.setGender(2); userInfo.setAge(20); System.out.println(userInfoXmlMapper.updateByCondition(userInfo)); }}
运行结果:
更新操作数据库中信息变化:
标签
在MyBatis中,标签是一个非常强大的动态SQL元素,它允许你遍历集合(List、Set等)或数组,并为每个元素生成相应的SQL片段。这在处理批量插入、批量更新、或者在WHERE子句中使用IN条件时非常有用。
属性
1.collection属性:它指定了要遍历的集合或数组的名称。如果是方法参数且参数类型为数组或集合,则可以使用array或list作为名称(取决于实际传入的参数类型)。如果是Map类型的参数,则需要指定Map中对应的key。
2.item属性:它是集合中每个元素的别名,可以在循环体内部通过该别名来引用当前元素。
3.index属性(可选):它是当前元素在集合中的索引,在需要时可以使用。
4.separator属性:它指定了集合中每个元素生成的SQL片段之间的分隔符。
5.open和close属性(可选):它们分别指定了循环开始前和结束后要添加的字符串,这对于生成某些特定结构的SQL语句非常有用。
使用案例
mapper接口
@Mapperpublic interface UserInfoXmlMapper { Integer batchDelete(List ids);}
**Mapper.xml
delete from userinfo where id in #{id}
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void batchDelete() { List ids = Arrays.asList(new Integer[]{7,23,24,25}); userInfoXmlMapper.batchDelete(ids); }}
运行结果:
删除操作数据库中信息变化:
标签
在MyBatis中,标签用于引用另一个SQL片段,这有助于重用SQL代码,使映射文件更加整洁和易于维护。当你发现自己在多个地方使用了相同的SQL片段时,就可以考虑将这些片段抽取出来,并使用标签在需要的地方引用它们。
步骤
1.定义SQL片段
首先,你需要定义一个可重用的SQL片段。这通常是通过在元素内部定义一个元素来实现的。元素具有一个id属性,该属性用于唯一标识这个SQL片段,以便在标签中引用。
2.引用SQL片段
然后,你可以在需要的地方使用标签来引用这个SQL片段。标签具有一个refid属性,该属性指定了要引用的SQL片段的id。
注意事项
1.refid属性:它指定了要引用的SQL片段的id。确保refid的值与元素的id属性值相匹配。
2.可重用性:通过定义和引用SQL片段,你可以提高SQL代码的可重用性,减少重复,并使得映射文件更加整洁。
3.性能考虑:虽然重用SQL片段可以提高代码的可读性和可维护性,但它并不会对性能产生直接影响。然而,确保你的SQL查询是高效的,并避免不必要的数据库操作,仍然是优化性能的关键。
使用案例
mapper接口
@Mapperpublic interface UserInfoXmlMapper { List selectAllUser();}
**Mapper.xml接口
select * from userinfo
UserInfo
package com.wmh.mybatisdemo.model;import lombok.Data;import java.util.Date;@Datapublic class UserInfo { private Integer id; private String username; private String password; private Integer age; private Integer gender; private String phone; private Integer deleteFlag; private Date createTime; private Date updateTime;}
Test代码
@SpringBootTestclass UserInfoXmlMapperTest { @Autowired private UserInfoXmlMapper userInfoXmlMapper; @Test void selectAllUser() { System.out.println(userInfoXmlMapper.selectAllUser()); }}
运行结果: