欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mybatis原理概述入门教程

程序员文章站 2024-03-31 21:05:10
本文我将要介绍一下mybatis的框架原理,以及mybatis的入门程序,实现用户的增删改查,她有什么优缺点以及mybatis和hibernate之间存在着怎么样的关系,希...

本文我将要介绍一下mybatis的框架原理,以及mybatis的入门程序,实现用户的增删改查,她有什么优缺点以及mybatis和hibernate之间存在着怎么样的关系,希望对小伙伴们有帮助,不足之处,还请多多指教。

什么是mybatis?

mybatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为mybatis 。2013年11月迁移到github。

mybatis 是支持定制化 sql、存储过程以及高级映射的优秀的持久层框架。mybatis 避免了几乎所有的 jdbc 代码和手工设置参数以及抽取结果集。mybatis 使用简单的 xml 或注解来配置和映射基本体,将接口和 java 的 pojo(plain old java objects,普通的 java对象)映射成数据库中的记录。简单来说,mybatis就是一个持久层的框架,mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,*灵活生成满足需要的sql语句,mybatis可以将向preparedstatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。

接着,我们通过一张图,来了解一下mybatis的框架原理:

框架架构讲解:

a、加载配置文件:配置来源于两个地方,一个是配置文件,一个是java代码的注解,将sql的配置信息加载成为一个个mappedstatement对象(包括了传入参数映射配置、执行的sql语句、结果映射配置),存储在内存中。

b、sql解析:当api接口层接收到调用请求时,会接收到传入slq的id和传入对象(可以是map或者基本数据类型),mybatis会根据sql的id找到对应的mappedstatement,然后根据传入参数对象对mappedstatement进行解析,解析后可以得到最终要执行的sql语句和参数。

c、 sql执行:将最终得到的sql和参数拿到数据库进行执行,得到操作数据库的结果。

d、结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成hashmap、javabean或者基本数据类型,并将最终结果返回。

mybatis入门程序解析

接着,小编结合demo来具体介绍一下,需求如下:

根据用户id查询用户信息;

根据用户名称模糊查询用户信息;

添加、删除、更新用户。

第一步、建立各种包和类,工程目录如下所示:

第二步、编写sqlmapconfig.xml中的内容,配置mybatis的运行环境,数据源,事务等。代码如下所示:

<span style="font-family:comic sans ms;font-size:18px;"><?xml version="1.0" encoding="utf-8" ?> 
<!doctype configuration 
public "-//mybatis.org//dtd config 3.0//en" 
"http://mybatis.org/dtd/mybatis-3-config.dtd"> 
<configuration> 
<!-- 将spring整合后environments配置将废除 --> 
<environments default="developent"> 
<!-- 使用jdbc事务管理,事务控制由mybatis --> 
<transactionmanager type="jdbc"/> 
<!-- 数据库连接池,由mybatis管理 --> 
<datasource type="polled"> 
<property name="driver" value="${jdbc.driver}"/> 
<property name="url" value="${jdbc.url}"/> 
<property name="username" value="${jdbc.username}"/> 
<property name="password" value="${jdbc.password}"/> 
</datasource> 
</environments> 
<!-- 加载 映射文件 --> 
<mappers> 
<mapper resource="sqlmap/user.xml"/> 
</mappers> 
</configuration> 
</span>

第三步、编写user.java中的内容,如下所示:

<span style="font-family:comic sans ms;font-size:18px;">package cn.itcast.mybatis.po; 
import java.util.date; 
/** 
* 
* <p>title: user</p> 
* <p>description:用户po </p> 
* @author 丁国华 
* @date 2016年7月31日 15:39:04 
* @version 1.0 
*/ 
public class user { 
//属性名和数据库表的字段对应 
private int id; 
private string username;// 用户姓名 
private string sex;// 性别 
private date birthday;// 生日 
private string address;// 地址 
public int getid() { 
return id; 
} 
public void setid(int id) { 
this.id = id; 
} 
public string getusername() { 
return username; 
} 
public void setusername(string username) { 
this.username = username; 
} 
public string getsex() { 
return sex; 
} 
public void setsex(string sex) { 
this.sex = sex; 
} 
public date getbirthday() { 
return birthday; 
} 
public void setbirthday(date birthday) { 
this.birthday = birthday; 
} 
public string getaddress() { 
return address; 
} 
public void setaddress(string address) { 
this.address = address; 
} 
@override 
public string tostring() { 
return "user [id=" + id + ", username=" + username + ", sex=" + sex 
+ ", birthday=" + birthday + ", address=" + address + "]"; 
} 
} 
</span>

第四步、实现增删改查的功能,首先编写user.xml中的内容,如下所示:

<span style="font-family:comic sans ms;font-size:18px;"><?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"> 
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 
注意:使用mapper代理方法开发,namespace有特殊重要的作用--> 
<mapper namespace="test"> 
<!-- 在 映射文件中配置很多sql语句 --> 
<!-- 需求:通过id查询用户表的记录 --> 
<!-- 通过 select执行数据库查询 
id:标识 映射文件中的 sql 
将sql语句封装到mappedstatement对象中,所以将id称为statement的id 
parametertype:指定输入 参数的类型,这里指定int型 
#{}表示一个占位符号 
#{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称 
resulttype:指定sql输出结果 的所映射的java对象类型,select指定resulttype表示将单条记录映射成的java对象。 
--> 
<select id="finduserbyid" parametertype="int" resulttype="cn.itcast.mybatis.po.user"> 
select * from user where id=#{value} 
</select> 
<!-- 根据用户名称模糊查询用户信息,可能返回多条 
resulttype:指定就是单挑记录所映射的java对象类型 
${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接到sql中。 
使用${}拼接sql,引起sql注入 
${value}:接收输入参数的内容,如果传入类型是简单类型,${}中只能使用value --> 
<select id="finduserbyname" parametertype="java.lang.string" resulttype="cn.itcast.mybatis.po.user"> 
select * from user where username like '%${value}%' 
</select> 
<!-- 添加用户 
parametertype:指定输入参数类型是pojo(包括用户信息) 
#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过ognl获取对象的属性值 --> 
<insert id="insertuser" parametertype="cn.itcast.mybatis.po.user"> 
<!-- 将插入数据的主键返回,返回到user对象中 
select last_insert_id():得到刚刚insert进去记录的主键值,只适用于自增主键 
keyproperty:将查询得到主键值设置到parametertype指定的对象的那个属性 
order:select last_insert_id()执行顺序,相对于insert语句来说她的执行顺序 
resulttype:指定select last_insert_id()的结果类型 
--> 
<selectkey keyproperty="id" order="after" resulttype="java.lang.integer"> 
select last_inser_id() 
</selectkey> 
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}) 
<!-- 使用mysql的uuid()函数生成主键 
执行过程,首先通过uuid得到主键,将主键设置到user对象的id属性中 
其次,在insert执行的时候,从user对象中,取出id属性值 --> 
<selectkey keyproperty="id" order="before" resulttype="java.lang.string"> 
select uuid() 
</selectkey> 
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}); 
</insert> 
<!-- 删除用户 
根据id删除用户,需要输入id值 --> 
<delete id="deleteuser" parametertype="java.lang.integer"> 
delete from user where id=#{id} 
</delete> 
<!-- 根据id更新用户 
分析: 
需要传入用户的id 
需要传入用户的更新信息 
parametertype指定user对象,包括 id和更新信息,注意:id必须存在 
#{id}:从输入 user对象中获取id属性值 
--> 
<update id="updateuser" parametertype="cn.itcast.mybatis.po.user"> 
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} 
where id=#{id} 
</update> 
</mapper></span>

第五步、编写具体的方法,如下所示:

