广州市专业做网站,网站建设 费用,株洲今天最新通知,免费建立微信网站学习视频#xff1a;3001 动态SQL中的元素_哔哩哔哩_bilibili 目录
1.1为什么学
1.2动态SQL中的元素 条件查询操作 if 元素 choose、when、otherwise元素 where、trim元素 更新操作 set元素使用场景 复杂查询操作 foreach 元素中的属性
编辑 迭代数组 迭代List 迭代Map 1… 学习视频3001 动态SQL中的元素_哔哩哔哩_bilibili 目录
1.1为什么学
1.2动态SQL中的元素 条件查询操作 if 元素 choose、when、otherwise元素 where、trim元素 更新操作 set元素使用场景 复杂查询操作 foreach 元素中的属性
编辑 迭代数组 迭代List 迭代Map 1.3案例学生信息查询系统
总结 1.1为什么学 在实际项目的开发中开发人员在使用JDBC或其他持久层框架进行开发时经常需要根据不同的条件拼接SQL语句拼接SQL语句时还要确保不能遗漏必要的空格、标点符号等这种编程方式给开发人员带来了非常大的不便而MyBatis提供的SQL语句动态组装功能恰能很好地解决这一问题。 1.2动态SQL中的元素 使用动态SQL的好处 动态SQL是MyBatis的强大特性之一MyBatis采用了功能强大的基于OGNLObject Graph Navigation Language的表达式来完成动态SQL。在MyBatis的映射文件中开发人员可通过动态SQL元素灵活组装SQL语句这在很大程度上避免了单一SQL语句的反复堆砌提高了SQL语句的复用性。 动态SQL常用元素 条件查询操作 if元素 在MyBatis中if元素是最常用的判断元素它类似于Java中的if语句主要用于实现某些简单的条件判断。在实际应用中我们可能会通过某个条件查询某个数据。例如要查找某个客户的信息可以通过姓名或者年龄来查找客户也可以不填写年龄直接通过姓名来查找客户还可以都不填写而查询出所有客户此时姓名和年龄就是非必须条件。类似于这种情况在MyBatis中就可以通过if元素来实现。 数据库准备 在名称为mybatis的数据库中创建一个t_customer表并插入几条测试数据。
USE mybatis;
CREATE TABLE t_customer (id int(32) PRIMARY KEY AUTO_INCREMENT,username varchar(50),jobs varchar(50),phone varchar(16));
INSERT INTO t_customer VALUES (1, joy, teacher, 13733333333);
INSERT INTO t_customer VALUES (2, jack, teacher, 13522222222);
INSERT INTO t_customer VALUES (3, tom, worker, 15111111111);POJO类准备 创建持久化类Customer在类中声明id、username、jobs和phone属性及属性对应的getter/setter方法。
public class Customer {private Integer id; private String username; // 主键ID、客户名称private String jobs; private String phone; // 职业、电话// 省略getter/setter方法Overridepublic String toString() {return Customer [id id , username username , jobs jobs , phone phone ]; }
}创建映射文件 创建映射文件CustomerMapper.xml在映射文件中根据客户姓名和年龄组合条件查询客户信息使用if元素编写该组合条件的动态SQL。
!– 该xml文件中只列出了if元素的动态SQL--
if testusername !null and username !‘’“and username like concat(%,#{username}, %)
/if
if testjobs !null and jobs !‘’“and jobs #{jobs}
/if修改核心配置文件 在配置文件mybatis-config.xml中引入CustomerMapper.xml映射文件将CustomerMapper.xml映射文件加载到程序中。
mapper
resourcecom/it/mapper/CustomerMapper.xml
/mapper创建获取SqlSession对象的工具类
public class MybatisUtils {private static SqlSessionFactory sqlSessionFactory null;// 初始化SqlSessionFactory对象static {try {// 使用MyBatis提供的Resources类加载MyBatis的配置文件Reader reader Resources.getResourceAsReader(mybatis-config.xml);// 构建SqlSessionFactory工厂sqlSessionFactory new SqlSessionFactoryBuilder().build(reader);} catch (Exception e) {e.printStackTrace();}}// 获取SqlSession对象的静态方法public static SqlSession getSession() {return sqlSessionFactory.openSession();}
}编写测试类 在测试类MyBatisTest中编写测试方法findCustomerByNameAndJobsTest()该方法用于根据客户姓名和职业组合条件查询客户信息列表。 public class MyBatisTest { Testpublic void findCustomerByNameAndJobsTest(){SqlSession session MyBatisUtils.getSession();Customer customer new Customer();customer.setUsername(“jack); customer.setJobs(teacher);ListCustomer customers session.selectList(com.itheima.mapper .CustomerMapper.findCustomerByNameAndJobs,customer);for (Customer customer2 : customers) { System.out.println(customer2); }session.close();}
}MyBatisTest.java
package com.it.test;import com.it.pojo.Customer;
import com.it.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;public class MyBatisTest {Testpublic void findCustomerByUsernameAndJobsTest(){SqlSession sqlSession MyBatisUtils.getSession();Customer customernew Customer();customer.setUsername(jack);customer.setJobs(teacher);//执行sqlListCustomer customerssqlSession.selectList(com.it.mapper.CustomerMapper.findCustomerByUsernameAndJobs,customer);for (Customer c:customers){System.out.println(c);}//释放资源sqlSession.close();}}CustomerMapper.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
!--mapper为映射的根节点用来管理DAO接口namespace指定DAO接口的完整类名表示mapper配置文件管理哪个DAO接口(包.接口名)mybatis会依据这个接口动态创建一个实现类去实现这个接口而这个实现类是一个Mapper对象--
mapper namespacecom.it.mapper.CustomerMapper!--id 接口中的方法名parameterType 接口中传入方法的参数类型resultType 返回实体类对象包.类名 处理结果集 自动封装注意:sql语句后不要出现;号查询select标签增加insert标签修改update标签删除delete标签--select idfindCustomerByUsernameAndJobs parameterTypecom.it.pojo.Customer resultTypecom.it.pojo.CustomerSELECT * FROM t_customer where 11if testusername!null and username!and username like concat(%,#{username},%)/ifif testjobs!null and jobs!and jobs#{jobs}/if/select
/mappermybatis-config.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
!--配置mybatis环境--
configuration!--配置连接使用的相关参数default为默认使用的环境development 测试环境product 生产环境--properties resourcejdbc.properties/propertiesenvironments defaultdevelopment!--测试环境--environment iddevelopment!--事务管理类型指定事务管理的方式 JDBC--transactionManager typeJDBC/!--数据库连接相关配置动态获取config.properties文件里的内容--!--数据源类型POOLED 表示支持JDBC数据源连接池UNPOOLED 表示不支持数据源连接池JNDI 表示支持外部数据源连接池--dataSource typePOOLED!--此处使用的是MySQL数据库使用Oracle数据库时需要修改仔细检查各项参数是否正确里面配置了时区、编码方式、SSL用以防止中文查询乱码导致查询结果为null及SSL警告等问题--property namedriver value${jdbc.driver}/property nameurlvalue${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}//dataSource/environment/environmentsmappers!--下面编写mapper映射文件↓↓↓↓↓ 参考格式mapper resourcedao/UserMapper.xml/ --mapper resourcecom/it/mapper/CustomerMapper.xml/mapper/mappers/configurationchoose、when、otherwise元素 choosewhenotherwise使用场景 在使用if元素时只要test属性中的表达式为true就会执行元素中的条件语句但是在实际应用中有时只需要从多个选项中选择一个去执行。 例如下面的场景“当客户名称不为空则只根据客户名称进行客户筛选当客户名称为空而客户职业不为空则只根据客户职业进行客户筛选。当客户名称和客户职业都为空则要求查询出所有电话不为空的客户信息。” 针对上面情况使用if元素进行处理是不合适的。MyBatis提供了choose、when、otherwise元素进行处理这三个元素往往组合在一起使用作用相当于Java语言中的if…else if…else。 select idfindCustomerByUsernameOrJobs parameterTypecom.it.pojo.Customer resultTypecom.it.pojo.CustomerSELECT * FROM t_customer where 11choosewhen testusername!null and username!and username like concat(%,#{username},%)/whenwhen testjobs!null and jobs!and jobs#{jobs}/whenotherwiseand phone is not null/otherwise/choose/select
Testpublic void findCustomerByUsernameOrJobsTest(){SqlSession sqlSession MyBatisUtils.getSession();Customer customernew Customer();customer.setUsername(jack);customer.setJobs(teacher);//执行sqlListCustomer customerssqlSession.selectList(com.it.mapper.CustomerMapper.findCustomerByUsernameOrJobs,customer);for (Customer c:customers){System.out.println(c);}//释放资源sqlSession.close();} where、trim元素 wheretrim使用场景 在映射文件中编写的SQL后面加入了“where 11”的条件的话既保证了where后面的条件成立又避免了where后面第一个词是and或者or之类的关键字。 例如下面这条Mybatis拼接出的SQL语句是不正确的。 select * from t_customer where and username likeconcat(%,?, %) and jobs #{jobs}上述SQL语句中where后直接跟的是and这在运行时会报SQL语法错误针对这种情况可以使用MyBatis提供的where元素和trim元素进行处理。 select idfindCustomerByUsernameAndJobs parameterTypecom.it.pojo.Customer resultTypecom.it.pojo.Customerselect * from t_customerwhereif testusername !null and username !and username like concat(%,#{username}, %)/ifif testjobs !null and jobs !and jobs #{jobs}/if/where/select 如果2个if都不满足,where会被忽视 上述代码配置中where元素会自动判断由组合条件拼装的SQL语句只有where元素内的某一个或多个条件成立时才会在拼接SQL中加入where关键字否则将不会添加即使where之后的内容有多余的“AND”或“OR”where元素也会自动将他们去除。 trim元素 trim元素用于删除多余的关键字它可以直接实现where元素的功能。trim元素包含4个属性。 select idfindCustomerByUsernameAndJobs parameterTypecom.it.pojo.Customer resultTypecom.it.pojo.Customerselect * from t_customertrim prefixwhere prefixOverridesandif testusername !null and username !and username like concat(%,#{username}, %)/ifif testjobs !null and jobs !and jobs #{jobs}/if/trim/select更新操作 set元素使用场景 在Hibernate框架中如果想要更新某一个对象就需要发送所有的字段给持久化对象然而在实际应用中大多数情况下都是更新某一个或几个字段。如果更新的每一条数据都要将其所有的属性都更新一遍那么执行效率是非常差的。为了解决更新数据的效率问题MyBatis提供了set元素。set元素主要用于更新操作它可以在动态SQL语句前输出一个SET关键字并将SQL语句中最后一个多余的逗号去除。set元素与if元素结合可以只更新需要更新的字段。 映射文件
update idupdateCustomerBySet parameterTypecom.it.pojo.Customerupdate t_customersetif testusername !null and username !username#{username},/ifif testjobs !null and jobs ! jobs#{jobs},/ifif testphone !null and phone !phone#{phone},/if/set where id#{id}/update测试 Testpublic void updateCustomerBySetTest(){SqlSession session MyBatisUtils.getSession();Customer customernew Customer();customer.setId(3);customer.setPhome(12345678912);int rows session.update(com.it.mapper.CustomerMapper.updateCustomerBySet,customer);if(rows0){System.out.println(修改了rows条数据);}else{System.out.println(没有修改数据);}session.commit();session.close();}set元素字段非空 在映射文件中使用set元素和if元素组合进行update语句动态SQL组装时如果set元素内包含的内容都为空则会出现SQL语法错误。因此在使用set元素进行字段信息更新时要确保传入的更新字段不能都为空。 使用trim元素更新 除了使用set元素外还可以通过trim元素来实现更新操作。其中 trim元素的prefix属性指定要添加的trim元素所包含内容的前缀为setsuffixOverrides属性指定去除的trim元素所包含内容的后缀为逗号 。 update idupdateCustomerBySet parameterTypecom.it.pojo.Customerupdate t_customertrim prefixset suffixOverrides,if testusername !null and username !username#{username},/ifif testjobs !null and jobs ! jobs#{jobs},/ifif testphone !null and phone !phone#{phone},/if/trim where id#{id}/update 复杂查询操作 foreach元素中的属性 collection属性的取值 在遍历参数时collection属性的值是必须指定的。不同情况下该属性的取值也是不一样的主要有以下三种情况List类型、数组类型、Map类型。 List-list 数组类型-array Map-Map foreach元素迭代数组 foreach实现入参为数组类型的遍历 例如要从数据表t_customer中查询出id为1、2、3的客户信息就可以利用数组作为参数存储id的属性值1、2、3并通过foreach元素迭代数组完成客户信息的批量查询操作。 select idfindByArrayresultTypecom.it.pojo.Customerselect * from t_customer where id inforeach itemid indexindex collectionarrayopen( separator, close) #{id}/foreach/select
Testpublic void SelectByArrayTest(){SqlSession session MyBatisUtils.getSession();//准备查询的条件Integer[] ids{2,3};ListCustomer customers session.selectList(com.it.mapper.CustomerMapper.findByArray,ids);for(Customer customer:customers){System.out.println(customer);}session.close();} foreach元素迭代List select idfindByListresultTypecom.it.pojo.Customerselect * from t_customer where id inforeach itemid indexindex collectionlistopen( separator, close) #{id}/foreach/select
Testpublic void SelectByListTest(){SqlSession session MyBatisUtils.getSession();//准备查询的条件ListInteger anew ArrayListInteger();a.add(1);a.add(2);ListCustomer customers session.selectList(com.it.mapper.CustomerMapper.findByList,a);for(Customer customer:customers){System.out.println(customer);}session.close();} foreach元素迭代Map
select idfindByMap parameterTypejava.util.MapresultTypecom.it.pojo.Customerselect * from t_customer where jobs#{jobs} and id inforeach itemroleMap indexindex collectionid open( separator, close) #{roleMap}/foreach/select Testpublic void findByMapTest() {SqlSession session MyBatisUtils.getSession();ListInteger idsnew ArrayListInteger();ids.add(1); ids.add(2); ids.add(3);MapString,Object conditionMap new HashMapString, Object();conditionMap.put(id,ids); conditionMap.put(jobs,teacher);ListCustomer customers session.selectList(com.it.mapper .CustomerMapper.findByMap, conditionMap);for (Customer customer : customers) { System.out.println(customer);}session.close();}1.3案例学生信息查询系统
多条件查询 当用户输入的学生姓名不为空则只根据学生姓名进行学生信息的查询 当用户输入的学生姓名为空而学生专业不为空则只根据学生专业进行学生的查询 select idfindStudentByNameAndMajorresultTypecom.it.pojo.Studentselect * from dm_student where 11choosewhen testname!null and name!and name like concat(%,#{name},%)/whenwhen testmajor!null and major!and major#{major}/whenotherwiseand sno is not null/otherwise/choose/select Testpublic void findStudentByNameAndMajorTest(){SqlSession session MyBatisUtils.getSession();Student studentnew Student();student.setName(张三);student.setMajor(英语);ListStudent students session.selectList(com.it.mapper.StudentMapper.findStudentByNameAndMajor,student);for (Student student2 : students){System.out.println(student2);}session.close();} 单条件查询 查询出所有id值小于5的学生的信息 select idfindByList parameterTypejava.util.ListresultTypecom.it.pojo.Studentselect * from dm_student where id inforeach itemid indexindex collectionlistopen( separator, close)#{id}/foreach/select Testpublic void findByListTest() {SqlSession session MyBatisUtils.getSession();ListInteger idsnew ArrayListInteger();for(int i 1;i5;i){ids.add(i);}ListStudent students session.selectList(com.it.mapper.StudentMapper.findByList, ids);for (Student student : students) { System.out.println(student);}session.close();} 总结 创建这个包和配置文件的时候千万不要在设置的时候写com.it.mapper应该用com/it/mapper否则等着报错吧