1. 개요
사실 가장 간단한 방법은 session.createSQLQuery("sql")와 같은 네이티브 SQL을 사용하거나 jdbcTemplate을 사용하는 것입니다. 하지만 프로젝트에 hql 쿼리가 사용되었기 때문에 수정이 힘들고 위험합니다! 따라서 더 나은 해결책을 찾아야 합니다. 작동하지 않으면 다시 작성하세요! 3일간의 연구 끝에 마침내 좋은 방법을 찾았습니다. 이에 대해서는 아래에 설명되어 있습니다.
2. 단계
2.1 새로운 최대 절전 모드 인터셉터 클래스를 생성합니다.
/** * Created by hdwang on 2017/8/7. * * hibernate拦截器:表名替换 */ public class AutoTableNameInterceptor extends EmptyInterceptor { private String srcName = StringUtils.EMPTY; //源表名 private String destName = StringUtils.EMPTY; // 目标表名 public AutoTableNameInterceptor() {} public AutoTableNameInterceptor(String srcName,String destName){ this.srcName = srcName; this.destName = destName; } @Override public String onPrepareStatement(String sql) { if(srcName.equals(StringUtils.EMPTY) || destName.equals(StringUtils.EMPTY)){ return sql; } sql = sql.replaceAll(srcName, destName); return sql; } }
이 인터셉터는 모든 데이터베이스 작업을 가로채서 전송하기 전에 SQL 문의 테이블 이름을 바꿉니다.
2.2 sessionFactory로 구성
먼저 sessionFactory가 무엇인지 살펴보겠습니다.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" > <property name="dataSource" ref="defaultDataSource"></property> <property name="packagesToScan"> <list> <value>com.my.pay.task.entity</value> <value>com.my.pay.paycms.entity</value> <value>com.my.pay.data.entity.payincome</value> </list> </property> <property name="mappingLocations"> <list> <value>classpath*:/hibernate/hibernate-sql.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">none</prop> <!-- 开启查询缓存 --> <prop key="hibernate.cache.use_query_cache">false</prop> <!-- 配置二级缓存 --> <prop key="hibernate.cache.use_second_level_cache">true</prop> <!-- 强制Hibernate以更人性化的格式将数据存入二级缓存 --> <prop key="hibernate.cache.use_structured_entries">true</prop> <!-- Hibernate将收集有助于性能调节的统计数据 --> <prop key="hibernate.generate_statistics">false</prop> <!-- 指定缓存配置文件位置 --> <prop key="hibernate.cache.provider_configuration_file_resource_path">/spring/ehcache.xml</prop> <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> <prop key="hibernate.current_session_context_class">jta</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop> <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop> </props> </property> </bean>
public class LocalSessionFactoryBean extends HibernateExceptionTranslator implements FactoryBean<SessionFactory>, ResourceLoaderAware, InitializingBean, DisposableBean { private DataSource dataSource; private Resource[] configLocations; private String[] mappingResources; private Resource[] mappingLocations; private Resource[] cacheableMappingLocations; private Resource[] mappingJarLocations; private Resource[] mappingDirectoryLocations; private Interceptor entityInterceptor; private NamingStrategy namingStrategy; private Object jtaTransactionManager; private Object multiTenantConnectionProvider; private Object currentTenantIdentifierResolver; private RegionFactory cacheRegionFactory; private Properties hibernateProperties; private Class<?>[] annotatedClasses; private String[] annotatedPackages; private String[] packagesToScan; private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); private Configuration configuration; private SessionFactory sessionFactory;
사실 sessionFactory는 LocalSessionFactoryBean 객체의 속성입니다. 이는 왜 Bean 주입이 클래스 자체가 아닌 클래스의 속성인지 알 수 있습니다. 이는 FactoryBean
우리 모두는 sessionFactory 객체에 의해 생성된 세션 객체를 사용하여 데이터베이스를 운영합니다. 다음은 sessionFactory 개체의 두 가지 메서드입니다.
/** * Open a {@link Session}. * <p/> * JDBC {@link Connection connection(s} will be obtained from the * configured {@link org.hibernate.service.jdbc.connections.spi.ConnectionProvider} as needed * to perform requested work. * * @return The created session. * * @throws HibernateException Indicates a problem opening the session; pretty rare here. */ public Session openSession() throws HibernateException; /** * Obtains the current session. The definition of what exactly "current" * means controlled by the {@link org.hibernate.context.spi.CurrentSessionContext} impl configured * for use. * <p/> * Note that for backwards compatibility, if a {@link org.hibernate.context.spi.CurrentSessionContext} * is not configured but JTA is configured this will default to the {@link org.hibernate.context.internal.JTASessionContext} * impl. * * @return The current session. * * @throws HibernateException Indicates an issue locating a suitable current session. */ public Session getCurrentSession() throws HibernateException;
그런 다음 프로젝트에서는 getCurrentSession()을 사용하여 세션 개체를 얻습니다.
최대 절전 모드 인터셉터를 구성하는 방법은 무엇입니까?
LocalSessionFactoryBean对象的entityInterceptor属性可以配置,你可以在xml中配置它,加到sessionFactory这个bean的xml配置中去。
<property name="entityInterceptor"> <bean class="com.my.pay.common.AutoTableNameInterceptor"/> </property>
글쎄, 하나만 구성할 수 있습니다. sessionFactory는 싱글톤이므로, sessionFactory를 참조하는 Dao 객체도 싱글톤이고, 서비스와 컨트롤러도 모두 싱글톤입니다. 그렇다면 질문이 있습니다. 테이블 이름을 동적으로 바꾸는 방법은 무엇입니까? 동적 다중 사례로 가는 길이 막혔습니다. 남은 것은 인터셉터 객체의 값을 동적으로 수정하는 것뿐입니다. 좋은 조언인 것 같습니다. 나의 시도는 실패로 끝났고 스레드 안전 문제를 해결할 수 없었습니다! 그 이유는 나중에 설명하겠습니다.
그래서 XML로 구성하면 내 요구 사항을 충족할 수 없습니다. 그런 다음 코드에서만 설정할 수 있습니다. 다행스럽게도 sessionFactory 객체는 이를 수정할 수 있는 입구를 제공합니다.
@Resource(name = "sessionFactory")private SessionFactory sessionFactory;protected Session getSession(){ if(autoTableNameInterceptorThreadLocal.get() == null){ return this.sessionFactory.getCurrentSession(); }else{ SessionBuilder builder = this.sessionFactory.withOptions().interceptor(autoTableNameInterceptorThreadLocal.get()); Session session = builder.openSession(); return session; } }
/** * 线程域变量,高效实现线程安全(一个请求对应一个thread) */ private ThreadLocal<AutoTableNameInterceptor> autoTableNameInterceptorThreadLocal = new ThreadLocal<>(); public List<WfPayLog> find(Long merchantId, Long poolId,String sdk, Long appId,String province, Integer price, String serverOrder, String imsi,Integer iscallback,String state, Date start, Date end, Paging paging) { 。。。。 //定制表名拦截器,设置到线程域 autoTableNameInterceptorThreadLocal.set(new AutoTableNameInterceptor("wf_pay_log","wf_pay_log_"+ DateUtil.formatDate(start,DateUtil.YEARMONTH_PATTERN))); List<WfPayLog> wfPayLogs; if (paging == null) { wfPayLogs = (List<WfPayLog>) find(hql.toString(), params); //find方法里面有 this.getSession().createQuery("hql") 等方法 } else { wfPayLogs = (List<WfPayLog>) findPaging(hql.toString(), "select count(*) " + hql.toString(), params, paging); } return wfPayLogs; }
빨간색으로 표시된 코드가 핵심코드이자 핵심설명입니다. 즉, DAO 레이어 객체에 sessionFactory 객체를 주입하여 세션을 획득하는 방식으로 데이터베이스를 운영할 수 있도록 변경했습니다. 테이블 이름을 변경해야 할 때, 스레드 도메인 변수를 정의하고, 인터셉터가 필요할 때 인터셉터 객체를 스레드 도메인에 저장합니다. 그러면 데이터베이스를 운영할 수 있도록 인터셉터로 구성된 세션을 얻게 됩니다. time 인터셉터가 적용됩니다.
객체 멤버 변수를 스레드 도메인 변수에 저장하지 않고 직접 정의하는 것은 확실히 불가능합니다. 동시성 문제가 있기 때문입니다(여러 요청(스레드)이 동시에 dao 메서드를 호출하고 getSession() 메서드가 호출됨) dao 메소드가 실행될 때, 아마도 gettingSession 시 인터셉터가 다른 요청에 대해 교체되었을 때) 물론 동기화를 통해 해결할 수도 있습니다. 스레드 도메인을 사용하는 것은 동기화된 동기화 잠금보다 훨씬 효율적입니다. 스레드 도메인을 사용하면 인터셉터 개체와 요청(스레드)이 함께 연결됩니다. dao 메서드가 실행될 때 실행 문이 동일한 스레드에 있는 한 스레드가 공유하는 개체 정보는 일관성이 있어야 합니다. 이므로 동시성 문제가 없습니다.
위에서 언급했듯이 싱글톤 인터셉터는 스레드 안전성 문제를 해결할 수 없기 때문에 작동하지 않습니다. AutoTableNameInterceptor는 싱글톤입니다. 새 집합 작업을 추가하는 등 dao 계층에서 해당 값을 수정할 수 있습니다. 그러나 설정하는 동안 다른 요청도 설정되므로 요청이 직렬(대기열에 하나씩 대기)이 아닌 이상 destName 및 srcName의 값이 계속 변경됩니다. 그리고 n dao 인스턴스가 인터셉터를 호출할 수도 있습니다. 스레드 동기화를 어떻게 달성합니까? dao 작업 중에 전체 인터셉터 개체를 잠그지 않으면 성능에 영향을 미칩니다! 이것은 스레드 도메인을 사용하여 달성할 수 없습니다. 테스트 후 우리는 요청 스레드 대신 인터셉터 메소드를 호출하는 최대 절전 모드 하단에 여러 스레드가 있음을 발견했습니다. 따라서 dao에서 인터셉터까지는 더 이상 스레드가 아닙니다. 인터셉터의 onPrepareStatement 콜백 메소드는 너무 단조롭고 기능이 제한되어 있습니다. 게다가 싱글톤을 사용하는 것은 sessionFactory의 전역 구성이므로 코드를 통해 추가하는 것은 일시적입니다.
위 내용은 Java의 Spring 최대 절전 모드에서 테이블 이름을 동적으로 바꾸는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

JVM은 바이트 코드 해석, 플랫폼 독립 API 및 동적 클래스 로딩을 통해 Java의 Wora 기능을 구현합니다. 1. 바이트 코드는 크로스 플랫폼 작동을 보장하기 위해 기계 코드로 해석됩니다. 2. 표준 API 추상 운영 체제 차이; 3. 클래스는 런타임에 동적으로로드되어 일관성을 보장합니다.

JAVA의 최신 버전은 JVM 최적화, 표준 라이브러리 개선 및 타사 라이브러리 지원을 통해 플랫폼 별 문제를 효과적으로 해결합니다. 1) Java11의 ZGC와 같은 JVM 최적화는 가비지 수집 성능을 향상시킵니다. 2) Java9의 모듈 시스템과 같은 표준 라이브러리 개선은 플랫폼 관련 문제를 줄입니다. 3) 타사 라이브러리는 OpenCV와 같은 플랫폼 최적화 버전을 제공합니다.