<span style="font-family:comic sans ms;font-size:18px;">package cn.itcast.mybatis.first; 
import java.io.ioexception; 
import java.io.inputstream; 
import java.util.date; 
import java.util.list; 
import org.apache.ibatis.io.resources; 
import org.apache.ibatis.session.sqlsession; 
import org.apache.ibatis.session.sqlsessionfactory; 
import org.apache.ibatis.session.sqlsessionfactorybuilder; 
import org.junit.test; 
import cn.itcast.mybatis.po.user; 
public class mybatisfirst { 
// 根据id查询用户信息,得到一条记录结果 
@test 
public void finduserbyidtest() throws ioexception { 
// mybatis配置文件 
string resource = "sqlmapconfig.xml"; 
// 得到配置文件流 
inputstream inputstream = resources.getresourceasstream(resource); 
// 创建会话工厂,传入mybatis的配置文件信息 
sqlsessionfactory sqlsessionfactory = new sqlsessionfactorybuilder() 
.build(inputstream); 
// 通过工厂得到sqlsession 
sqlsession sqlsession = sqlsessionfactory.opensession(); 
// 通过sqlsession操作数据库 
// 第一个参数:映射文件中statement的id,等于=namespace+"."+statement的id 
// 第二个参数:指定和映射文件中所匹配的parametertype类型的参数 
// sqlsession.selectone结果 是与映射文件中所匹配的resulttype类型的对象 
// selectone查询出一条记录 
user user = sqlsession.selectone("test.finduserbyid", 1); 
system.out.println(user); 
// 释放资源 
sqlsession.close(); 
} 
//根据用户名称模糊查询用户列表 
@test 
public void finduserbynametest() throws ioexception{ 
//mybatis配置文件 
string resource ="sqlmapconfig.xml"; 
//得到配置文件 
inputstream inputstream = resources.getresourceasstream(resource); 
//创建会话工厂,传入mybatis的配置文件信息 
sqlsessionfactory sqlsessionfactory = new sqlsessionfactorybuilder().build(inputstream); 
//通过工厂得到sqlsession 
sqlsession sqlsession = sqlsessionfactory.opensession(); 
//list中的user和映射文件中德resulttype所指定的类型一致 
list<user> list = sqlsession.selectlist("test.finduserbyname","小明"); 
system.out.println(list); 
sqlsession.close(); 
} 
public void insertusertest() throws ioexception{ 
//mybatis配置文件 
string resource ="sqlmapconfig"; 
//得到配置文件流 
inputstream inputstream = resources.getresourceasstream(resource); 
//创建会话工厂,传入mybatis的配置文件信息 
sqlsessionfactory sqlsessionfactory = new sqlsessionfactorybuilder().build(inputstream); 
//通过工厂得到sqlsession 
sqlsession sqlsession = sqlsessionfactory.opensession(); 
//插入用户对象 
user user = new user(); 
user.setusername("丁国华"); 
user.setbirthday(new date()); 
user.setsex("1"); 
user.setaddress("安徽合肥"); 
//list中的user和映射文件中的resulttype所指定的类型一直 
sqlsession.insert("test.insertuser",user); 
//提交事物 
sqlsession.commit(); 
//关闭会话 
sqlsession.close(); 
} 
//根据id删除用户信息 
@test 
public void deleteusertest() throws ioexception{ 
//mybatis配置文件 
string resource = "sqlmapconfig.xml"; 
//得到配置文件流 
inputstream inputstream = resources.getresourceasstream(resource); 
//创建工厂,传入mybatis的配置文件信息 
sqlsessionfactory sqlsessionfactory = new sqlsessionfactorybuilder().build(inputstream); 
//通过工厂得到sqlsession 
sqlsession sqlsession = sqlsessionfactory.opensession(); 
//传入id删除用户 
sqlsession.delete("test.deleteuser",39); 
//提交事物 
sqlsession.commit(); 
//关闭会话 
sqlsession.close(); 
} 
// 更新用户信息 
@test 
public void updateusertest() throws ioexception { 
// mybatis配置文件 
string resource = "sqlmapconfig.xml"; 
// 得到配置文件流 
inputstream inputstream = resources.getresourceasstream(resource); 
// 创建会话工厂,传入mybatis的配置文件信息 
sqlsessionfactory sqlsessionfactory = new sqlsessionfactorybuilder() 
.build(inputstream); 
// 通过工厂得到sqlsession 
sqlsession sqlsession = sqlsessionfactory.opensession(); 
// 更新用户信息 
user user = new user(); 
//必须设置id 
user.setid(41); 
user.setusername("丁国华"); 
user.setbirthday(new date()); 
user.setsex("2"); 
user.setaddress("安徽合肥"); 
sqlsession.update("test.updateuser", user); 
// 提交事务 
sqlsession.commit(); 
// 关闭会话 
sqlsession.close(); 
} 
} 
</span>

mybatis的优缺点

优点:

a、易于上手和掌握。

b、sql写在xml里,便于统一管理和优化。

c、 解除sql与程序代码的耦合。

d、提供映射标签,支持对象与数据库的orm字段关系映射

e、提供对象关系映射标签,支持对象关系组建维护

f、提供xml标签,支持编写动态sql。

缺点:

a、 sql工作量很大,尤其是字段多、关联表多时,更是如此。

b、sql依赖于数据库,导致数据库移植性差。

c、 由于xml里标签id必须唯一,导致dao中方法不支持方法重载。

d、dao层过于简单,对象组装的工作量较大。

e、 缓存使用不当,容易产生脏数据。

mybatis和hibernate的对比

相同点:hibernate和mybatis都可以是通过sessionfactorybuilder由xml配置文件生成sessionfactory,然后由sessionfactroy生成session,最后由session来开启执行事物和sql语句,其中sessionfactorybuider、sessionfactory、session的生命周期都是差不多的。

不同点:

mybatis:小巧、方便、高效、简单、直接、半自动;

hibernate:强大、方便、高效、复杂、绕弯子、全自动;

mybatis:

a、入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很多的sql使用经验,对于没有那么高的对象模型要求的项目来说,堪称perfect。

b、 可以进行更为细致的sql优化,可以减少查询字段。

c、 缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

d、 二级缓存机制不佳。

hibernate:

a、功能强大,数据库无关性好,o/r映射能力强,如果你对hibernate相当精通,而且对hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很,开发速度很快,非常爽。

b、有更好的二级缓存机制,可以使用第三方缓存。

c、缺点就是学习门槛不低,要精通门槛更高,而且怎么设计o/r映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好hibernate方面需要你的经验和能力都很强才行。

举个形象的比喻:

mybatis:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使由我决定。

hibernate:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以摆脱他了,但仅限于它能做的事。

小编寄语:该博文,小编主要简单的介绍了mybatis的基本知识,包括一个简单的增删改查的demo,mybatis的优缺点,以及hibernate和mybatis的对比,她们之间的相同点和不同,mybatis简单来说,就是一个持久层的框架,mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,*灵活生成满足需要的sql语句,mybatis可以将向preparedstatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。

以上所述是小编给大家介绍的mybatis原理概述入门教程,希望对大家有所帮助