当前位置: 首页 > 知识库问答 >
问题:

如何在Laravel中使用多个数据库以及数据库连接随用户的变化而变化?[副本]

钮鸿煊
2023-03-14

我想创建用户基础数据库,例如在我的系统中有两个用户A和B。我有一个主数据库和两个数据库用户A(用于用户A)和用户B(用于用户B)。在主数据库中,我拥有所有用户的信息。现在我想要的是,当用户A登录系统时,它访问主数据库和用户A数据库,当用户B登录数据库时,连接应该是主数据库和用户B数据库。

共有1个答案

端木淇
2023-03-14

以下是@ADyson建议后我的答案

我在网上做了很多搜索,但没有找到任何完美的解决方案。有一些博客只解释了创建两个或更多connection database.php配置文件,然后使用$connection在模型中访问这些连接。是的,我同意这是一个很好的解决方案,但是,如果我的系统中有数百万用户,我不想手动在database.php文件上创建所有连接。

所以我做了一个实验,它对我有用,我想把这个解决方案分享给所有其他开发者。

首先,我在masterdatabase中为所有用户的数据库名提供了一个选项(超级管理员可以在超级管理员创建的用户在我的系统中添加数据库名)

其次,我创建了一个中间件DatabaseSwitcher.php,并在Kernel.php中全局注册了该中间件,并在web.php中以auth Middleware的名字调用该中间件:

(['middleware' => ['auth', 'DatabaseSwitcher']]).

下面是中间件的代码。

<?php 
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Config;    //to get configuration data
class DatabaseSwitcher {
    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {   
        //check if user logged in
        if ( !$this->auth->guest() )
        {    
            //get authenticate user information
            $user = $this->auth->user();
            //get user's database            
            $user_db = $user->user_database;
            //first get default mysql connection array and use in new variable for new connection which will create dynamically.(default connection is defined in database.php config file)
            $dbConfig = config('database.connections.mysql');
            //now use database name which is in user record; 
            $dbConfig['database'] = $user_db;
            //now set a new database connection name is mysql_new in my case 
            Config::set("database.connections.mysql_new", $dbConfig); 
            //now set default connection which is created for the user
            Config::set("database.default", 'mysql_new'); 
            //now there are two connection one for master (mysql) and other for user(mysql_new) and default connection is (mysql_new)
            //we can access these two connection in every models by using $connection as mentioned in Larave documentation.            
        } 
        return $next($request);
    }
}

现在,我们可以在模型中使用标准结构或类似laravel的动态数据库连接:

protected $connection = 'mysql'; 
protected $connection = 'mysql_new'; 

所有这些都是好的,但是当我们使用unique和exist时,Laravel验证规则仍然可能存在问题。

为了克服这个问题,我使用了唯一和存在规则的连接名称。例如//连接应该是数据库连接的名称,如mysql和mysql_new(在我的情况下)

'name' => 'required|unique:connection.users,name',
'email' => 'required|exist:connection.users,email',

我希望它能帮助所有其他希望系统看起来像这样的开发人员。对不起,我的英语不好,因为我不擅长语法。

 类似资料:
  • 问题内容: 我想在系统中合并多个数据库。大多数情况下,数据库是MySQL。但是将来可能会有所不同,即Admin可以生成这样的报告,该报告是 使用异构 数据库系统的 来源 。 所以我的问题是 Laravel是否提供了Facade 来应对这种情况?还是任何其他具有更合适问题处理能力的框架是? 问题答案: [**使用> = 5.0**](https://github.com/laravel/larave

  • 所以我有数百个数据库,我想根据我传递的值来改变使用什么数据库 例如,我有许多公司分支机构有branch_code(000,001,002,003等。高达200)。它们都有相同的表,但只是在不同的数据库中创建的。还假设只有DB Name不同。我的问题是,当有数百个数据库时,我如何访问不同的数据库?我应该动态更改. env文件吗?当用户选择另一个分支时,我应该创建一个改变连接的函数吗?如果是的话,怎么

  • 我们将redis用于缓存和会话。我希望能够使用分离redis数据库(相同的服务器,只是不同的数据库)为每个情况,以及能够使用相同的服务器生产和预生产。我知道Redis允许您在一台服务器上定义多个数据库(http://www.redisocokbook.org/multiple_databases.html),但是我不知道如何将其翻译成Redis。配置(至少根据文档http://laravel.co

  • 问题内容: 我有一个使用Java Servlet / JSP的应用程序。我的应用有多个客户端,但是每个客户端都有一个单独的数据库。所有数据库都具有相同的架构。我想确定用户登录系统时要使用哪个数据库连接。 例如,客户端A登录后,我确定客户端A属于数据库C,抓住了数据库C的连接,然后继续愉快地进行操作。 我正在将JPA与Hibernate一起用作我的JPA提供程序。是否可以使用多个持久性单元并在登录时

  • 我的WebApp使用多个数据库,我尝试使用GlassFish连接池来管理连接,但我发现配置示例只使用一个数据库。 那么,我该怎么办?创建与我正在使用的数据库数量相同的连接池,或者是否有方法将一个池配置为多个数据库?

  • 从bugu-mongo 2.11版本开始,支持连接到多个数据库。 在前面的示例代码中,我们都只是连接到一个数据库: //默认的数据库连接 BuguConnection conn = BuguFramework.getInstance().createConnection(); conn.setHost("192.168.0.100"); conn.setPort(27017); conn.setU