У меня сейчас 2 таблицы в базе данных:AbstractRoutingDataSource карта изменения во время выполнения
- пользователя
- user_database
В пользователя хранить логин, пароль, роль
В user_database я хранить базу данных драйвер, URL-адрес, пароль и пользователь. База данных диаграмм
Я хочу, чтобы пользовательский логин на моей странице и следующее соединение, что он сделал, будет отправлен в базу данных пользователей. Почему мне нужно что? Я планирую карту популярной электронной коммерции и создаю приложение для Android, где пользовательский логин и видят данные хранилища, могут добавлять и просматривать заказы на продукцию.
Теперь время, чтобы пройти практику, мои знания в весенних технологиях малы, пожалуйста, объясните мне что-то, когда я делаю неправильно. Все примеры в Интернете для AbstractRoutingDataSource
имеют файл данных декларации в файле персистентности или создают источник данных и начинают использовать AbstractRoutingDataSource
. В моем проекте я не сейчас подключаюсь к пользователю, и мне нужно получить его из базы данных. Я попытался получить репозиторий и этот пример https://stackoverflow.com/a/17575648/3037869 но я получаю null на @Autowired
в контроллере, я думаю, что соединение для хранилища равно null. Как установить соединение для этого репозитория и задать маршрут? Дефект этого метода, когда я добавляю пользователя, мне нужно перезагрузить сервер, чтобы обновить соединение.
Следующая попытка использовать то, что я сейчас использую класс User
реализовать UserDetails
после входа в систему я могу получить подключение пользователя от getPrincipal()
и добавить к карте.
private void setDataSources() {
HashMap<Object, Object> targetDataSources = new HashMap<>();
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
dataSourceBuilder.username("sa");
dataSourceBuilder.password("");
targetDataSources.put("auth", dataSourceBuilder.build());
setDefaultTargetDataSource(dataSourceBuilder.build());
if(SecurityContextHolder.getContext().getAuthentication()!=null) {
User user=(User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
System.out.println(user.getUserDatabase().getDriver());
dataSourceBuilder.driverClassName(user.getUserDatabase().getDriver());
dataSourceBuilder.url(user.getUserDatabase().getUrl());
dataSourceBuilder.username("3450_Menadzer");
dataSourceBuilder.password(user.getUserDatabase().getPassword());
targetDataSources.put("user", dataSourceBuilder.build());
}
setTargetDataSources(targetDataSources);
afterPropertiesSet(); //map is refresh when i add this
}
я запускаю этот метод на constuctor и determineCurrentLookupKey
protected Object determineCurrentLookupKey() {
if(SecurityContextHolder.getContext().getAuthentication()!=null) {
setDataSources();
return "user";
}
return "auth";
}
Это работает, но когда я обновить 3-4 раза запросить базу данных пользователей я получаю
User 3450_Menadzer already has more than 'max_user_connections' active connections
Настройки карты подключения Мануалов и не обновлять каждый метод. determineCurrentLookupKey
run У меня нет этой проблемы. Я думаю, что мой метод не связывает соединение. Как я могу это очистить? Это возможно для лучшего способа маршрутизации соединения?
EDIT @SergeBallesta я изменить код из ваших примеров Это мой класс для отображения
@Component
@Scope(value = "singleton")
public class DataSourceMap {
private Map<Object,Object> dataSourceMap;
public DataSourceMap()
{
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
dataSourceBuilder.username("sa");
dataSourceBuilder.password("");
dataSourceMap=new HashMap<Object,Object>();
dataSourceMap.put("auth",dataSourceBuilder.build());
}
public void addDataSource(String session,DataSource dataSource)
{
this.dataSourceMap.put(session,dataSource);
}
public Map<Object,Object> getDataSourceMap()
{
return dataSourceMap;
}
public void removeSource(String session)
{
dataSourceMap.remove(session);
}
}
Для AbstractRoutingDataSource
я сделал некоторые изменения, я был добавить afterPropertiesSet()
beacuse DataSource не обновляют. Я сделал некоторое обновление, и я не получаю ошибку, я думаю, что это работает. Мне нужно проверить это для большего количества баз данных в будущем
@Component
public class CustomRoutingDataSource extends AbstractRoutingDataSource{
@Autowired
DataSourceMap dataSources;
@Override
protected Object determineCurrentLookupKey() {
setDataSources(dataSources);
afterPropertiesSet();
System.out.println("test");
if(SecurityContextHolder.getContext().getAuthentication()!=null) {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
return request.getSession().getId();
}
return "auth";
}
@Autowired
public void setDataSources(DataSourceMap dataSources) {
System.out.println("data adding");
setTargetDataSources(dataSources.getDataSourceMap());
}
}
Вы можете поделиться своим кодом? У меня есть та же миссия после входа в систему пользователя, подключитесь к базовому db и получите источник данных, а затем CRUD для источника данных taht! Но я очень новичок в Spring Framework, я пробовал месяц, но никакого хорошего результата. Надеюсь, ваш код может мне помочь. – mikezang