目录:
一 、实验目的:
通过 mybatis 提供的各种标签方法实现动态拼接 sql
二 、预习要求:
预习 if、choose、 when、where 等标签的用法
三、实验内容:
- 根据性别和名字查询用户
- 使用 if 标签改造 UserMapper.xml
- 使用 where 标签进行改造 UserMapper.xml
- 使用 Sql 片段改造 UserMapper.xml
- 利用 foreach 标签实现根据多个 id 查询用户信息
四、实验方法和步骤:
实验前准备:
①创建数据库experience03,创建表user,并插入以下数据:
CREATE DATABASE experience03;
USE experience03;DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(0) NOT NULL AUTO_INCREMENT,`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,`birthday` date NULL DEFAULT NULL,`sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`address` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ;INSERT INTO `user` VALUES (1, '关羽', '2024-09-29', '男', '蜀国');
INSERT INTO `user` VALUES (2, '梁王孙', '2024-09-11', '男', '北京市');
INSERT INTO `user` VALUES (3, '陈长生', '2024-05-14', '女', '京都西庙');
INSERT INTO `user` VALUES (4, '王婆', '2024-09-05', '女', '快远');
INSERT INTO `user` VALUES (5, '黄忠', '2016-07-24', '1', '三国');
INSERT INTO `user` VALUES (6, '张飞', '2024-10-16', '女', '三国');
INSERT INTO `user` VALUES (7, 'lucky', '2021-10-08', '男', '三国');
INSERT INTO `user` VALUES (14, '关羽', '2024-12-02', '男', '蜀国');
②配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.haust</groupId><artifactId>experience03</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.14</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency></dependencies></project>
③编写User.java在com.haust.pojo中
package com.haust.pojo;import java.util.Date;public class User {private int id;private String username;private Date birthday;private String sex;private String address;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';}
}
在java/com/haust/mapper中创建UserMapper接口
package com.mapper;public interface UserMapper {
}
在resources/com/haust/mapper简历UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace=""></mapper>
在resources下创建db.properties
jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/experience03jdbc.username=rootjdbc.password=root
在resources根目录下配置mybatis-config.cml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"/>
<!-- <settings>-->
<!-- <setting name="logImpl" value="LOG4J"/>-->
<!-- </settings>--><typeAliases><typeAlias type="com.haust.pojo.User" alias="User"/></typeAliases><environments default="environment"><environment id="environment"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><mapper resource="com/haust/mapper/UserMapper.xml"/></mappers>
</configuration>
(1)根据性别和名字查询用户
查询 sql:
SELECT id, username, birthday, sex, address
FROM `user`
where sex = '1' AND username LIKE '%张%'
①Mapper.xml 文件
UserMapper.xml 配置 sql,如下:
<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select * from userwhere username like '%${username}%' and sex = #{sex}</select>
②Mapper 接口
编写 Mapper 接口,如下:
List<User> findUserUsernameAndSex(User user);
③测试方法
在 UserMapperTest 添加测试方法,如下:
@Test
public void test09() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();user.setSex("女");user.setUsername("王");List<User> list = userMapper.findUserUsernameAndSex(user);System.out.println(list);sqlSession.commit();sqlSession.close();
}
④实验效果
测试效果如下图:
如果注释掉 user.setSex("1"),测试结果如下图:
测试结果二很显然不合理。
按照之前所学的,要解决这个问题,需要编写多个 sql,查询条件越多,需要编写的 sql 就 更多了,显然这样是不靠谱的。
解决方案,使用动态 sql 的 if 标签
(2)使用 if 标签改造 UserMapper.xml
(二)使用 if 标签改造 UserMapper.xml
①改造 UserMapper.xml,如下:
<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select * from userwhere 1=1<if test="username != null and username != ''">and username like '%${username}%'</if><if test="sex != null and sex != ''">and sex = #{sex}</if></select>
注意字符串类型的数据需要要做不等于空字符串校验。
②实验效果
测试类:
@Testpublic void test09() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();// user.setSex("男");user.setUsername("王");List<User> list = userMapper.findUserUsernameAndSex(user);System.out.println(list);sqlSession.commit();sqlSession.close();}
如上图所示,测试 OK
注意:使用<if test="">后sex注释掉,会选择username作为唯一条件
(3)使用 where 标签进行改造 UserMapper.xml
(三)使用 where 标签进行改造 UserMapper.xml
上面的 sql 还有 where 1=1 这样的语句,很麻烦
可以使用 where 标签进行改造,where 标签可以自动添加 where,同时处理 sql 语句中第一个 and 关键字
①改造 UserMapper.xml,如下
<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select * from user<where><if test="username != null and username != ''">and username like '%${username}%'</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select>
测试类:
@Testpublic void test09() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();// user.setSex("男");user.setUsername("王");List<User> list = userMapper.findUserUsernameAndSex(user);System.out.println(list);sqlSession.commit();sqlSession.close();}
②实验效果
(4)使用 Sql 片段改造 UserMapper.xml
使用 Sql 片段改造 UserMapper.xml Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。
①把上面例子中的 id, username, birthday, sex, address 提取出来,作为 sql 片段,如下:
<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select <include refid="userFields"></include> from user<where><if test="username != null and username != ''">and username like '%${username}%'</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select><sql id="userFields">id, username, birthday, address, sex</sql>
如果要使用别的 Mapper.xml 配置的 sql 片段,可以在 refid 前面加上对应的 Mapper.xml 的
namespace。
(5)利用 foreach 标签实现根据多个 id 查询用户信息
利用 foreach 标签实现根据多个 id 查询用户信息
向 sql 传递数组或 List,mybatis 使用 foreach 解析,如下:
①根据多个 id 查询用户信息
查询 sql:
SELECT * FROM user WHERE id IN (1,3,4)
①在java/com/haust/pojo下创建 QueryVo
如下在 pojo 中定义 list 属性 ids 存储多个用户 id,并添加 getter/setter 方法
package com.haust.pojo;import java.util.List;public class QueryVo {private User user;private List<Integer> ids;public List<Integer> getIds() {return ids;}public void setIds(List<Integer> ids) {this.ids = ids;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}@Overridepublic String toString() {return "QueryVo{" +"user=" + user +", ids=" + ids +'}';}
}
②Mapper.xml 文件
UserMapper.xml 添加 sql,如下:
<select id="findUserByList" parameterType="com.haust.pojo.QueryVo" resultType="com.haust.pojo.User">select * from user where id in<foreach collection="list" item="id" index="index" separator="," open="(" close=")">#{id}</foreach></select>
③测试方法如下图:
@Testpublic void test10() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);QueryVo queryVo = new QueryVo();List<Integer> list = new ArrayList();list.add(1);list.add(3);list.add(4);List<User> list1 = userMapper.findUserByList(list);for (User u:list1){System.out.println(u);}sqlSession.commit();sqlSession.close();}
④实验效果
测试效果如下图: