面试 Ibatis与mybatis区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试 Ibatis与mybatis区别相关的知识,希望对你有一定的参考价值。
我要他们的本质区别,不是网上所说的什么升级、改了个名字啥的。面试的时候经常问到。求在这方面有研究的大神指教。
这个区别不是很大,最主要的区别就是mybatis简化了编码的过程,不需要去写dao的实现类,直接写一个dao的借口,再写一个xml配置文件,整个mybatis就配置好了,也就是数据库就连接好了,然后再service里面调用dao就可以了,但是ibatis则不可以,必须要写dao的实现类,在写个什么return getSqlMapClientTemplate().queryForList()神马的,所以说mybatis是ibatis的升级版本,也就是在这里,不用写dao的实现类,还有些区别就是xml里面的sql语句的写法有些小变化,但是不大 参考技术A iBatis2.x 和 MyBatis 3.0.x 的区别
1、 全局配置文件命名
iBatis
通常把为 sqlMapConfig.xml,文件名本身并没有要求,在 MyBatis 中经常会将该文件命名为 Configuration.xml
2、 全局配置文件
<?xml
version="1.0" encoding="UTF-8" ?> iBatis 和 MyBatis 的全局配置文件使用不同的 DTD 约束,在将应用由
iBatis 升级至 MyBatis 时需要注意(两者的映射文件 DTD 约束也不相同)
<!DOCTYPE
configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
配置数据源相关的信息 -->
<environments
default="demo">
<environment id="demo">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value= … />
<property name="url" value= … />
<property
name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--
列出映射文件 -->
<mappers>
<mapper resource="footmark/mybatis/demo/UserInfoMapper.xml"/>
</mappers>
</configuration>
有了这些信息,MyBatis
便能够和数据库建立连接,并应用给定的连接池信息和事务属性。
MyBatis
封装了这些操作,最终暴露一个 SqlSessionFactory 实例供开发者使用,从名字可以看出来,
这是一个创建
SqlSession 的工厂类,通过 SqlSession 实例,开发者能够直接进行业务逻辑的操作,
而不需要重复编写
JDBC 相关的样板代码。根据全局配置文件生成 SqlSession 的代码如下:
Reader reader = Resources.getResourceAsReader("Configuration.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sqlSessionFactory.openSession();
上面的三行代码看做是
MyBatis 创建 SqlSession 的样板代码。
其中第一行代码在类路径上加载配置文件,Resources
是 MyBatis 提供的一个工具类,它用于简化资源文件的加载,它可以访问各种路径的文件,不过最常用的还是示例中这种基于类路径的表示方式
在完成全局配置文件,并通过
MyBatis 获得 SqlSession 对象之后,便可以执行数据访问操作了
--- 设置属性的区别
iBatis
:<settings props1="value1" props2="value2"… />
MyBatis
:<settings> <setting name="props1" value="value1"/> <setting
name="props2" value="value2"/> …… </settings>
---配置事务管理器和数据源的区别
iBatis
:
<transactionManager
type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="$driver"/>
</dataSource>
</transactionManager>
MyBatis
:
<environments
default="demo">
<environment id="demo">
<transactionManager type="JDBC"/>
<dataSource
type="POOLED">
<property
name="JDBC.Driver" value="$driver"/>
</dataSource>
</environment>
</environments>
通过
<environments> 来进行数据源管理,主要是为了简化在多套数据源配置之间的切换,比如开发和发布使用不同的配置。
3、 在映射文件中配置 SQL 语句
<?xml
version="1.0" encoding="UTF-8" ?>
<!DOCTYPE
mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace="mybatis.demo.UserInfoMapper">
<select id="selectUser" parameterType="int"
resultType="mybatis.demo.UserInfo">
select * from UserInfo where userid =#userid
</select>
</mapper>
在
iBatis 中,namespace 不是必需的,且它的存在没有实际的意义。在 MyBatis 中,namespace
终于派上用场了,它使得映射文件与接口绑定变得非常自然
---指定映射文件的方式的区别
iBatis:<sqlMap
resource=... /> <sqlMap resource=... /> <sqlMap resource=...
/>
MyBatis
:<mappers> <mapper resource=... /> <mapper resource=... />
</mappers>
4、 使用 SqlSession 执行映射文件中配置的 SQL
语句
try
UserInfo userinfo = (UserInfo) sqlSession.selectOne
("mybatis.demo.UserInfoMapper.getUser", 2);
System.out.println(userinfo);
finally
sqlSession.close();
需要注意的是,SqlSession
的使用必需遵守上面的格式,即在 finally 块中将其关闭。以保证资源得到释放,防止出现内存泄露!
5、 在 MyBatis 中使用代码进行配置
DataSource
ds = …… // 获取一个 DataSource
TransactionFactory
txFactory = new JdbcTransactionFactory();
Environment
env = new Environment("demo", txFactory, ds);
Configuration
cfg = new Configuration(env);
cfg.addMapper(UserInfoMapper.class);
SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfg);
结合前面的配置文件,很容易理解这段代码的意思,故不再赘述。不过,需要注意的是
Configuration 的 addMapper() 方法,该方法的参数通常是一个接口,可以在接口里面定义若干方法,在方法上使用注解来指定映射的 SQL
语句。一个典型的接口定义以及对应的数据访问方法如下:
6、 将映射的 SQL 语句与接口中的方法绑定
// 映射 SQL 绑定接口
public
interface UserInfoMapper
@Select("select * from userinfo where userid = #userid")
public UserInfo getUserInfo(int userid);
//
接口绑定对应的数据访问方法
try
//UserInfo
userinfo = (UserInfo) sqlSession.selectOne
("mybatis.demo.UserInfoMapper.selectUser", 2);
UserInfoMapper
userinfoMapper = sqlSession.getMapper(UserInfoMapper.class);
UserInfo
userinfo = userinfoMapper.getUserInfo(1);
System.out.println(userinfo);
finally
sqlSession.close();
7、 MyBatis
映射文件的改变(仅仅是名称的改变,用法和含义并没有发生变化)
和全局配置文件一样,由于 DTD
约束发生变化,根元素也由原来的 <sqlMap> 调整为 <mapper>。
<select> 等元素的
parameterClass 属性改为了 parameterType 属性。
<select> 等元素的
resultClasss 属性改为了 resultType 属性。
<parameterMap>
等元素的 class 属性改为了 type 属性。
<result> 元素的
columnIndex 属性被移除了。
嵌套参数由 #value# 改为了
#value。
<parameter>
等元素的 jdbcType 属性取值中,原来的 "ORACLECURSOR" 取值改为了现在的 "CURSOR","NUMBER" 取值改为了
"NUMERIC"。
iBatis/MyBatis
对存储过程的支持一直是值得称道的。之前通过使用 <procedure> 元素进行存储过程的定义,示例如下:
--- 存储过程的区别
iBatis:
<procedure id="getValues" parameterMap="getValuesPM">
? = call pkgExample.getValues(p_id => ?)
</procedure>
MyBatis
:
<select
id="getValues" parameterMap="getValuesPM" statementType="CALLABLE">
? = call pkgExample.getValues(p_id => ?)
</select>
通过
statementType 属性将该语句标识为存储过程而非普通 SQL 语句
8、代码层面的改变
MyBatis
在编码中的最大的改变就是将一个最常用的 API 由 SqlMapClient 改为了 SqlSessionFactory。
另外,类型处理器接口也由原来的
TypeHandlerCallback 改为了 TypeHandler。
最后
DataSourceFactory 也进行了调整,移动到 org.apache.ibatis.datasource
包下,其中的方法也作了微调。总之,代码层面公开的部分改动较少,不会给开发者造成较大的移植成本 参考技术B 感觉这有点过了.还不如叫面试官研究下mybatis与bee有什么区别.
ibatis语法
ibatis动态sql<select id="UPP_ENUM.selectCountByQuery" resultClass="java.lang.Integer" parameterClass="com.taobao.upp.biz.enumtype.dal.query.EnumQuery"> select count(*) from UPP_ENUM t <dynamic prepend="where"> <isNotNull prepend="and" property="typeName"> t.TYPE_NAME = #typeName# </isNotNull> <isNotNull prepend="AND" property="typeId"> t.TYPE_ID = #typeId# </isNotNull> <isNotNull prepend="AND" property="bizId"> t.BIZ_ID = #bizId# </isNotNull> </dynamic> </select> 这个SQL是否有问题???如果按照ibatis的语法来说 如果第一个条件存在的话,那么sql语句会变成select....where and... 如果是这样的话那是有sql的语法错误的。不知道是否有高人解释下,小弟刚接触ibatis。。 如果我写成下面这样把第一个and去掉是否可行?不过如果第一个条件不存在第二个条件存在的话 又和上面一样。迷惑········<select id="UPP_ENUM.selectCountByQuery" resultClass="java.lang.Integer" parameterClass="com.taobao.upp.biz.enumtype.dal.query.EnumQuery"> select count(*) from UPP_ENUM t <dynamic prepend="where"> <isNotNull prepend="" property="typeName"> t.TYPE_NAME = #typeName# </isNotNull> <isNotNull prepend="AND" property="typeId"> t.TYPE_ID = #typeId# </isNotNull> <isNotNull prepend="AND" property="bizId"> t.BIZ_ID = #bizId# </isNotNull> </dynamic> </select> 有知道的高手指点下, 谢谢!
如果你会用IBatis结合其他数据库的话,那结合oracle应该就不会有什么问题了吧。我现在用的就是IBatis和oracle,首先你的配置文件里,应该有数据源的配置,和sqlMapClient的配置,比如:
Java代码
1.<bean id="dataSource"
2.class="org.apache.commons.dbcp.BasicDataSource"
3.destroy-method="close">
4.<property name="driverClassName">
5.<value>net.sourceforge.jtds.jdbc.Driver</value>
6.</property>
7.<property name="url">
8.<value>jdbc:jtds:sqlserver://127.0.0.1:1433/Sample</value>
9.</property>
10.<property name="username">
11.<value>test</value>
12.</property>
13.<property name="password">
14.<value>123456</value>
15.</property>
16.</bean>
17.
18.<bean id="sqlMapClient"
19.class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
20.<property name="configLocation">
21.<value>SqlMapConfig.xml</value>
22.</property>
23.</bean>
24.
25.<bean id="userDAO" class="com.cn.dao.UserDAO">
26.<property name="dataSource">
27.<ref local="dataSource" />
28.</property>
29.<property name="sqlMapClient">
30.<ref local="sqlMapClient" />
31.</property>
32.</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>net.sourceforge.jtds.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:jtds:sqlserver://127.0.0.1:1433/Sample</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>SqlMapConfig.xml</value>
</property>
</bean>
<bean id="userDAO" class="com.cn.dao.UserDAO">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="sqlMapClient">
<ref local="sqlMapClient" />
</property>
</bean>
然后就是你的sqlmap配置文件SqlMapConfig.xml
Java代码
1.<sqlMapConfig>
2.<sqlMap resource="com/cn/dao/entity/sqlmap-mapping.xml"/>
3.</sqlMapConfig>
<sqlMapConfig>
<sqlMap resource="com/cn/dao/entity/sqlmap-mapping.xml"/>
</sqlMapConfig>
然后就是sqlmap-mapping.xml
Java代码
1.<sqlMap namespace="User">
2.<typeAlias alias="user" type="net.xiaxin.dao.entity.User" />
3.<insert id="insertUser" parameterClass="user">
4.INSERT INTO users ( username, password) VALUES ( #username#,
5.#password# )
6.</insert>
7.</sqlMap>
<sqlMap namespace="User">
<typeAlias alias="user" type="net.xiaxin.dao.entity.User" />
<insert id="insertUser" parameterClass="user">
INSERT INTO users ( username, password) VALUES ( #username#,
#password# )
</insert>
</sqlMap>
最后就是DAO调用sqlmap的实现
UserDAO.java
Java代码
1.public class UserDAO extends SqlMapClientDaoSupport implements
2.IUserDAO
3.public void insertUser(User user)
4.getSqlMapClientTemplate().update("insertUser", user);
5.
6.
public class UserDAO extends SqlMapClientDaoSupport implements
IUserDAO
public void insertUser(User user)
getSqlMapClientTemplate().update("insertUser", user);
以上代码仅供参考 参考技术A 第一个不能去掉,如果第一个存在ibatis会自动去掉,但如果你不写第二个也存在时就会报错。
以上是关于面试 Ibatis与mybatis区别的主要内容,如果未能解决你的问题,请参考以下文章
ibatis/mybatis属性三:resultMap和resultClass/resultType