С помощью SQL_CALC_FOUND_ROWS
вы не можете.
Число строк, доступное через FOUND_ROWS (), является переходным и не предназначено для доступа к оператору после инструкции SELECT SQL_CALC_FOUND_ROWS.
blockquote>Как заметил кто-то в вашем предыдущем вопросе, использование
SQL_CALC_FOUND_ROWS
часто медленнее, чем просто получение счета.Возможно, вам лучше всего сделать это как подзапрос:
SELECT (select count(*) from my_table WHERE Name LIKE '%prashant%') as total_rows, Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
Все, что «просто работает» с Spring Boot, на самом деле не более, чем какая-то конфигурация. В конце концов, это всего лишь приложение Spring. Поэтому я считаю, что вы, вероятно, можете настроить все вручную, что Boot делает для вас автоматически, но я не знаю никого, кто бы на самом деле пробовал этот конкретный угол. Создание контекста приложения начальной загрузки, безусловно, является предпочтительным подходом, но в зависимости от вашего варианта использования вы можете заставить его работать с одним контекстом, если убедитесь, что локаторы источника свойств выполняются достаточно рано.
Приложения, отличные от Spring (или не Spring Boot), могут получать доступ к обычному тексту или двоичным файлам на сервере конфигурации. Например. весной вы можете использовать @PropertySource
с расположением ресурса, который был URL-адресом, например http://configserver/{app}/{profile}/{label}/application.properties
или http://configserver/{app}-{profile}.properties
. Все это описано в руководстве пользователя.
У меня есть подобное требование; У меня есть веб-приложение, которое использует конфигурацию Spring XML для определения некоторых bean-компонентов, значения свойств хранятся в файлах .property. Требуется, чтобы конфигурация загружалась с жесткого диска во время разработки и с сервера Spring Cloud Config в производственной среде.
Моя идея состоит в том, чтобы иметь два определения для PropertyPlaceholderConfigurer; первый будет использоваться для загрузки конфигурации с жесткого диска:
<bean id="resources" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" doc:name="Bean">
<property name="locations">
<list>
<value>dcm.properties</value>
<value>post_process.properties</value>
</list>
</property>
</bean>
Второй будет загружать .properties с сервера Spring Config:
<bean id="resources" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" doc:name="Bean">
<property name="locations">
<list>
<value>http://localhost:8888/trunk/dcm-qa.properties</value>
</list>
</property>
</bean>
Ссылка: https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html
Root WebApplicationContext
и Servlet WebApplicationContext
использует Environment и инициализирует PropertySources на основе профиля пружины , Для приложений, не поддерживающих Spring, нам нужно настроить их, чтобы получить свойства от сервера конфигурации и обновлять компоненты при каждом изменении свойства. Ниже приведены изменения, которые должны произойти, чтобы заставить конфигурацию работать в SpringMVC. Вам также понадобится системное свойство для spring.profile.active
Создайте CustomBeanFactoryPostProcessor
и установите lazyInit
для всех определений бинов в значение true, чтобы инициализировать все бин лениво, т. Е. Бины инициализируются только при запрос.
@Component
public class AddRefreshScopeProcessor implements BeanFactoryPostProcessor, ApplicationContextAware {
private static ApplicationContext applicationContext;
@SuppressWarnings("unchecked")
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = applicationContext.getBeanDefinitionNames();
for(int i=0; i<beanNames.length; i++){
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanNames[i]);
beanDef.setLazyInit(true);
beanDef.setScope("refresh");
}
}
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
applicationContext = context;
}
/**
* Get a Spring bean by type.
*
* @param beanClass
* @return
*/
public static <T> T getBean(Class<T> beanClass) {
return applicationContext.getBean(beanClass);
}
/**
* Get a Spring bean by name.
*
* @param beanName
* @return
*/
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}
Создайте собственный класс, расширяющий StandardServletEnvironment
и переопределяющий метод initPropertySources
для загрузки дополнительных PropertySources (с сервера конфигурации).
public class CloudEnvironment extends StandardServletEnvironment {
@Override
public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) {
super.initPropertySources(servletContext,servletConfig);
customizePropertySources(this.getPropertySources());
}
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
super.customizePropertySources(propertySources);
try {
PropertySource<?> source = initConfigServicePropertySourceLocator(this);
propertySources.addLast(source);
} catch (
Exception ex) {
ex.printStackTrace();
}
}
private PropertySource<?> initConfigServicePropertySourceLocator(Environment environment) {
ConfigClientProperties configClientProperties = new ConfigClientProperties(environment);
configClientProperties.setUri("http://localhost:8888");
configClientProperties.setProfile("dev");
configClientProperties.setLabel("master");
configClientProperties.setName("YourApplicationName");
System.out.println("##################### will load the client configuration");
System.out.println(configClientProperties);
ConfigServicePropertySourceLocator configServicePropertySourceLocator =
new ConfigServicePropertySourceLocator(configClientProperties);
return configServicePropertySourceLocator.locate(environment);
}
}
Создайте пользовательский ApplicatonContextInitializer
и переопределите метод initialize
, чтобы установить custom Enviroment
вместо StandardServletEnvironment
.
public class ConfigAppContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.setEnvironment(new CloudEnvironment());
}
}
Измените web.xml
, чтобы использовать этот инициализатор пользовательского контекста для application context
и servlet context
.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.my.context.ConfigAppContextInitializer</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.my.context.ConfigAppContextInitializer</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
Чтобы обновить бины, создавшие конечную точку обновления, вам также необходимо обновить application Context
.
@Controller
public class RefreshController {
@Autowired
private RefreshAppplicationContext refreshAppplicationContext;
@Autowired
private RefreshScope refreshScope;
@RequestMapping(path = "/refreshall", method = RequestMethod.GET)
public String refresh() {
refreshScope.refreshAll();
refreshAppplicationContext.refreshctx();
return "Refreshed";
}
}
RefreshAppplicationContext.java
@Component
public class RefreshAppplicationContext implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void refreshctx(){
((XmlWebApplicationContext)(applicationContext)).refresh();
}
}
Я нашел решение для использования spring-cloud-zookeeper без Spring Boot, основываясь на представленной здесь идее https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html
Его следует легко обновить в соответствии с вашими потребностями и использовать сервер Spring Cloud Config (необходимо обновить класс CloudEnvironement, чтобы загрузить файл с сервера вместо Zookeeper)
Сначала создайте класс CloudEnvironement, который будет создайте PropertySource (например, из Zookeeper):
CloudEnvironement.java
public class CloudEnvironment extends StandardServletEnvironment {
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
super.customizePropertySources(propertySources);
try {
propertySources.addLast(initConfigServicePropertySourceLocator(this));
}
catch (Exception ex) {
logger.warn("failed to initialize cloud config environment", ex);
}
}
private PropertySource<?> initConfigServicePropertySourceLocator(Environment environment) {
ZookeeperConfigProperties configProp = new ZookeeperConfigProperties();
ZookeeperProperties props = new ZookeeperProperties();
props.setConnectString("myzookeeper:2181");
CuratorFramework fwk = curatorFramework(exponentialBackoffRetry(props), props);
ZookeeperPropertySourceLocator propertySourceLocator = new ZookeeperPropertySourceLocator(fwk, configProp);
PropertySource<?> source= propertySourceLocator.locate(environment);
return source ;
}
private CuratorFramework curatorFramework(RetryPolicy retryPolicy, ZookeeperProperties properties) {
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();
builder.connectString(properties.getConnectString());
CuratorFramework curator = builder.retryPolicy(retryPolicy).build();
curator.start();
try {
curator.blockUntilConnected(properties.getBlockUntilConnectedWait(), properties.getBlockUntilConnectedUnit());
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
return curator;
}
private RetryPolicy exponentialBackoffRetry(ZookeeperProperties properties) {
return new ExponentialBackoffRetry(properties.getBaseSleepTimeMs(),
properties.getMaxRetries(),
properties.getMaxSleepMs());
}
}
Затем создайте собственный класс XmlWebApplicationContext: он позволит загружать PropertySource из Zookeeper, когда запустите ваше веб-приложение и замените магию начальной загрузки Spring Boot:
MyConfigurableWebApplicationContext.java
public class MyConfigurableWebApplicationContext extends XmlWebApplicationContext {
@Override
protected ConfigurableEnvironment createEnvironment() {
return new CloudEnvironment();
}
}
Последняя, в вашем файле web.xml добавьте следующий контекстный параметр для использования вашего класса MyConfigurableWebApplicationContext и начальной загрузки вашего CloudEnvironement.
<context-param>
<param-name>contextClass</param-name>
<param-value>com.kiabi.config.MyConfigurableWebApplicationContext</param-value>
</context-param>
Если вы используете стандартный конфигуратор файлов свойств, он все равно должен быть загружен, чтобы вы могли иметь свойства как в локальном файле, так и в Zookeeper.
Чтобы все это работало, вам нужно иметь в своем classpath файлы spring-cloud-starter-zookeeper-config и curator-framework jar с их зависимостью. Если вы используете maven, вы можете добавить следующее в pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-zookeeper-dependencies</artifactId>
<version>1.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-config</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
</dependencies>