91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mybatis多線程下使用Example的示例

發布時間:2021-02-02 10:36:27 來源:億速云 閱讀:267 作者:小新 欄目:編程語言

這篇文章主要介紹了Mybatis多線程下使用Example的示例,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

前言

服務器每收到一個請求,都會從線程池中調度一個空閑線程來處理,spring整合的web時,controller和service一般都是單例的,這樣導致無論你的Example標注的是單例還是多例,同一個service下的Example也只有一個,多線程訪問時產生的

問題如下

問題詳情

工程目錄結構如下

Mybatis多線程下使用Example的示例

MyService 的service()方法接收兩個參數并據此查詢數據庫

@Service
public class MyService {
 @Autowired
 StudentMapper studentMapper;
 @Autowired
 StudentExample studentExample;
 public void service(Integer begin,Integer end){
  StudentExample.Criteria criteria1 = studentExample.createCriteria();
  criteria1.andAgeBetween(begin,end);
  List<Student> list=studentMapper.selectByExample(studentExample);
  studentExample.clear();
  System.out.println(list);
 }
}

當同時有兩個請求時,兩個請求的StudentExample相同

請求1如下

begin=2,end=8

Mybatis多線程下使用Example的示例

請求2如下

begin=4,end=8

Mybatis多線程下使用Example的示例

先放行請求1,請求1成功添加條件

Mybatis多線程下使用Example的示例

再放行請求2,請求2添加失敗

Mybatis多線程下使用Example的示例

這時如果請求2在請求1執行查詢操作前就已經執行完studentExample.clear (),請求1的查詢條件就失效了

Mybatis多線程下使用Example的示例

至此兩個請求都沒有得到正確的結果。

解決方案

可以使用ThreadLocal為每個線程配備單獨的Example,為保證每次都能獲取到值,這里對ThreadLocal簡單擴展一下,如果當前線程沒有對應的Example(多例),就從spring容器中獲取一個并與這個線程綁定。

ThreadLocalExtension

public class ThreadLocalExtension<T> extends ThreadLocal<T> {
   //獲取ApplicationContext方法見下
  @Autowired
  ApplicationContext applicationContext;
  public ThreadLocalExtension(){
    super();
  }
  public T get(Class<T> example){
    T bean=super.get();
    if(bean==null){
      super.set((T) applicationContext.getBean(example));
    }
    return super.get();
  }
}

spring泛型依賴注入

由于Example會有很多個,所以這里使用了泛型,spring4.0提供了對泛型依賴注入的支持。

首先實際類型對應的ThreadLocalExtension交由spring管理

@Repository
public class StudentExampleThreadLocal extends ThreadLocalExtension<StudentExample> {
}

然后直接在代碼中注入

@Autowired
ThreadLocalExtension<StudentExample> studentExampleThreadLocal;

修改后的MyService

@Service
public class MyService {
  @Autowired
  StudentMapper studentMapper;
  @Autowired
  ThreadLocalExtension<StudentExample> studentExampleThreadLocal;
  public void service(Integer begin,Integer end){
    StudentExample studentExample = studentExampleThreadLocal.get(StudentExample.class);
    StudentExample.Criteria criteria1 = studentExample.createCriteria();
    criteria1.andAgeBetween(begin,end);
    List<Student> list=studentMapper.selectByExample(studentExample);
    studentExample.clear();
    System.out.println(list);
  }
}

獲取ApplicationContext

創建一個類實現ApplicationContextAware,并向spring容器中注入applicationContext

@Component
public class ApplicationContextHelper implements ApplicationContextAware {
  private static ApplicationContext applicationContext;

  public ApplicationContextHelper() {
  }
  @Bean(name="applicationContext")
  public ApplicationContext getApplicationContext(){
    return applicationContext;
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    ApplicationContextHelper.applicationContext = applicationContext;
  }

  public static Object getBean(String beanName) {
    return applicationContext != null?applicationContext.getBean(beanName):null;
  }
}

結果

至此,整個改造完成,看看效果

請求1

Mybatis多線程下使用Example的示例

請求2

Mybatis多線程下使用Example的示例

每個請求獲取到了不同的StudentExample,也就不存在沖突的問題,并且StudentExample沒有大量的創建與銷毀,最多只創建了與服務器線程池中線程相同的個數,實現了重復使用

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Mybatis多線程下使用Example的示例”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永川市| 五大连池市| 白水县| 临湘市| 锦州市| 南乐县| 满城县| 昌平区| 峨眉山市| 韶关市| 卫辉市| 英吉沙县| 哈密市| 抚州市| 天峻县| 诸城市| 四平市| 上饶市| 安阳县| 隆昌县| 临潭县| 论坛| 拜城县| 且末县| 扬中市| 江源县| 克山县| 绥化市| 阳原县| 二连浩特市| 无为县| 西丰县| 商南县| 修武县| 集安市| 海口市| 南澳县| 建平县| 会同县| 府谷县| 鞍山市|