整体介绍
◆需求说明与环境准备 ◆开发基于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.");
}
}
然后build→build 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文件
进行配置
<?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&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&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&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&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"/>