zoukankan      html  css  js  c++  java
  • Saas模式


    1.saas系统

    1.1 saas系统概念

    SAAS:软件即服务

    本系统是基于saas服务的。统一开放,维护,租户(注册付费的公司)需要在本系统中进行注册,并付费,然后根据付费情况使用系统功能。

    1.2 saas平台数据库隔离设计

    多租户数据库隔离的三种设计模式:

    ①: 针对每一个租户或者都设计单独的数据库:

    在应用服务器中配制不同的数据源,或者使用不同的连接池。

    优点:不同客户的数据物理分离,安全性比较好。

    缺点:数据库连接的利用效率不高,技术难度大,需要动态的切换数据源。

     

    ② :共享数据库,独立的scheme(表)

    这个方案基本是方案①的变种。同一个数据库下可以有多个Schema

    优点:除了方案①的优点以外,共享数据源或连接池,效率更高。

    缺点:数据库连接池开销会比较大,在mysql数据库中,schema概念不像oracle那么明了。

     

    ③ :共享数据库,共享scheme,共享数据库表,通过租户id进行区别:

    所有租户的数据都存放在一个数据库的同一套表中, 在表中增加tenant_id标志字段,表明该记录是属于哪个租户的。

    优点:数据源和数据库的管理都比较简单。和原来的应用没有差别。

    缺点:数据权限比较复杂,增加程序的复杂性。如果应用比较复杂,很多数据表都需

    要加入客户标志字段,很多查询都需要包括该字段,会比较麻烦。如果有遗漏,、特别是查询条件中遗漏该字段,就会造成一个客户看到另一个客户的数据。

    1.3 代码实现(部分)

    租户TenantMapper.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="cn.itsource.mapper.TenantMapper">
    <!-- 保存部门 -->
    <insert id="save" parameterType="Tenant" useGeneratedKeys="true"
    keyProperty="id" keyColumn="id">
    insert into
    t_tenant(companyName,companyNum,registerTime,state,address,logo)
    values(#{companyName},#{companyNum},#{registerTime},#{state},#{address},#{logo})
    </insert>

    <!-- 修改部门 -->
    <update id="update" parameterType="Tenant">
    update t_tenant set
    companyName=#{companyName},companyNum=#{companyNum},registerTime=#{registerTime},
    state=#{state},address=#{address},logo=#{logo}
    where id=#{id}
    </update>

    <!-- 删除部门 -->
    <delete id="remove" parameterType="long">
    delete from t_tenant where
    id=#{id}
    </delete>

    <!-- 通过部门id获取部门 -->
    <select id="loadById" parameterType="long" resultType="Tenant">
    select * from
    t_tenant where d.id = #{id}
    </select>

    <!-- 获取所有部门 -->
    <select id="loadAll" resultType="Tenant">
    select * from t_tenant
    </select>

    </mapper>

    EmployeeMapper.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="cn.itsource.mapper.EmployeeMapper">

    <!-- 保存员工 -->
    <insert id="save" parameterType="Employee" useGeneratedKeys="true"
    keyProperty="id" keyColumn="id">
    insert into
    t_employee(username,realName,password,tel,email,dept_id,inputTime,state,type,tenant_id)
    values(#{username},#{realName},#{password},#{tel},#{email},#{dept.id},#{inputTime},#{state},
    #{type},#{tenant.id})
    </insert>
    <!-- 修改员工 -->
    <update id="update" parameterType="Employee">
    update t_employee set
    username=#{username},realName=#{realName},password=#{password},tel=#{tel},
    email=#{email},dept_id=#{dept.id},inputTime=#{inputTime},state=#{state},type=#{type},tenant_id=#{tenant.id}
    where id=#{id}
    </update>
    <!-- 删除 -->
    <delete id="romove" parameterType="long">
    delete from t_employee where id=#{id}
    </delete>


    <select id="loadById" parameterType="long" resultType="Employee">
    select * from
    t_employee where id = #{id}
    </select>
    <!-- 获取所有员工 -->
    <select id="loadAll" resultType="Employee">
    select *
    from t_employee
    </select>
    </mapper>

    Service层:EmployeeServiceImpl

    @Service
    public class EmployeeServiceImpl extends BaseServiceImpl<Employee> implements IEmployeeService {

       @Autowired
       private TenantMapper tenantMapper;

       @Autowired
       private EmployeeMapper employeeMapper;
       @Override
       public void addTenantEmployee(Employee employee) {
           Tenant tenant = employee.getTenant();
           tenant.setRegisterTime(new Date());
           tenant.setState(0);
           //添加租户返回租户id   添加前对象里面没有id,添加完成后就有了
           tenantMapper.save(tenant);
           //把租户id设置给员工
           employee.setTenant(tenant);
           //在保存员工
           employee.setRealName(employee.getUsername());
           employeeMapper.save(employee);
      }

    Controller层:EmployeeController

     */
    @Controller
    @RequestMapping("/employee") //定位资源
    @CrossOrigin
    public class EmployeeController implements BaseController<Employee> {
      @Autowired
      private IEmployeeService employeeService;

      //添加租户员工
      @RequestMapping(value = "/tenant",method = RequestMethod.PUT)
      @ResponseBody
      public AjaxResult addTenantEmployee(@RequestBody Employee employee){
          try {
              employeeService.addTenantEmployee(employee);
              return AjaxResult.me();
          } catch (Exception e) {
              e.printStackTrace();
              return AjaxResult.me().setSuccess(false).setMessage("入驻失败!"+e.getMessage());
          }
      }

    前端:部分代码

    密码验证:

                var validatePass2 = (rule, value, callback) => {
                   console.log(value); //确认密码
                   if (value === '') {
                       callback(new Error('请再次输入密码'))
                  } else if (value !== this.employee.password) {
                       callback(new Error('两次输入密码不一致!'))
                  } else {
                       callback()
                  }
              }

    methods:

            methods: {
               settledIn(){
                   this.$refs.tenantForm.validate((valid) => {
                       //校验表单成功后才做一下操作
                       if (valid) {
                           this.$confirm('确认入驻吗?', '提示', {}).then(() => {
                               //拷贝后面对象的值到新对象,防止后面代码改动引起模型变化
                               let para = Object.assign({}, this.employee); //employee
                               let tenant = {
                                   companyName: para.companyName,
                                   companyNum: para.companyNum,
                                   address: para.address,
                                   logo:para.logo,
                              }
                               para.tenant = tenant;
                               //判断是否有id有就是修改,否则就是添加
                               this.$http.put("/employee/tenant",para).then((res) => {
                                   if(res.data.success){
                                       this.$message({
                                           message: '操作成功!',
                                           type: 'success'
                                      });
                                       //重置表单
                                       this.$refs['tenantForm'].resetFields();
                                       //跳转登录页面
                                       this.$router.push({ path: '/login' });
                                  }
                                   else{
                                       this.$message({
                                           message: res.data.message,
                                           type: 'error'
                                      });
                                  }

                              });
                          });
                      }
                  })
              }
          }
  • 相关阅读:
    LaTeX 表格指定宽度并居中
    ubuntu 14.04服务器上使用nginx搭建wordpress博客详解
    17款可视化工具,让你的数据更酷炫
    创建oracle数据库图示(一步一步教你安装oracle)
    创建oracle数据库图示(一步一步教你安装oracle)
    oracle 内连接 外连接 查询 笔记
    oracle 内连接 外连接 查询 笔记
    Telnet用不了怎么办
    Telnet用不了怎么办
    File 类 操作实例
  • 原文地址:https://www.cnblogs.com/htq29study/p/12080152.html
Copyright © 2011-2022 走看看