1. /**
  2. * Copyright: Copyright (c) 2005-2005
  3. * Company: JavaResearch(http://www.javaresearch.org)
  4. */
  5. package org.javaresearch.jerch;
  6. import javax.sql.DataSource;
  7. /**
  8. * 类库的初始化和管理类。
  9. * 最后更新日期:2005年3月25日
  10. * @author cherami
  11. */
  12. public class JerchManager {
  13. /**
  14. * 数据源定义。
  15. */
  16. private DataSource datasource;
  17. /**
  18. * 唯一实例定义。
  19. */
  20. private static JerchManager instance;
  21. /**
  22. * 线程实例存储器
  23. */
  24. private static final ThreadLocal threadLocal = new ThreadLocal();
  25. /**
  26. * JDBCTemplate的实例个数的计数器。
  27. */
  28. private static int count;
  29. /**
  30. * 初始化类库。
  31. * 这个方法不能被使用两次,除非使用destroy方法消耗先前初始化的实例。
  32. * @param datasource 数据源
  33. */
  34. public static synchronized void init(DataSource datasource) {
  35. init(datasource,false);
  36. }
  37. /**
  38. * 初始化类库。
  39. * 这个方法不能被使用两次,除非使用destroy方法消耗先前初始化的实例。
  40. * @param datasource 数据源
  41. * @param debug 是否是调试模式
  42. */
  43. public static synchronized void init(DataSource datasource,boolean debug) {
  44. Utils.setDebuggable(debug);
  45. Utils.debug("JerchManager.START_INIT",null);
  46. if (instance != null) {
  47. throw new JerchException("JerchManager.HAVA_INITED");
  48. }
  49. instance = new JerchManager(datasource);
  50. }
  51. /**
  52. * 销毁实例以便重新设置。
  53. * 要在初始化后更换数据源必须使用本方法先销毁实例。
  54. */
  55. public static synchronized void destroy() {
  56. System.out.println("Template count:"+count+",Open count:"+Utils.getOpenConnectionCount()+",close count:"+Utils.getCloseConnectionCount());
  57. instance = null;
  58. count=0;
  59. threadLocal.set(null);
  60. if (Utils.getOpenConnectionCount()!=Utils.getCloseConnectionCount()) {
  61. Utils.debug("JerchManager.SOME_CONNECTION_NOT_CLOSED",null);
  62. }
  63. Utils.debug("JerchManager.DESTROYED",null);
  64. }
  65. /**
  66. * 得到JerchManager的实例。
  67. * 一般情况下没有必要使用此方法,可以直接使用getTemplate()得到需要使用的JDBCTemplate实例。
  68. * @return JerchManager实例。
  69. */
  70. public static JerchManager getInstance() {
  71. return instance;
  72. }
  73. /**
  74. * 私有构造方法,防止得到多个对象。
  75. * @param datasource 数据源
  76. */
  77. private JerchManager(DataSource datasource) {
  78. if (datasource==null) {
  79. throw new JerchException("JerchManager.DataSource_CAN_NOT_NULL");
  80. }
  81. this.datasource = datasource;
  82. }
  83. /**
  84. * 得到一个JDBCTemplate实例。
  85. * 对于当前线程,得到的是原来所使用的实例,对于一个新的线程,将创建一个新的实例。
  86. * 因此通过此方法得到并使用JDBCTemplate是线程安全的。
  87. * @return JDBCTemplate实例
  88. */
  89. public static JDBCTemplate getTemplate() {
  90. JDBCTemplate template = (JDBCTemplate) threadLocal.get();
  91. if (template==null) {
  92. if (instance==null) {
  93. throw new JerchException("JerchManager.HAVA_NOT_INITED");
  94. }
  95. template = createTemplate();
  96. }
  97. return template;
  98. }
  99. /**
  100. * 创建一个JDBCTemplate实例。
  101. * @return 新建的JDBCTemplate实例
  102. */
  103. protected static synchronized JDBCTemplate createTemplate() {
  104. JDBCTemplate template = new JDBCTemplate(instance.datasource);
  105. count++;
  106. threadLocal.set(template);
  107. return template;
  108. }
  109. /**
  110. * 得到JDBCTemplate实例的个数。
  111. * @return JDBCTemplate实例的个数
  112. */
  113. public static int getTemplateCount() {
  114. return count;
  115. }
  116. }