JVM의 바이트 코드 검증 프로세스에는 네 가지 주요 단계가 포함됩니다. 1) 클래스 파일 형식이 사양을 준수하는지 확인, 2) 바이트 코드 지침의 유효성과 정확성을 확인하고 3) 유형 안전을 보장하기 위해 데이터 흐름 분석을 수행하고 4) 검증의 철저한 성능 균형을 유지합니다. 이러한 단계를 통해 JVM은 안전하고 올바른 바이트 코드 만 실행되도록하여 프로그램의 무결성과 보안을 보호합니다.

Java'splatforminccendenceallowsapplicationStorunonAnyAnyOperatingSystemwithajvm.1) SingleCodeBase : writeAndCompileOnceforAllPlatforms.2) EasyUpdates : UpdateByTeCodeForsimultiancodeporsimultiancomeDeployment.3) 시험 효율성 : westernoneplatformforunivor.4) Scalab

Java의 플랫폼 Independence는 JVM, JIT 컴파일, 표준화, 제네릭, Lambda 표현 및 ProjectPanama와 같은 기술을 통해 지속적으로 향상됩니다. 1990 년대 이래 Java는 기본 JVM에서 고성능 현대 JVM으로 발전하여 다양한 플랫폼에서 코드의 일관성과 효율성을 보장했습니다.

