在前面的博文中,小编介绍了springmvc的相关知识点,在今天这篇博文中,小编将介绍一下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;
-
-
-
-
-
-
-
-
-
- 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>
第五步、编写具体的方法,如下所示:
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对象
在前面的博文中,小编介绍了springmvc的相关知识点,在今天这篇博文中,小编将介绍一下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;
-
-
-
-
-
-
-
-
-
- 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>
第五步、编写具体的方法,如下所示:
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对象