Helloxxm

 

一、课程介绍

         

                模仿企业对于人员的管理,包括部门信息,人员信息,日志信息记录和浏览的管理

 

              

 

 

二、案例展示及概述

        

 

三、案例准备及控制模块开发

         

            

                     

                          

                 创建表后再添加约束,这样就不用担心表的创建顺序。

                示例:给staff表添加外键

                alter table staff add constraint fk_staff(外键表名)_dep(主键表名)【约束名foreign key(did)(以当前表的哪个字段进行关联 references department(id)(关联到该表的那个字段);

             

                  

                       

                Spring全局配置需要做的事情,第一、Spring和Mybatis的整合,实质就是将Mybatis管理的SqlSessionFactory对象和持久化对象交给Spring管理

                                                                 第二、声明式事务,需配置事务管理器、通知、以及将通知织入

                                                                 第三、全局扫描,包扫面和aspectj表达式扫描

 

               mybatis.xml配置文件模板实例

 

<?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>
    <!--propertis配置,用于加载外部的properties配置文件-->
    <properties resource="db.properties"></properties>
    <!--environments 主要用于进行数据源的配置
        可以配置多个数据源,通过default属性来指定当前项目运行过程中使用的是哪个数据源
        environmets中的default属性对应于environment中的id,对应哪个即使用那个独立的数据源-->
    <environments default="development">
        <environment id="development">
            <!--transactionManager用于配置事务管理,默认情况下使用JDBC事务管理-->
            <transactionManager type="JDBC"/>
            <!--dataSource具体数据源的链接信息,type属性用于指定是否使用连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
        <environment id="product">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>

    </environments>

    <!--mappers主要用于配置外部的映射配置文件
      在主配置文件中需要引入加载外部的映射配置文件-->
    <mappers>
        <!--mapper主要配置引入某一个具体的映射配置文件,resource进行路径方式的引入-->
        <mapper resource="mapper/usersMapper.xml"/>
    </mappers>
</configuration>

 

           Spring.xml全局配置

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="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.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--spring整合mybatis,即把mybatis原本管理的持久化操作对象和SqlSessionFactory对象交给spring管理-->
    <!--数据源-->
    <bean id="dateSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url"
                  value="jdbc:mysql://localhost:3306/sm?useUnicode=true&amp;characterEncoding=utf-8"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <!--session工厂-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dateSource"></property>
        <property name="typeAliasesPackage" value="com.imooc.sm.entity"></property>
    </bean>
    <!--持久化对象,对应于mybatis.xml映射器接口的配置-->
       <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
           <property name="basePackage" value="com.imooc.sm.dao"></property>
           <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
       </bean>

    <!--声明式事务-->
     <!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dateSource"></property>
    </bean>
    <!--通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="search*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!--织入-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.imooc.sm.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>
    <!--全局扫描-->
    <context:component-scan base-package="com.imooc.sm"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>                                      

                  

为什么要有核心控制器(也是一个Servlet):
当用户向web容器发送请求时,web容器会根据url判断这个请求是否该用Servlet以及用哪个Servlet处理。判断完成后它会构造出Servlet对象然后进行初始化,之后再调用service方法对请求进行处理。
但是,Servlet对象由Web容器进行管理,service对象、dao对象由ioc容器进行管理。Servlet对象处理用户请求时需要调用Service对象,(根据IoC思想,你需要对象我就可以帮你注入这个对象,
但是无法实现。因为servlet对象不再IoC容器里,所以没办法注入他需要的对象)所以在Servlet对象无法使用spring_ioc进行对象的注入。 解决:核心控制器。 用户发送请求到web容器,web容器将请求全部交给核心控制器,核心控制器不做具体操作,只是判断该调用哪个控制器进行处理。 又因为核心控制器也是一个对象且是由我们写的,所以可以将这个放到ioc容器里。再从ioc容器里获取对象。
核心控制器干什么: 1、解析url得到ioc容器里小控制器的bean的名字。
2、处理这一次请求时获得这个请求要用的方法。通过bean的名字在ioc容器中把这个bean对象(即最终进行处理的控制器)拿出来,然后再通过方法名反射执行该方法。

 核心控制器代码

package com.imooc.sm.global;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class DispatchServlet extends GenericServlet {
    private ApplicationContext context;

    //在Servlet初始化时就生成Ioc容器,从而只执行一次,不会每次都加载配置文件
    @Override
    public void init() throws ServletException {
        super.init();
        context = new ClassPathXmlApplicationContext("spring.xml");
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //强转后才能获得请求路径
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        /*
        使用核心控制器的相关规范:1.访问路径格式 存在两种格式 /staff/add(方法名).do类型和login.do类型
                              2.控制器的命名  BeanName 应如  staffController
                              3.定义处理请求的实际方法格式  public void add(httpServletRequest,httpServletResponse){}
         */
        //获取url,去掉前面的“/”才是需要的url
        String path = httpServletRequest.getServletPath().substring(1);//相当于substring(0,1)
        System.out.println(httpServletRequest.getServletPath()+"===="+httpServletRequest.getContextPath());
        //获取BeanName和处理此次请求的方法
        String beanName = null;
        String methodName = null;
        int index = path.indexOf(\'/\');
        //判断路径格式类型
        if (index != -1) {
            beanName = path.substring(0, index) + "Controller";
            methodName = path.substring(index + 1, path.indexOf(".do"));
        } else {
            beanName = "selfController";
            methodName = path.substring(0, path.indexOf(".do"));
        }
        //访问IOC容器有beanName获取对象
        //获取Spring上下文

        Object object = context.getBean(beanName);
        try {
            //通过反射获取方法
            Method method = object.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //执行方法
            try {
                method.invoke(object, httpServletRequest, httpServletResponse);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

四、部门及员工管理实现

           1 ) 功能实现

                   

                 2)部门管理实现-业务

                   

         Dao接口与Sql映射文件(分两部分配置实体类和数据表的对应关系、持久化接口中的操作方法对应的sql):

              

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Dao接口与Sql映射-->
<mapper namespace="com.imooc.sm.dao.DepartmentDao">
<!--实体类和表的对应关系-->
    <!--实体类属性和数据库表字段的映射关系-->
    <!--配置结果集,type为实体类类名,此处配置了能使用类名简称-->
    <resultMap id="resultMap" type="Department">
        <!--属性对应字段为主键时用id标签,其他则用result标签-->
        <id property="id" column="id" javaType="Integer"/>
        <result property="name" column="name" javaType="String"/>
        <result property="address" column="address" javaType="String"/>
    </resultMap>
<!--持久化操作接口中操作方法对应的sql-->
<!--配置sql,dao接口有多少个方法配置多少个sql,sql的id为方法名-->
    <!--parameterType设置方法参数类型,insert语句需要调用数据库自增的规范,故要设置useGeneratedKeys-->
    <insert id="insert" parameterType="Department" useGeneratedKeys="true">
        insert into department(name,address) values(#{name},#{address})
    </insert>
    <delete id="delete" parameterType="Integer">
        delete from department where id=#{id}
    </delete>
    <update id="update" parameterType="Department">
        update department set name=#{name},address=#{address} where id=#{id}
    </update>
    <select id="selectById" parameterType="Integer" resultMap="resultMap">
        select * from department where id=#{id}
    </select>
    <select id="selectAll" resultMap="resultMap">
        select * from department
    </select>
</mapper>

 

                           3)部门管理实现-界面

 

           

 

                          4)员工管理实现-业务

           

员工关联部门,获取员工对象时希望也能获取关联的复杂的部门对象

       1) 实体类中需要先定义关联的对象            private Department department

       2)配置文件中定义    

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.sm.dao.StaffDao">
    <resultMap id="resultMap" type="Staff">
        <id property="id" column="id" javaType="Integer"/>
        <result property="account" column="account" javaType="String"/>
        <result property="password" column="password" javaType="String"/>
        <result property="status" column="status" javaType="String"/>
<!--关联字段did-->
<result property="did" column="did" javaType="Integer"/> <result property="name" column="name" javaType="String"/> <result property="sex" column="sex" javaType="String"/> <result property="idNumber" column="id_number" javaType="String"/> <result property="workTime" column="work_time" javaType="java.util.Date"/> <result property="leaveTime" column="leave_time" javaType="java.util.Date"/> <result property="bornDate" column="born_date" javaType="java.util.Date"/> <result property="info" column="info" javaType="String"/>
<!--想要获取的复杂对象-->
<association property="department" column="did" javaType="Department" select="com.imooc.sm.dao.DepartmentDao.selectById" /> </resultMap> <insert id="insert" parameterType="Staff" useGeneratedKeys="true"> insert into staff(account,password,status,did,name,sex,id_number,work_time,leave_time,born_date,info) values(#{account},#{password},#{status},#{did},#{name},#{sex},#{idNumber},#{workTime},#{leaveTime},#{bornDate},#{info}) </insert> <delete id="delete" parameterType="Integer"> delete from staff where id=#{id} </delete> <update id="update" parameterType="Staff"> update staff set account=#{account},password=#{password},status=#{status}, did=#{did},name=#{name},sex=#{sex},id_number=#{idNumber}, work_time=#{workTime},leave_time=#{leaveTime},born_date=#{bornDate},info=#{info} where id=#{id} </update> <select id="selectById" parameterType="Integer" resultMap="resultMap"> select * from staff where id=#{id} </select> <select id="selectAll" resultMap="resultMap"> select * from staff </select> </mapper>

 

 

 

 

 

 

默认登陆密码设置可通过交给SpringIOC产生bean对象时就设置为默认属性

            

@Resource
    private StaffDao staffDao;

    public void add(Staff staff) {
        staff.setPassword("123456");
        staff.setWorkTime(new Date());
        staff.setStatus("正常");
        staffDao.insert(staff);
    }

 

          

 

 

五、登录与个人中心实现

              

登录过滤器;

package com.imooc.sm.global;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

//该过滤器功能:登录后才能访问后台功能,不能直接跳过登录通过url访问
public class LoginFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        
        HttpServletRequest request=(HttpServletRequest)servletRequest;
        HttpServletResponse response=(HttpServletResponse)servletResponse;

        String path=request.getServletPath();
        //判断该路径中是否包含login,如果有则不过滤放过
        if (path.toLowerCase().indexOf("login")!=-1){
            filterChain.doFilter(request,response);
        }else {
            HttpSession session=request.getSession();
            //判断session中是否保存用户信息
            Object object=session.getAttribute("USER");
            if (object!=null){
                filterChain.doFilter(request,response);
            }else {
                //拦截的url可能是一级目录形式,也可能是二级,故此处要用绝对路径
                response.sendRedirect(request.getContextPath()+"/toLogin.do");
            }
        }
    }

    public void destroy() {

    }
}

六、日志处理实现(切面编程注入)

        实现从底层开始实现,先创建实体类,创建持久化操作接口,配置持久化接口和sql映射文件(.xml),业务层接口及实现类,表现层(什么时候记录日志,记录日志需要考虑操作源,操作源保存在session中在web层,处理用户请求时开始记录日志)

             

 

分类:

技术点:

相关文章: