整体介绍

◆需求说明与环境准备 ◆开发基于RBAC的访问控制模块 ◆开发多级请假审批流程

办公自动化OA系统

◆办公自动化系统(Office Automation)是替代传统办公的解决方案 ◆OA系统是利用软件技术构建的单位内部办公平台,用于辅助办公 ◆利用OA系统可将办公数据数字化,可极大提高办公流程执行效率

需求介绍

◆MK办公OA系统要求采用B/S架构设计开发 ◆HR为每一位员工分配系统账户,员工用此账户登录系统 ◆公司采用分级定岗,从1-8依次提升,不同岗位薪资水平不同 ◆6级(含)以下员工为业务岗,对应人员执行公司业务事宜 ◆7-8级为管理岗,其中7级为部门经理,8级为总经理 ◆业务岗与管理岗员工可用系统功能不同,要求允许灵活配置

请假流程

◆公司所有员工都可以使用”请假申请”功能申请休假 ◆请假时间少于72小时,部门经理审批后直接通过 ◆请假时间大于72小时,部门经理审批后还需总经理进行审批 ◆部门经理只允许批准本部门员工申请 ◆部门经理请假需直接由总经理审批 ◆总经理提起请假申请,系统自动批准通过

搭建基础架构

框架&组件

◆MySQL8 ◆Mybatis3.5 ◆Alibaba Druid ◆Servlet3.1 ◆Vue3.x ◆Element Plus

准备工作

数据库:

新建连接localhost,新建数据库imooc_oa

JavaWeb工程: 创建Maven工程

在java文件夹下新建包com.imooc.oa 新建Test.java,测试环境是否正常

package com.imooc.oa;
 
public class Test {
    public static void main(String[] args) {
        System.out.println("I‘m test class.");
    }
}

然后buildbuild project,只构建不运行,会出现target文件夹存放构建项目,可以看到java文件构建成功

也可以点击函数名,右键运行,说明环境正常 因为时javaweb项目,需要支持web开发,项目结构模块,然后点击加号,添加web模块

点击apply,然后ok即可 在pom.xml中添加依赖

<dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

记得右键reload,重新加载,引入依赖

provided表示我们开发测试时会将servlet引用到classpath中,但是实际打包时就不会将其打包,因为我们发布到tomcat时自带servlet

点击运行,出现out目录文件夹,字节码问价出现我们的java文件,说明环境配置成功

介绍MVC架构模式

视图就是界面,包括与用户进行交互的UI部分,比如安卓、ios的app,用来显示数据和将用户数据往后台提交,视图本身不处理任何业务逻辑 模型的职责用来进行业务或数据处理,比如数据的增删查改、支付宝支付逻辑、银行转账等等 控制器用来接收用户输入,经过数据处理后交给模型来处理,相反,模型处理完一些数据,要返回给控制器,控制器再返回给视图层,这样就完成了视图与模型的交互 视图层面:前端工程师 模型层面:后端工程师即Java工程师

MVC架构模式优点

◆软件团队分工合作,成员各司其职 ◆分层开发,显示与数据解耦,便于维护 ◆组件可灵活替代,互不影响

基于MVC的软件分层设计

MVC之所以称为架构模式,是因为其凌驾于开发语言之上的,任何基于开发语言的产品,都可以用MVC实现

业务逻辑层用来实现现实中业务问题,如银行账本计算等 数据持久层用来与数据库进行交互,实现增删查改功能 层和层之间只能逐级访问,虽然java编译不会出错,但是不符合规范,项目经理可能会处分

开发MyBatis工具类

需要与数据库打交道,引入mysql与mybatis的驱动

<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
<!--        junit4单元测试框架-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
<!--         logback日志输出组件-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

<scope>test</scope>表示只有进行test测试时才会引入依赖驱动 记得右键点击Maven选项,然后reload重载即可,如果仓库下载慢,请使用阿里云镜像仓库

在resource目录下创建mybatis-config.xml文件

入门_MyBatis中文网

进行配置

<?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>
    <settings>
<!--        开启驼峰命名转换 form_id => formId-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
 
<!--    增加与环境配置有关选项-->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/imooc_oa?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
                <property name="username" value="root"/>
                <property name="password" value="20020829"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

接下来一步是加载这个mybatis-config.xml文件 java目录下新增包:com.imooc.oa.utils,然后新增类MybatisUtils.java文件 用于加载xml文件并提供一些数据处理方法

package com.imooc.oa.utils;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import javax.annotation.Resource;
import java.io.IOException;
import java.io.Reader;
 
public class MybatisUtils {
    //利用static(静态)属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;
    //利用静态块在初始化类时实例化sqlSessionFactory
    static{
        Reader reader = null;
        try {
            //读取mybatis-config.xml
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            //构建SqlSessionFactory
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            //初始化错误时,通过抛出异常ExceptionInInitializerError通知调用者
            throw new ExceptionInInitializerError(e);
        }
    }
}

当我们准备对数据库进行增删查改时,需要打开sqlsession,数据操作完成时,就关闭sqlsession,每执行一条sql语句,就要打开关闭一次,如果忘记关闭,占用连接池,所以非常麻烦,我们可以使用lambda表达式/函数式接口进行封装,让执行sql语句时自动打开sqlsession,无论执行成功与否,都要关闭 在MybatisUtils.java文件继续书写

/**
     * 执行SELECT查询SQL
     * @param func 要执行查询语句的代码块
     * @return 查询结果
     */
    public static Object executeQuery(Function<SqlSession,Object> func){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Object obj = func.apply(sqlSession);
            return obj;
        }finally {
            sqlSession.close();
        }
    }

使用try…finally,无论try里代码块是否执行成功,都会执行finally下的语句块 如何使用上面的executeQuery()函数? 构建测试用的代码,在resource目录下创建mappers文件夹,里面保存执行的sql语句和xml文件 创建test.xml

<?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="test">
    <select id="sample" resultType="String">
        select 'success'
    </select>
</mapper>

一定要在mybatis-config.xml文件里注册,让其知道test.xml的存在

<mappers>
        <mapper resource="mappers/test.xml"/>
 
    </mappers>

然后构建测试用例,在test的java文件夹下新建MybatisUtilsTestor.java

import com.imooc.oa.utils.MybatisUtils;
import org.junit.Test;
 
public class MybatisUtilsTestor {
    @Test
    public void testCase1(){
        String result = (String)MybatisUtils.executeQuery(sqlSession -> {
            String out = (String) sqlSession.selectOne("test.sample");
            return out;
        });
        System.out.println(result);
    }
//利用lambda简化上面代码
    @Test
    public void testCase2(){
        String result = (String)MybatisUtils.executeQuery(sqlSession -> sqlSession.selectOne("test.sample"));
        System.out.println(result);
    }
}

使用lambda表达式传入函数式接口参数,其中test是上面的test.xml文件中的namespace,sample是id名,通过这样的方式一一对应进行访问

上面在工具类里添加了查询操作,接下来在添加写操作

/**
     * 执行INSERT/UPDATE/DELETE写操作SQL
     * @param func 要执行的写操作代码块
     * @return 写操作后返回的结果
     */
    public static Object executeUpdate(Function<SqlSession,Object> func){
        //openSession传入false参数代表手动提交/回滚事务
        SqlSession sqlSession = sqlSessionFactory.openSession(false);
        try {
            Object obj = func.apply(sqlSession);
            sqlSession.commit();
            return obj;
        }catch (Exception e){
            sqlSession.rollback();
            throw e;
        }finally {
            sqlSession.close();
        }
    }

Mybatis整合Druid连接池

Maven添加Druid连接池仓库 在pom.xml中

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.14</version>
        </dependency>

mybatis默认没有支持druid,需要我们扩展 添加子包datasource,新建DruidDataSourceFactory.java类

package com.imooc.oa.datasource;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
 
import javax.sql.DataSource;
import java.sql.SQLException;
 
public class DruidDataSourceFactory extends UnpooledDataSourceFactory {
    @Override
    public DataSource getDataSource() {
        try {
            ((DruidDataSource)this.dataSource).init();
        } catch (SQLException throwables) {
            throw new RuntimeException(throwables);
        }
        return this.dataSource;
    }
 
    public DruidDataSourceFactory(){
        this.dataSource = new DruidDataSource();
    }
 
}

UnpooledDataSourceFactory是用来拓展连接池的 构造方法,将数据源设置成自己的

public DruidDataSourceFactory(){
this.dataSource = new DruidDataSource();
}

然后重写getDataSource()方法,druid就整体定义好了,接下来如何让mybatis认识这个连接池呢? 在mybatis-config.xml文件中 改造dataSource标签

<!--            <dataSource type="POOLED">-->
 
<dataSource type="com.imooc.oa.datasource.DruidDataSourceFactory">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/imooc_oa?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
            <property name="username" value="root"/>
            <property name="password" value="20020829"/>
 
             <property name="initialSize" value="10"/>
               <property name="maxActive" value="20"/>
            </dataSource>

注意:driver要改为driverClassName,可以通过官方文档获取参数设置,要严格按照官方所给参数名进行配置 运行测试用例:

可以看出,自定义连接池设置成功 此时我们就可以设置连接池独有的设置,比如连接池数量等

<property name="initialSize" value="10"/>
                <property name="maxActive" value="20"/>