SSM整合&高级查询
第一部分:SS【Spring+SpringMvc】整合
一. Spring整合SpringMvc
=========================第一阶段
|-- 创建动态web工程,名称【day0412-sssm
|-- 注意:web.xml和classes的位置都在WEB-INF下
测试1:在根路径WebContent下新建index.jsp进行测试
=========================第二阶段
|-- 导入jar包
|-- 课件资源中所有的jar包【昨天资源获取共 - 31个】
|-- servlet.jar + jsp.jar【其他工程获取 - 2个】
|-- Junit4的库【从工程直接添加,也可以在测试的时候添加】
|-- web.xml
|-- 前端控制器,加载applicationContext-mvc.xml【参考以前工程和课件】
|-- 字符编码过滤器【参考课件】
|-- 创建资源文件Source Folder,名称【resources】
|-- 在【resources】下创建applicationContext-mvc.xml【参考昨天的工程,copy之后要写注释,注意格式】
|-- 1.扫描包路径【注意这里只扫描cn.itsource.controller包,不要全都扫描,即cn.itsource,各司其职】
|-- 2.静态资源放行
|-- 3.开启Spring对Mvc的支持,能够使用@RequestMapping注解
|-- 4.配置视图解析器
测试2:测试当前环境
|-- 在src创建包cn.itsource.controller
|-- 在cn.itsource.controller包下创建测试TestController,
|-- 编写业务方法test方法使用/test进行测试,跳转到index.jsp【使用默认转发】
=========================第三阶段
问题:Spring与SpringMvc配置分离,各司其职
|-- 在【resources】下创建applicationContext.xml【SpringMvc的配置】
|-- 1.扫描包路径,只扫描cn.itsource.service包
|-- 在src创建包cn.itsource.service
|-- 使用监听器加载applicationContext.xml配置文件,打开web.xml配置监听器
<!-- 1.1 Spring容器初始化 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
测试3:测试当前环境,在测试2的基础之上,在发送一次请求看下结果
二. Spring整合SpringMvc再整合Mybatis
|-- 注意:
|-- 过滤器,监听器,Servlet都是web组件,都需要在web.xml中配置
|-- 前端控制器是一个Servlet,一个请求来了首先要交给前端控制器,然后匹配请求,
所以前端控制器加载SpringMvc的配置文件appliacationContext-mvc.xml,SpringMvc是
控制层的框架,扫描包只扫描controller
|-- 监听器在初始化参数中加载Spring的配置文件appliacationContext.xml
|-- appliacationContext.xml上下文对象创建的时候加载的,称为父容器,appliacationContext-mvc.xml是子容器
子容器可以用父容器的东西,父容器不可以用子容器的东西,跟Java的继承是一个道理
=======================整合Mybatis:第一阶段=
分析:要得到Mapper代理对象【整合包】 -> 要获取SqlSessionFactory对象【整合包】 -> 数据库连接池对象【BasicDataSource】 -> 属性文件信息
Spring管理对象:如果由于一个类中有无参构造,都可以交给Spring去管理,Spring除了管理对象,还可以管理属性文件【.properties】
|-- Spring管理属性文件db.properties
|-- 在【resources】下创建属性文件db.properties【四大金刚 - 从其他工程拷贝】
|-- 在appliacationContext.xml加载属性文件,注意属性文件中key是否有前缀
|-- Spring管理数据源对象BasicDataSource【参考文档】
测试:在SpringTest中测试BasicDataSource对象【SpringMvc第一天】
=======================整合Mybatis:第二阶段=
|-- Spring管理SqlSessionFactory
|-- Spring管理Mapper代理对象
|-- 创建包cn.itsource.mapper
|-- 在包cn.itsource.mapper下创建接口EmpMapper,先不写方法
|-- 在包cn.itsource.mapper下创建mapper文件EmpMapper.xml,并清空内容【参考以前的工程】
|-- 创建包cn.itsource.domain,在改包写新建Emp实体类,先不写字段
二. 使用SSM查询emp表的所有
=======================准备工作
1.引入log4j的日志配置放在resources下:log4j.properties【参考以前工程mybatis】
2.引入资源ssm.sql【参考课件随堂资源中】
3.将show.jsp放在web根目录WebContext下【参考课件随堂资源中】
4.根据ssm数据库的表emp创建实体类【自己手写 or 可以用之前有个工具类】
5.修改db.properties属性文件中的数据库为ssm
===========================查询所有
1.找请求和参数:在index.jsp中
<jsp:forward page="emp/show"></jsp:forward>
2.编写控制器:
@Controller
@RequestMapping("/emp")
public class EmpController {
@Autowired //从容器中去找IEmpService类型或其子类的类型,找到之后赋值给当前字段 //预支 -- 提前用了,后期再换
private IEmpService service;//给字段赋值 = 注入
@RequestMapping("/show")
public String show(Model model){
//第一大职责:匹配请求 +获取请求参数
//第二大职责:调用业务代码
List<Emp> emps = service.findAll();
//第三大职责:响应跳转
model.addAttribute("emps", emps);
return "show";
}
}
3.编写Service
@Service //还了
public class EmpServiceImpl implements IEmpService{
@Autowired
private EmpMapper mapper;
@Override
public List<Emp> findAll() {
return mapper.findAll();
}
}
4.编写Mapper接口和mapper映射文件
public interface EmpMapper {
List<Emp> findAll();
}
<mapper namespace="cn.itsource.mapper.EmpMapper">
<select id="findAll" resultType="emp">
select * from emp
</select>
</mapper><!-- xml解析:dom4j -->
5.在emp表中最后面添加字段deptno
6.重构Emp实体类
=======================高级查询初体验==========================
Controller:
@RequestMapping("/findByCondition")
public String findByCondition(Emp emp,Model model){
List<Emp> emps = service.findByCondition(emp);
model.addAttribute("emps", emps);
return "show";
}
Service:
@Override
public List<Emp> findByCondition(Emp emp) {
return mapper.findByCondition(emp);
}
Mapper:
List<Emp> findByCondition(Emp emp);
Mapper文件:
<select id="findByCondition" parameterType="emp" resultType="emp">
select * from emp
</select>
MyBatis
一:Mybatis动态SQL
简介:使用Mybatis动态SQL与JSTL很相似,可以在xml中构建不同的SQL语句
网页中:
<form action="${pageContext.request.contextPath}/emp/findByCondition">
<div>
<h1>员工列表显示</h1>
姓名:<input type="text" name="ename" value="${emp.ename }"/>  
地址:<input type="text" name="address" value="${emp.address }"/>  
部门编号:
<selecsd("deptno").value="${emp.deptno}";
document.getElementById("sal").value="${emp.sal}";
</script>
</form>
1.if标签
作用:两个作用:1.进行判断,条件通过就拼接标签中的内容 2.会自动加上一个空格
需求1【第一种方式】:查询信息,如果部门编号不为空,拼接
where deptno = #{deptno}
<!-- if标签:相当于java中的if分支语句 -->
<select id="findByCondition" resultType="emp" parameterType="emp">
select * from emp
<!-- if元素:满足指定条件时追加if元素中的SQL,不满足不追加 -->
<if test="deptno != null">
where deptno = #{deptno}
</if>
</select>
<!-- 缺点:只有一个条件没有问题,如果有多个条件如下写呢? -->
注意:
A.对于字符串变量,需要对null值和空字符串进行判断,并且要去掉两端空白,其他类型只需要进行null判断
B.对于基本类型的变量,如果用实体这种方式接收,前台是空字符串的话,会报异常,所以实体类实例变量最好用其包装类作为基本类型的替换类型
C.对于网页标记中的元素,如果不写value属性,那么就默认value值为标签中的内容
D.如果有多个参数,可以使用或者使用下面的这种方式也行
需求2【第一种方式】:查询信息,如果部门编号不为空,拼接where deptno = #{deptno},如果姓名和地址不为空就拼接姓名和地址
<select id="findByCondition" resultType="emp" parameterType="emp">
select * from emp where 1 = 1
<if test="deptno != null">
and deptno = #{deptno}
</if>
<if test='ename != null and !"".equals(ename.trim())'>
and ename like CONCAT('%',trim(#{ename}),'%')
</if>
<if test='address != null and !"".equals(address.trim())'>
and address like CONCAT('%',trim(#{address}),'%')
</if>
</select>
2.where标签
作用:两个作用:
1.拼接了一个where
2.忽略第一个多余的and 或者 or
3.自动加空格
需求1【第二种方式】:查询信息,如果部门编号不为空,拼接
where deptno = #{deptno}
<select id="findByCondition" resultType="emp" parameterType="emp">
select * from emp
<where>
<if test="deptno != null">
and deptno = #{deptno}
</if>
</where>
</select>
需求2【第二种方式】:查询信息,如果部门编号不为空,拼接where deptno = #{deptno},如果姓名和地址不为空就拼接姓名和地址
<select id="findByCondition" resultType="emp" parameterType="emp">
select * from emp
<where>
<if test="deptno != null">
and deptno = #{deptno}
</if>
<if test='ename != null and !"".equals(ename.trim())'>
and ename like CONCAT('%',trim(#{ename}),'%')
</if>
<if test='address != null and !"".equals(address.trim())'>
and address like CONCAT('%',trim(#{address}),'%')
</if>
</where>
</select>
3.choose标签
作用:choose标签:相当于java中的switch…case,通常与when和otherwise搭配使用
需求3:如果是3000,查询<3000以下的。如果是5000,查询3000-5000的。如果是8000,查询5000-8000的。如果是8001,查询8000以上的。
<select id="findByCondition" resultType="emp" parameterType="emp">
select * from emp
<where>
<if test="deptno != null">
and deptno = #{deptno}
</if>
<if test='ename != null and !"".equals(ename.trim())'>
and ename like CONCAT('%',trim(#{ename}),'%')
</if>
<if test='address != null and !"".equals(address.trim())'>
and address like CONCAT('%',trim(#{address}),'%')
</if>
<if test="sal != null">
<choose>
<when test="sal == 3000">
and sal <= #{sal}
</when>
<when test="sal == 5000">
and sal <= #{sal} and sal > #{sal}-2000
</when>
<when test="sal == 8000">
and sal <![CDATA[ <= ]]> #{sal} and sal > #{sal}-3000
</when>
<when test="sal == 8001">
sal > #{sal} - 1
</when>
</choose>
</if>
</where>
</select>
注意:在xml的转义字符:
符号: < <= > >= & ' "
替换符号 < <= > >= & ' "
【gt -> greater than(大于 )lt -> less than(小于)】
或者可以用CDATA代码段:
大于等于 <![CDATA[ >= ]]>
小于等于 <![CDATA[ <= ]]>
4.使用抽取和调用
使用抽取:
<sql id="address">
<if test='address != null and !"".equals(address.trim())'>
and address like CONCAT('%',trim(#{address}),'%')
</if>
</sql>
使用<include>调用:
<select id="findByCondition" resultType="emp" parameterType="emp">
select * from emp
<where>
<if test="deptno != null">
and deptno = #{deptno}
</if>
<if test='ename != null and !"".equals(ename.trim())'>
and ename like CONCAT('%',trim(#{ename}),'%')
</if>
<include refid="address"></include>
<if test="sal != null">
<choose>
<when test="sal == 3000">
and sal <= #{sal}
</when>
<when test="sal == 5000">
and sal <= #{sal} and sal > #{sal}-2000
</when>
<when test="sal == 8000">
and sal <![CDATA[ <= ]]> #{sal} and sal > #{sal}-3000
</when>
<when test="sal == 8001">
sal > #{sal} - 1
</when>
</choose>
</if>
</where>
<select>