当前位置: 移动技术网 > IT编程>开发语言>Java > spring-mybatis与原生mybatis使用对比分析

spring-mybatis与原生mybatis使用对比分析

2019年07月19日  | 移动技术网IT编程  | 我要评论

原生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();  
}

spring使用方法,直接注入即可

@autowired
employeemapper employeemapper

那么spring为我们做了什么?下面研究一下mybatis-spring.jar这个jar包

首先来看一下如何使用spring整合mybatis,下面是使用spring-mybatis的四种方法:

方法一:(使用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>

这样做的缺点是每一个mapper接口都要在xml里配置一下

方法二:采用接口org.apache.ibatis.session.sqlsession的实现类 org.mybatis.spring.sqlsessiontemplate

mybatis中, sessionfactory可由sqlsessionfactorybuilder.来创建。mybatis-spring 中,使用了sqlsessionfactorybean来替代。sqlsessionfactorybean有一个必须属性datasource,另外其还有一个通用属性configlocation(用来指定mybatis的xml配置文件路径)。

sqlsessionfactorybean即相当于原生mybatis中的sqlsessionfactorybuilder

<!-- 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类实现了原生mybatis中的sqlsession接口,实际上它就是原生mybatis中的sqlsession

方法三:采用抽象类 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类后,就可以在类中注入sessionfact
ory,进而通过getsqlsession()获取当前sqlsession

下面是 sqlsessiondaosupport的源码 ,它是一个抽象类,并拥有sqlsession属性,在setsqlsessionfactory方法中实例化了该sqlsession:

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"); }}

方法四:(也是 最常见的使用方法 ,使用mapperscannerconfigurer,它将会查找类路径下的映射器并自动将它们创建成mapperfactorybean)

由于直接使用mapperfactorybean会在配置文件中配置大量mapper,因此这里使用包扫描的方式通过注解获取该bean

<!-- 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; }

总结:spring-mybatis与原生mybatis相比,如下概念:

1)sqlsessionfactory类在两者中都存在

2)前者用sqlsessionfactorybean生成sqlsessionfactory,后者则使用sqlsessionfactorybuilder;

3)前者使用sqlsessiontemplate,后者使用sqlsession,实际上前者实现了后者

4)mapperfactorybean中实现了原生mybatis中下面的步骤,因此通过该类可以直接获取到一个mapper接口的实现对象

employeemapper mapper = session.getmapper(employeemapper.class);

总结

以上所述是小编给大家介绍的spring-mybatis与原生mybatis使用对比分析,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网