Как использовать родной mybatis:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
Employee employee = new Employee(null, "doubi", "1", "ddd@sys.com");
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
mapper.addEmp(employee);
session.commit();
} finally {
session.close();
}
Как использовать пружину, просто введите ее напрямую@Autowired
EmployeeMapper employeeMapper
Так что же делает нам весна? Изучим пакет jar mybatis-spring.jar
Во-первых, давайте посмотрим, как использовать Spring для интеграции mybatis.Вот четыре способа использования spring-mybatis:
Способ 1: (с использованием MapperFactoryBean)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<!--上面生成sqlSessionFactory的几个方法基本相同-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
Недостатком этого является то, что каждый интерфейс картографа должен быть настроен в xml
Способ 2. Используйте класс реализации интерфейса org.apache.ibatis.session.SqlSession.org.mybatis.spring.SqlSessionTemplate
В mybatis sessionFactory можно создать с помощью SqlSessionFactoryBuilder. MyBatis-Весна
, вместо этого используйте SqlSessionFactoryBean. SqlSessionFactoryBean имеет обязательный атрибут dataSource, а также общий атрибут configLocation (используется для указания пути файла конфигурации xml mybatis).
SqlSessionFactoryBean эквивалентен SqlSessionFactoryBuilder в собственном mybatis.
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
<!-- 自动扫描mapping.xml文件,**表示迭代查找,也可在sqlMapConfig.xml中单独指定xml文件-->
<property name="mapperLocations" value="classpath:com/hua/saf/**/*.xml" />
</bean>
<!-- mybatis spring sqlSessionTemplate,使用时直接让spring注入即可 -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
</bean>
//使用方法:
@Repositorypublic class UserDao{ @Resource private SqlSessionTemplate sqlSessionTemplate; public User getUser(int id) { return sqlSessionTemplate.selectOne(this.getClass().getName() + ".getUser", 1); } }
Почему так можно написать, давайте посмотрим на SqlSessionTemplate
public class SqlSessionTemplate implements SqlSession { private final SqlSessionFactory sqlSessionFactory; private final ExecutorType executorType; private final SqlSession sqlSessionProxy; private final PersistenceExceptionTranslator exceptionTranslator; /** * Constructs a Spring managed SqlSession with the {@code SqlSessionFactory} * provided as an argument. * * @param sqlSessionFactory */ public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType()); }
........省略......
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) { notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required"); notNull(executorType, "Property 'executorType' is required"); this.sqlSessionFactory = sqlSessionFactory; this.executorType = executorType; this.exceptionTranslator = exceptionTranslator; this.sqlSessionProxy = (SqlSession) newProxyInstance( SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor()); }
}
Как показано в приведенном выше коде, класс SqlSessionTemplate реализует интерфейс SqlSession в собственном Mybatis, фактически это SqlSession в собственном Mybatis.
Способ 3: Используйте абстрактные классыorg.mybatis.spring.support.SqlSessionDaoSupportПредоставить SqlSession
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
<!-- 自动扫描mapping.xml文件,**表示迭代查找,也可在sqlMapConfig.xml中单独指定xml文件-->
<property name="mapperLocations" value="classpath:com/hua/saf/**/*.xml" />
</bean>
public class BaseDao extends SqlSessionDaoSupport{ //使用sqlSessionFactory @Autowired private SqlSessionFactory sqlSessionFactory; @Autowired public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { super.setSqlSessionFactory(sqlSessionFactory); } /** * 执行insert操作 * @param statement * @return */ public int insert(String statement) { return getSqlSession().insert(statement); } /** * 执行insert操作 * @param statement * @param parameter * @return */ public int insert(String statement, Object parameter) { return getSqlSession().insert(statement, parameter); } public int update(String statement) { return getSqlSession().update(statement); } public int update(String statement, Object parameter) { return getSqlSession().update(statement, parameter); } public int delete(String statement) { return getSqlSession().delete(statement); } public int delete(String statement, Object parameter) { return getSqlSession().delete(statement, parameter); } /** * 获取一个list集合 * @param statement * @return */ public List<?> selectList(String statement) { return getSqlSession().selectList(statement); } /** * 根据参数 获取一个list集合 * @param statement * @param parameter * @return */ public List<?> selectList(String statement, Object parameter) { return getSqlSession().selectList(statement, parameter); } public Map<?, ?> selectMap(String statement, String mapKey) { return getSqlSession().selectMap(statement, mapKey); } public Map<?, ?> selectMap(String statement, Object parameter, String mapKey) { return getSqlSession().selectMap(statement, parameter, mapKey); } /** * 获取Object对象 * @param statement * @return */ public Object selectOne(String statement) { return getSqlSession().selectOne(statement); } /** * 获取connection, 以便执行较为复杂的用法 * @return */ public Connection getConnection() { return getSqlSession().getConnection(); } }
Как показано в приведенном выше коде, после того, как класс Dao наследует класс SqlSessionDaoSupport, он может внедрить SessionFactory в класс, а затем получить текущий SqlSession с помощью getSqlSession().
НижеИсходный код SqlSessionDaoSupport, который является абстрактным классом и имеет свойство sqlSession, экземпляр которого создается в методе setSqlSessionFactory:
public abstract class SqlSessionDaoSupport extends DaoSupport { private SqlSession sqlSession; private boolean externalSqlSession; public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { if (!this.externalSqlSession) { this.sqlSession = new SqlSessionTemplate(sqlSessionFactory); } } public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { this.sqlSession = sqlSessionTemplate; this.externalSqlSession = true; } public SqlSession getSqlSession() { return this.sqlSession; } protected void checkDaoConfig() { notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required"); }}
Способ 4: (такжеСамый распространенный способ использования, используя MapperScannerConfigurer, он будет искать сопоставления в пути к классам и автоматически создавать их как MapperFactoryBean)
Поскольку использование MapperFactoryBean напрямую приведет к настройке большого количества мапперов в конфигурационном файле, здесь используется метод сканирования пакетов для получения бина через аннотации
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
<property name="mapperLocations" value="classpath:com/hua/saf/**/*.xml" />
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 ,包下的类需要使用@MapperScan注解,否则容器注入会失败 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.hua.saf.*" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
//使用如下代码,即可完成注入
@Resource
private UserDao userDao;
Давайте взглянем на класс MapperScannerConfigurer:
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware { private String basePackage; private boolean addToConfig = true; private SqlSessionFactory sqlSessionFactory; private SqlSessionTemplate sqlSessionTemplate; private String sqlSessionFactoryBeanName; private String sqlSessionTemplateBeanName; private Class<? extends Annotation> annotationClass; private Class<?> markerInterface; private ApplicationContext applicationContext; private String beanName; private boolean processPropertyPlaceHolders; private BeanNameGenerator nameGenerator;
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.setAddToConfig(this.addToConfig); scanner.setAnnotationClass(this.annotationClass); scanner.setMarkerInterface(this.markerInterface); scanner.setSqlSessionFactory(this.sqlSessionFactory); scanner.setSqlSessionTemplate(this.sqlSessionTemplate); scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName); scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName); scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.registerFilters(); scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); }
ClassPathMapperScanner :
public Set<BeanDefinitionHolder> doScan(String... basePackages) { Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages); if (beanDefinitions.isEmpty()) { logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration."); } else { for (BeanDefinitionHolder holder : beanDefinitions) { GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition(); if (logger.isDebugEnabled()) { logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + definition.getBeanClassName() + "' mapperInterface"); } // the mapper interface is the original class of the bean // but, the actual class of the bean is MapperFactoryBean definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName()); definition.setBeanClass(MapperFactoryBean.class); definition.getPropertyValues().add("addToConfig", this.addToConfig); boolean explicitFactoryUsed = false; if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) { definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName)); explicitFactoryUsed = true; } else if (this.sqlSessionFactory != null) { definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory); explicitFactoryUsed = true; } if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) { if (explicitFactoryUsed) { logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); } definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName)); explicitFactoryUsed = true; } else if (this.sqlSessionTemplate != null) { if (explicitFactoryUsed) { logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); } definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate); explicitFactoryUsed = true; } if (!explicitFactoryUsed) { if (logger.isDebugEnabled()) { logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'."); } definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); } } } return beanDefinitions; }
Резюме: По сравнению с родным Mybatis, spring-mybatis имеет следующие концепции:
1) класс SqlSessionFactory существует в обоих
2) первый использует SqlSessionFactoryBean для создания SqlSessionFactory, а второй использует SqlSessionFactoryBuilder;
3) Первый использует SqlSessionTemplate, второй использует SqlSession, фактически первый реализует последний
4) Следующие шаги в нативном mybatis реализованы в MapperFactoryBean, поэтому объект реализации интерфейса картографа можно напрямую получить через этот класс.
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Вышеупомянутое является личным резюме, если есть какие-либо ошибки, пожалуйста, поправьте меня.