Java는 플랫폼 별 문제를 어떻게 완화합니까? Java는 JVM 및 표준 라이브러리를 통해 플랫폼 독립성을 구현합니다. 1) Bytecode 및 JVM을 사용하여 운영 체제 차이를 추상화합니다. 2) 표준 라이브러리는 Paths 클래스 처리 파일 경로 및 Charset 클래스 처리 문자 인코딩과 같은 크로스 플랫폼 API를 제공합니다. 3) 최적화 및 디버깅을 위해 실제 프로젝트에서 구성 파일 및 다중 플랫폼 테스트를 사용하십시오.

java'splatformincendenceenhancesmicroservicesarchitectureDeploymentFlexibility, 일관성, 확장 성 및 포트 가능성

Graalvm은 Java의 플랫폼 독립성을 세 가지 방식으로 향상시킵니다. 1. 교차 언어 상호 운용성, Java는 다른 언어와 원활하게 상호 작용할 수 있습니다. 2. 독립적 인 런타임 환경, Java 프로그램을 GraalvMnativeImage를 통해 로컬 실행 파일로 컴파일합니다. 3. 성능 최적화, Graal Compiler는 Java 프로그램의 성능과 일관성을 향상시키기 위해 효율적인 기계 코드를 생성합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

Dreamweaver Mac版
시각적 웹 개발 도구
