001/* 002 * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core; 017 018import com.mybatisflex.core.datasource.FlexDataSource; 019import com.mybatisflex.core.exception.FlexAssert; 020import com.mybatisflex.core.mybatis.FlexConfiguration; 021import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder; 022import com.mybatisflex.core.mybatis.Mappers; 023import org.apache.ibatis.logging.Log; 024import org.apache.ibatis.logging.LogFactory; 025import org.apache.ibatis.mapping.Environment; 026import org.apache.ibatis.session.Configuration; 027import org.apache.ibatis.transaction.TransactionFactory; 028import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; 029 030import javax.sql.DataSource; 031import java.util.ArrayList; 032import java.util.List; 033import java.util.concurrent.atomic.AtomicBoolean; 034 035/** 036 * MybatisFlex 的启动类 037 * 038 * <code> 039 * MybatisFlexBootstrap.getInstance() 040 * .setDatasource(...) 041 * .addMapper(...) 042 * .start(); 043 * <p> 044 * <p> 045 * MybatisFlexBootstrap.getInstance() 046 * .execute(...) 047 * </code> 048 */ 049public class MybatisFlexBootstrap { 050 051 protected final AtomicBoolean started = new AtomicBoolean(false); 052 053 protected String environmentId = FlexConsts.NAME; 054 protected TransactionFactory transactionFactory; 055 056 protected FlexDataSource dataSource; 057 protected Configuration configuration; 058 protected List<Class<?>> mappers; 059 060 protected Class<? extends Log> logImpl; 061 062 063 /** 064 * 虽然提供了 getInstance,但也允许用户进行实例化, 065 * 用于创建多个 MybatisFlexBootstrap 实例达到管理多数据源的目的 066 */ 067 public MybatisFlexBootstrap() { 068 069 } 070 071 private static volatile MybatisFlexBootstrap instance; 072 073 public static MybatisFlexBootstrap getInstance() { 074 if (instance == null) { 075 synchronized (MybatisFlexBootstrap.class) { 076 if (instance == null) { 077 instance = new MybatisFlexBootstrap(); 078 } 079 } 080 } 081 return instance; 082 } 083 084 085 public <T> MybatisFlexBootstrap addMapper(Class<T> type) { 086 if (this.mappers == null) { 087 mappers = new ArrayList<>(); 088 } 089 mappers.add(type); 090 return this; 091 } 092 093 094 public MybatisFlexBootstrap start() { 095 if (started.compareAndSet(false, true)) { 096 097 FlexAssert.notNull(dataSource,"dataSource"); 098 099 //init configuration 100 if (configuration == null) { 101 102 if (transactionFactory == null) { 103 transactionFactory = new JdbcTransactionFactory(); 104 } 105 106 Environment environment = new Environment(environmentId, transactionFactory, dataSource); 107 configuration = new FlexConfiguration(environment); 108 } 109 110 if (logImpl != null) { 111 configuration.setLogImpl(logImpl); 112 } 113 114 //init sqlSessionFactory 115 new FlexSqlSessionFactoryBuilder().build(configuration); 116 117 //init mappers 118 if (mappers != null) { 119 mappers.forEach(configuration::addMapper); 120 } 121 122 LogFactory.getLog(MybatisFlexBootstrap.class).debug("Mybatis-Flex has started."); 123 } 124 125 return this; 126 } 127 128 129 /** 130 * 直接获取 mapper 对象执行 131 * 132 * @param mapperClass 133 * @return mapperObject 134 */ 135 public <T> T getMapper(Class<T> mapperClass) { 136 return Mappers.ofMapperClass(getEnvironmentId(), mapperClass); 137 } 138 139 140 public String getEnvironmentId() { 141 return environmentId; 142 } 143 144 public MybatisFlexBootstrap setEnvironmentId(String environmentId) { 145 this.environmentId = environmentId; 146 return this; 147 } 148 149 public TransactionFactory getTransactionFactory() { 150 return transactionFactory; 151 } 152 153 public MybatisFlexBootstrap setTransactionFactory(TransactionFactory transactionFactory) { 154 this.transactionFactory = transactionFactory; 155 return this; 156 } 157 158 public DataSource getDataSource() { 159 return dataSource; 160 } 161 162 public MybatisFlexBootstrap setDataSource(DataSource dataSource) { 163 this.dataSource = new FlexDataSource(FlexConsts.NAME, dataSource); 164 return this; 165 } 166 167 public MybatisFlexBootstrap setDataSource(String dataSourceKey, DataSource dataSource) { 168 this.dataSource = new FlexDataSource(dataSourceKey, dataSource); 169 return this; 170 } 171 172 public MybatisFlexBootstrap addDataSource(String dataSourceKey, DataSource dataSource) { 173 if (this.dataSource == null) { 174 this.dataSource = new FlexDataSource(dataSourceKey, dataSource); 175 } else { 176 this.dataSource.addDataSource(dataSourceKey, dataSource); 177 } 178 return this; 179 } 180 181 public Configuration getConfiguration() { 182 return configuration; 183 } 184 185 public MybatisFlexBootstrap setConfiguration(FlexConfiguration configuration) { 186 this.configuration = configuration; 187 this.environmentId = configuration.getEnvironment().getId(); 188 return this; 189 } 190 191 public List<Class<?>> getMappers() { 192 return mappers; 193 } 194 195 196 public Class<? extends Log> getLogImpl() { 197 return logImpl; 198 } 199 200 public MybatisFlexBootstrap setLogImpl(Class<? extends Log> logImpl) { 201 this.logImpl = logImpl; 202 return this; 203 } 204 205}