第5章MyBatis 动态SQL 附带SSM框架整合 系统管理员 2022-11-20 09:34 167阅读 0赞 # 第5章MyBatis 动态SQL 附带SSM框架整合 # > ***第5章MyBatis 动态SQL*** > 在实际应用开发过程中,我们往往需要写复杂的 SQL 语句,需要拼接,而拼接SQL语句又稍微不注意,由于引号,空格等缺失可能都会导致错误。 > **Mybatis提供了动态SQL,也就是可以根据用户提供的参数,动态决定查询语句依赖的查询条件或SQL语句的内容。** > ***第六章SSM框架整合*** > ***MyBatista—Spring MyBatis Spring*** > **三大框架整合过程**。个人认为使用框架并不是很难,关键要理解其思想,这对于我们提高编程水平很有帮助。不过,如果用都不会,谈思想就变成纸上谈兵了!!!先技术,再思想。实践出真知。 -------------------- ### 第5章MyBatis 动态SQL附加:SSM框架整合……第6章 ### * 第5章MyBatis 动态SQL 附带SSM框架整合 * * 5.1 MyBatis动态SQL简介 * 5.2 if 和 where 标签 * 5.3 trim 标签 * 5.4 set 标签 * 5.5 choose(when、otherwise) 标签 * 5.6 foreach 标签 * * * list批量插入 * list集合参数 * map参数 * 5.7 sql * 第6章:SSM框架整合 * * 6.1 整合注意事项 * 6.2整合思路、步骤 * 6.3整合的配置 * * 6.3.1 web.xml· * 6.3.2 Spring配置 * 6.3.3 SpringMVC配置 * 6.3.4 MyBatis配置 * 6.3.5 Spring 整合MyBatis 配置 * Log4j的配置 * 6.4 整合测试 ## 5.1 MyBatis动态SQL简介 ## 1. 动态 SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作 2. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似 3. MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作 If. choose (when, otherwise) trim (where, set) foreach 4. OGNL( Object Graph Navigation Language )对象图导航语言,这是一种强大的 表达式语言,通过它可以非常方便的来操作对象属性。 类似于我们的EL,SpEL等 访问对象属性: person.name 调用方法: person.getName() 调用静态属性/方法: @java.lang.Math@PI @java.util.UUID@randomUUID() 调用构造方法: new com.atguigu.bean.Person(‘admin’).name **运算符: +,-\*,/,%** **逻辑运算符: in,not in,>,>=,<,<=,==,!=** 注意:xml中特殊符号如”,>,<等这些都需要使用转义字符 -------------------- ## 5.2 if 和 where 标签 ## 1)If用于完成简单的判断. 2)Where用于解决SQL语句中where关键字以及条件中第一个and或者or的问题 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.beans.Employee"> select id , last_name ,email , gender from tbl_employee <where> <if test="id!=null"> and id = #{ id} </if> <if test="lastName!=null && lastName!="""> and last_name = #{ lastName} </if> <if test="email!=null and email.trim()!=''">(这里调了去空格的方法) and email = #{ email} </if> <if test=""m".equals(gender) or "f".equals(gender)"> and gender = #{ gender} </if> </where> </select> -------------------- ## 5.3 trim 标签 ## 1. Trim 可以在条件判断完的SQL语句前后 添加或者去掉指定的字符 prefix: 添加前缀 prefixOverrides: 去掉前缀 suffix: 添加后缀 suffixOverrides: 去掉后缀 <select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.beans.Employee"> select id , last_name ,email , gender from tbl_employee <trim prefix="where" suffixOverrides="and"> <if test="id!=null"> id = #{ id} and </if> <if test="lastName!=null && lastName!="""> last_name = #{ lastName} and </if> <if test="email!=null and email.trim()!=''"> email = #{ email} and </if> <if test=""m".equals(gender) or "f".equals(gender)"> gender = #{ gender} </if> </trim> </select> -------------------- ## 5.4 set 标签 ## 1. set 主要是用于解决修改操作中SQL语句中可能多出逗号的问题 <update id="updateEmpByConditionSet"> update tbl_employee <set> <if test="lastName!=null && lastName!="""> last_name = #{ lastName}, </if> <if test="email!=null and email.trim()!=''"> email = #{ email} , </if> <if test=""m".equals(gender) or "f".equals(gender)"> gender = #{ gender} </if> </set> where id =#{ id} </update> -------------------- ## 5.5 choose(when、otherwise) 标签 ## 1. choose 主要是用于分支判断,类似于java中的switch case,只会满足所有分支中的一个 <select id="getEmpsByConditionChoose" resultType="com.atguigu.mybatis.beans.Employee"> select id ,last_name, email,gender from tbl_employee <where> <choose> <when test="id!=null"> id = #{ id} </when> <when test="lastName!=null"> last_name = #{ lastName} </when> <when test="email!=null"> email = #{ email} </when> <otherwise> gender = 'm' </otherwise> </choose> </where> </select> -------------------- ## 5.6 foreach 标签 ## 1. **foreach** 主要用户循环迭代 **collection:** 要迭代的集合 **item:** 当前从集合中迭代出的元素 **open:** 开始字符 **close:** 结束字符 **separator:** 元素与元素之间的分隔符 **index:** 迭代的是List集合: index表示的当前元素的下标 迭代的Map集合: index表示的当前元素的key <select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.beans.Employee"> select id , last_name, email ,gender from tbl_employee where id in <foreach collection="ids" item="curr_id" open="(" close=")" separator="," > #{ curr_id} </foreach> </select> #### list批量插入 #### <!--动态Sql: foreach标签, 批量插入--> <insert id="dynamicSqlInsertList" useGeneratedKeys="true" keyProperty="id"> insert into users (name, age, county, date) values <foreach collection="list" item="user" separator="," > (#{ user.name}, #{ user.age}, #{ user.county}, #{ user.date}) </foreach> </insert> ![!!!!!!!!1][1] 从结果可以看出,我们一下插入了两条数据,每条数据之间使用“,”进行分割,separator="," 的作用就是如此。其中< foreach >标签内部的属性务必加上item.。 #### list集合参数 #### <!--动态Sql: foreach标签, list参数查询--> <select id="dynamicSqlSelectList" resultType="com.lks.domain.User"> SELECT * from users WHERE id in <foreach collection="list" item="id" open="(" close=")" separator="," > #{ id} </foreach> </select> ![!!!!!!!!2][2] 可以看出我们的 SQL 语句新增了:( ? , ? ) ,前后的括号由 open="(" close=")" 进行控制,用“?”占位符占位,并通过separator以:“,”隔开,内部两个循环遍历出的元素。array 集合与 list 的做法也是类似的: <!--动态Sql: foreach标签, array参数查询--> <select id="dynamicSqlSelectArray" resultType="com.lks.domain.User"> select * from users WHERE id in <foreach collection="array" item="id" open="(" close=")" separator=","> #{ id} </foreach> </select> #### map参数 #### < map> 标签需要结合MyBatis的参数注解 @Param()来使用,需要告诉Mybatis配置文件中的collection="map"里的map是一个参数: <!--动态Sql: foreach标签, map参数查询--> <select id="dynamicSqlSelectMap" resultType="com.lks.bean.User"> select * from users WHERE <foreach collection="map" index="key" item="value" separator="="> ${ key} = #{ value} </foreach> </select> 需要主要$\{\}和\#\{\}的使用。 -------------------- ## 5.7 sql ## 1. sql 标签是用于抽取可重用的sql片段,将相同的,使用频繁的SQL片段抽取出来,单独定义,方便多次引用. 2. 抽取SQL: <sql id="selectSQL"> select id , last_name, email ,gender from tbl_employee </sql> 1. 引用SQL: <include refid="selectSQL"></include> -------------------- # 第6章:SSM框架整合 # > 使用框架都是较新的版本: > Spring 4.0.2 RELEASE > Spring MVC 4.0.2 RELEASE > MyBatis 3.2.6 ## 6.1 整合注意事项 ## 1)查看不同MyBatis版本整合Spring时使用的适配包; ![版本整合表][2020102809313896.png_pic_center] 1. 下载整合适配包 链接: [https://github.com/mybatis/spring/releases][https_github.com_mybatis_spring_releases]. 2. 官方整合示例,jpetstore 链接: [https://github.com/mybatis/jpetstore-6][https_github.com_mybatis_jpetstore-6]. ## 6.2整合思路、步骤 ## ***1) 搭建环境*** 创建一个动态的WEB工程 导入SSM需要使用的jar包 导入整合适配包 导入其他技术的一些支持包 连接池 数据库驱动 日志… ***2) Spring + Springmvc*** 在web.xml中配置: Springmvc的前端控制器 实例化Spring容器的监听器 字符编码过滤器 REST 过滤器 创建Spring的配置文件: applicationContext.xml:组件扫描、 连接池、 事务… 创建Springmvc的配置文件: springmvc.xml : 组件扫描、 视图解析器 mvc:... ***3) MyBatis*** 创建MyBatis的全局配置文件 编写实体类 Mapper接口 Mapper映射文件 ***4) Spring + MyBatis :*** MyBatis的 SqlSession的创建 . MyBatis的 Mapper接口的代理实现类 ***5) 测试: REST CRUD*** 课堂: 查询所有的员工信息,列表显示 课下: 增删改 ## 6.3整合的配置 ## ### 6.3.1 web.xml· ### <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 字符编码过滤器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- REST 过滤器 --> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 实例化SpringIOC容器的监听器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Springmvc的前端控制器 --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> ### 6.3.2 Spring配置 ### <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- 组件扫描 --> <context:component-scan base-package="com.atguigu.ssm"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 连接池 --> <context:property-placeholder location="classpath:db.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 事务 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/> </beans> ### 6.3.3 SpringMVC配置 ### <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 组件扫描 --> <context:component-scan base-package="com.atguigu.ssm" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> <mvc:default-servlet-handler/> <mvc:annotation-driven/> </beans> ### 6.3.4 MyBatis配置 ### 1. 全局文件的配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- Spring 整合 MyBatis 后, MyBatis中配置数据源,事务等一些配置都可以 迁移到Spring的整合配置中。MyBatis配置文件中只需要配置与MyBatis相关 的即可。 --> <!-- settings: 包含很多重要的设置项 --> <settings> <!-- 映射下划线到驼峰命名 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 设置Mybatis对null值的默认处理 --> <setting name="jdbcTypeForNull" value="NULL"/> <!-- 开启延迟加载 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 设置加载的数据是按需还是全部 --> <setting name="aggressiveLazyLoading" value="false"/> <!-- 配置开启二级缓存 --> <setting name="cacheEnabled" value="true"/> </settings> </configuration> 1. SQL映射文件配置 <?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.atguigu.ssm.mapper.EmployeeMapper"> <!-- public List<Employee> getAllEmps(); --> <select id="getAllEmps" resultMap="myEmpsAndDept" > select e.id eid, e.last_name,e.email,e.gender, d.id did, d.dept_name from tbl_employee e ,tbl_dept d where e.d_id = d.id </select> <resultMap type="com.atguigu.ssm.beans.Employee" id="myEmpsAndDept"> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> <association property="dept" javaType="com.atguigu.ssm.beans.Department"> <id column="did" property="id"/> <result column="dept_name" property="departmentName"/> </association> </resultMap> </mapper> ### 6.3.5 Spring 整合MyBatis 配置 ### <!-- Spring 整合 Mybatis --> <!--1. SqlSession --> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据源 --> <property name="dataSource" ref="dataSource"></property> <!-- MyBatis的配置文件 --> <property name="configLocation" value="classpath:mybatis-config.xml"></property> <!-- MyBatis的SQL映射文件 --> <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"></property> <property name="typeAliasesPackage" value="com.atguigu.ssm.beans"></property> </bean> <!-- Mapper接口 MapperScannerConfigurer 为指定包下的Mapper接口批量生成代理实现类.bean的默认id是接口名首字母小写. --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.atguigu.ssm.mapper"></property> </bean> <!-- <mybatis-spring:scan base-package="com.atguigu.ssm.mapper"/> --> ### Log4j的配置 ### > 为了方便调试,一般都会使用日志来输出信息,Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。 Log4j的配置很简单,而且也是通用的,下面给出一个基本的配置,换到其他项目中也无需做多大的调整,如果想做调整或者想了解Log4j的各种配置,参看我转载的一篇博文,很详细: 链接: [http://blog.csdn.net/zhshulin/article/details/37937365][http_blog.csdn.net_zhshulin_article_details_37937365]. 下面给出配置文件目录: ![在这里插入图片描述][20201028100417765.png_pic_center] log4j.properties #定义LOG输出级别 log4j.rootLogger=INFO,Console,File #定义日志输出目的地为控制台 log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.Target=System.out #可以灵活地指定日志输出格式,下面一行是指定具体的格式 log4j.appender.Console.layout = org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n #文件大小到达指定尺寸的时候产生一个新的文件 log4j.appender.File = org.apache.log4j.RollingFileAppender #指定输出目录 log4j.appender.File.File = logs/ssm.log #定义文件最大大小 log4j.appender.File.MaxFileSize = 10MB # 输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志 log4j.appender.File.Threshold = ALL log4j.appender.File.layout = org.apache.log4j.PatternLayout log4j.appender.File.layout.ConversionPattern =[%p] [%d{ yyyy-MM-dd HH\:mm\:ss}][%c]%m%n ## 6.4 整合测试 ## > 至此已经完成了SSM三大框架的整合了,接下来测试一下,如果成功了,那么恭喜你,如果失败了,继续调试吧,作为程序员就是不停的与BUG做斗争! 1. **编写页面,发送请求:http://localhost:8888/ssm/employees** 2. **编写Handler,处理请求,完成响应** 3. **在页面中获取数据,显示数据** [1]: /images/20221120/3b0c656083164d01aa33a3c3fc60e75c.png [2]: /images/20221120/5da3a0f166f143dc94295a8f34fc732b.png [2020102809313896.png_pic_center]: /images/20221120/229bd1b633ae4dd8a769f4cec72326f5.png [https_github.com_mybatis_spring_releases]: https://github.com/mybatis/spring/releases [https_github.com_mybatis_jpetstore-6]: https://github.com/mybatis/jpetstore-6 [http_blog.csdn.net_zhshulin_article_details_37937365]: http://blog.csdn.net/zhshulin/article/details/37937365 [20201028100417765.png_pic_center]: /images/20221120/9c39c3ac037e44929016518f5f94f06c.png
还没有评论,来说两句吧...