1. 添加jar包
Spring框架的jar包
springMVC的jar包
Mybatis框架的jar包
Oracle的驱动包
C3P0数据源框架的jar包
Jstl标签的jar包
Log4j日志框架的jar包
2. 设计实体类
2.1. Emp 将部门Dept属性设置为对象类型(多对一的关联关系)
2.2. Dept 将Emp属性设置为List<Emp>类型(一对多的关联关系)
3. 设计业务接口
3.1. 添加员工:int addEmp(Emp emp);
4. 配置EmpMapper.xml,实现EmpDao业务接口
4.1. 指定当前映射文件针对的业务接口全称
4.2. 将实体类的属性名和表的列名做映射(如果属性名与列名一致,则可以省略)
4.3. 配置多对一:
4.3.1. 一的方面Dept在Emp类中的属性名,
4.3.2. Dept在Emp表中的外键名称
4.3.3. Dept的类型
4.3.4. Select属性:指定调用的方法来为每一个Emp的Dept属性的子属性找到对应的值
4.4. 在Insert节点中拼写SQL语句,实现添加操作
5. 配置DeptMapping.xml,实现DeptDao业务接口
5.1. 配置一对多
5.1.1. 多的方面Emp在Dept类中的属性名
5.1.2. Emp的类型
5.1.3. 指定一个部门下的每个员工使用的结果映射resultMap,从而实现Emp与Dept连表查询后,员工的属性与连表结果的对应关系
6. 设计服务层Service,通过依赖注入DAO接口,实现业务
6.1. EmpService:服务层接口,根据业务需求,调用多个DAO层方法,实现复杂业务
6.2. EmpServiceImpl:将EmpDao接口作为属性,通过依赖注入,实现具体功能
7. 定义Controller控制器层:根据用户请求,调用Service层方法,完成请求的任务
8. 配置web.xml
8.1. 配置过滤器,解决中文乱码
8.2. 加载spring配置文件,统一管理其他框架的核心对象
8.3. 配置spring监听器,随时监听项目运行时需要的对象,使用依赖注入实现对象的创建与销毁
8.4. 加载springMVC的前置控制器DispatcherServlet,处理用户请求
9. 配置springmvc-common.xml
9.1. 如果需要转换特殊类型的数据,可以配置类型转换器ConversionServiceFactoryBean
9.2. 开启springMVC的注解:让Controller中的@RequestMapping注解生效
<mvc:annotation-driven ></mvc:annotation-driven>
9.3. 配置程序跳转路径的规则InternalResourceViewResolver
9.4. 开启spring注解:让Service,Controller层的组件依赖注入的功能生效
<context:component-scan base-package="com"></context:component-scan>
10. 配置mybatis-config.xml
10.1. 设置settings:指定mybatis自动映射规则autoMappingBehavior
10.2. 给所有实体类命别名typeAliases
10.3. 加载所有实体映射文件mappers
11. 配置spring-common.xml实现让spring框架来管理所有其他框架的核心对象
11.1. 加载数据库资源文件
11.2. 配置数据源
11.3. 注入SqlSessionFactory对象
11.4. 使用MapperScannerConfigurer对象自动扫描需要注入SqlSession对象的DAO层的实现类对象,自动为每个DAO层接口的实现对象注入一个由SqlSessionFactory对象提供的SqlSession对象
11.5. 配置spring的事务对象DataSourceTransactionManager:实现事务管理
11.6. 开启注解实现事务的功能
<tx:annotation-driven transaction-manager="tx" />
12. Jackson框架
12.1. 将程序的对象和json字符串互相转换
12.2. Jackson的jar包
12.3. 对象转换为json字符串
List<Emp> emps=new ArrayList<Emp>();
for (int i = 0; i < 3; i++) {
d=new Dept((i+1),"开发部"+(i+1),"上海"+(i+1));
e=new Emp((i+1), "jack"+(i+1), "coder"+(i+1), new Date(), 8888.8d+(i+1), 87777.8d+(i+1), d);
emps.add(e);
}
try {
ObjectMapper om=new ObjectMapper();
String str= om.writeValueAsString(emps);
System.out.println(str);
} catch (JsonProcessingException ex) {
ex.printStackTrace();
}
13. Ssm+ajax框架集成验证用户名是否存在
13.1. 设计DAO层接口方法:根据用户输入的姓名,查找表中存在该用户名的记录数
13.2. 使用XxxMapper.xml实现查询记录数的方法
<select id="findEmpByName" parameterType="String" resultType="java.lang.Integer" >
select count(1) from emp where ename=#{name}
</select>
13.3. 设计SERVICE层接口方法:根据方法返回的真假,以便判断用户名是否存在
public boolean checkUname(String name) {
int i=empDao.findEmpByName(name);
if (i>0) {
return true;
}else{
return false;
}
}
13.4. Controller层完成业务
@RequestMapping("/checkUname")
public void checkUname(HttpServletResponse response, String name) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
if (empService.checkUname(name) == true) {
out.print("<font color='red'>用户名已存在!</font>");
} else {
out.print("<font color='green'>用户名可用!</font>");
}
out.flush();
out.close();
}
13.5. 页面代码:通过AJAX获取用户名,传递到controller
$(function() {
$("#uname").blur(function() {
var uname = $(this).val();
$.ajax({
type : "POST",
url : "emp/checkUname",
data : "name="+uname,
success : function(msg) {
//直接将后台打印到前台的字符串,作为提示span元素的内容
$("#tip").html(msg);
}
});
});
});
13.6.
14. Ssm+Jackson+AJAX显示动态列表
14.1. Controller的方法参数使用@ResponseBody注解自动将后台获取的集合转换为json字符串,传递到前台
@RequestMapping("/list2")
public
// 指定需要使用jackson框架转换成json字符串的对象
@ResponseBody List<Emp> findAllEmps2() {
List<Emp> emps = empService.findAllEmps();
return emps;
}
14.2. 页面处理
$(function() {
$.ajax({
type : "POST",
url : "emp/list2",
success : function(msg) {
$.each(msg,function(index,item){
var d=new Date(item.hiredate);
var tr=$("<tr><td>"+item.ename+"</td><td>"+d.toLocaleString()+"</td><td>"+item.dept.dname+"</td></tr>");
$("#tab").append(tr);
});
}
});
});
15. Ssm多条件查询并分页显示列表
15.1. 设计接口方法
15.1.1. 根据多条件和当前页码,每页显示的行数,获取对象集合
15.1.2. 根据多条件和每页显示的行数,计算总行数
15.2. 使用XxxMapper.xml实现以上方法
<select id="findEmpByCondition" parameterType="java.util.HashMap" resultMap="empMap">
SELECT a.ename,a.hiredate,a.deptid,a.dname FROM (
SELECT e.*,d.dname,d.loc,ROWNUM r
FROM emp e
LEFT JOIN dept d
ON e.deptid=d.deptid
WHERE ROWNUM<=#{start}
<if test="eu.name!=null and eu.name!='' ">
AND e.ename LIKE #{eu.name}
</if>
<if test="eu.startDate!=null">
AND e.hiredate>=#{eu.startDate}
</if>
<if test="eu.endDate!=null">
AND e.hiredate<=#{eu.endDate}
</if>
<if test="eu.deptid!=null and eu.deptid!=0">
AND e.deptid=#{eu.deptid}
</if>
)a WHERE r>#{end}
</select>
<select id="calcTotalCount" parameterType="EmpUtil" resultType="java.lang.Integer" >
SELECT COUNT(1) FROM emp
<where>
<if test="eu.name!=null and eu.name!='' ">
ename LIKE #{eu.name}
</if>
<if test="eu.startDate!=null">
AND hiredate>=#{eu.startDate}
</if>
<if test="eu.endDate!=null">
AND hiredate<=#{eu.endDate}
</if>
<if test="eu.deptid!=null and eu.deptid!=0">
AND deptid=#{eu.deptid}
</if>
</where>
</select>
15.3. Controller层实现业务
15.3.1. 获取前台页面传递的条件对象,当前页码,每页显示行数
15.3.2. 根据获取的数据,构建DAO接口方法需要的HashMap类型的参数
15.3.3. 调用SERVICE层的方法,获取查询结果和查询到的总行数
15.3.4. 根据总行数和每页显示行数,计算出总页数
15.3.5. 使用request或者session作用域保存查询结果,当前页码,每页显示行数,总页数,查询条件
15.3.6. 跳转到目标页面
15.4. 页面的处理
15.4.1. 使用jstl标签判断request中是否保存了集合,如果没有集合,则返回后台Controller的分页方法,获取集合
15.4.2. 设计表单元素
15.4.2.1. 定义隐藏域,保存当前页码
15.4.2.2. 使用value属性,将用户每次输入的条件显示在输入框中
15.4.3. 使用jstl标签遍历集合
15.4.4. 设计分页的按钮:使用JavaScript脚本让用户翻页调用方法,重新改变当前页码,重新提交表单,以便将用户输入的条件和当前页面一起传递到后台,防止翻页时条件丢失