一、Mybatis 框架之原理及基本概念
1、MyBatis框架概念
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
- Mybatis是一个半ORM(对象关系映射)框架,底层封装了JDBC,是程序员在开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。使得程序员可以花更多的精力放到业务开发中。另外,程序员直接编写原生态sql,严格控制sql执行性能,灵活度高。
- MyBatis 可以使用简单的 XML文件 或注解方式来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
- 通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。
2、Mybaits框架的优点
- 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
- 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
- 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
- 能够与Spring很好的集成;
- 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
3、MyBatis框架的缺点
- SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
- SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
4、MyBatis框架适用场合
- MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。
- 对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。
5、MyBatis与Hibernate有哪些不同
- Mybatis是一个半自动的ORM框架,在查询关联对象或关联集合对象时,需要手动编写sql语句来完成;
Hibernate是全自动ORM映射工具,查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,不需要编写sql.- Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,
非常适合对性能要求高,需求变化频繁的项目;但是如果涉及到较多的字段或者关联多表时,sql语句编写量大且对开发人的sql语句编写功底要求高。- Hibernate对象/关系映射能力强,数据库无关性好,适合需求变化不大的项目,使用hibernate开发可以节省很多代码,提高效率。
二、架构
我们把Mybatis的功能架构分为三层:
1、API接口层
提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
2、数据处理层
负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
3、基础支撑层
负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
Mybatis是一个二级的orm框架(对象关系管理),他是封装了jdbc、提高了我们的开发效率。(dao层框架)
三、Mybatis
1、Mybatis入门
准备对应的业务实体类,并且封装
/**
* 功能描述
*
* @author fengzi
* 万物皆对象
* 代码里有对象,我敲代码我快乐
*/
public class UserInfo {
private int userid;
private String username;
private String userpass;
public int getUserid() {
return userid;
}
导包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.4</version>
</dependency>
<!--导入mybatis包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
书写主配置文件
相关配置官网:https://mybatis.org/mybatis-3/configuration.html
名字随便定:mybatis-config.xml
<!--mybatis主配置-->
<configuration>
<!--环境配置 default默认使用哪个环境-->
<environments default="mysql">
<!--具体单个环境配置 id环境名或者环境标示符-->
<environment id="mysql">
<!--事务管理器配置 JDBC原始的JDBC的事务管理,切记大写-->
<transactionManager type="JDBC"></transactionManager>
<!--数据源配置 type对应的数据源连接方式,有三种
POOLED :连接池连接方式
UNPOOLED:非连接池,每次都会生成新的连接
JNDI:取决于你服务器所采用的连接方式
-->
<dataSource type="POOLED">
<!--相关属性配置-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--引入Mapper配置文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
附属说明:关于<dataSource type="POOLED">
的详细说明
mybatis连接池为我们提供了3种方式的配置:
- POOLED:采用传统的
javax.sql.DataSource
规范中的连接池,mybatis中有针对规范的实现- UNPOOLED:采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
- JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
注意:如果不是web或者maven的war工程,JNDI是不能使用的
2、POOLED数据源的配置方式
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
UNPOOLED数据源的配置方式
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
JNDI数据源的配置方式
将数据源的配置文件
context.xml
放到工程的webapp/META-INF/
下
context.xml
<Resource
name="jdbc/mybatis" 数据源的名称
type="javax.sql.DataSource" 数据源类型
auth="Container" 数据源提供者
maxActive="20" 最大活动数
maxWait="10000" 最大等待时间
maxIdle="5" 最大空闲数
username="root" 用户名
password="1234" 密码
driverClassName="com.mysql.jdbc.Driver" 驱动类
url="jdbc:mysql://localhost:3306/mybatis" 连接url字符串
/>
然后在mybatis的主配置文件中配置数据源,其中前缀
"java:comp/env/"
是
固定的,后缀"jdbc/mybatis"
是在context.xml
中取的JNDI数据源名称
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/mybatis"/>
</dataSource>
3、建立dao层接口
/**
* 功能描述
*
* @author fengzi
* 万物皆对象
* 代码里有对象,我敲代码我快乐
*/
public interface UserInterDao {
//数据添加方法
Integer addUser(UserInterDao user);
//数据修改方法
Integer updateUser(UserInterDao user);
//数据删除方法
Integer deleteUser(Integer UserId);
//数据查询方法
List<UserInterDao> selectUser();
}
书写对应的mapper配置文件,在resource下面建对应的包,新建对应的
UserMapper.xml
文件加入相关mapper配置信息
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper配置用来装sql语句 namespace指定dao层接口-->
<mapper namespace="com.qf.dao.UserInterDao">
<!--查询语句 id对应的是dao层接口的相关方法 |resultType设置返回值类型-->
<select id="selectUser" resultType="UserMain.UserInfo">
select * from userinfo
</select>
<update id="">
</update>
</mapper>
执行Mapper文件—将Mapper引入到主配置文件
Mybatis-config.xml
中
<!--mybatis主配置-->
<configuration>
<!--环境配置 default默认使用哪个环境-->
<environments default="mysql">
<!--具体单个环境配置 id环境名或者环境标示符-->
<environment id="mysql">
<!--事务管理器配置 JDBC原始的JDBC的事务管理,切记大写-->
<transactionManager type="JDBC"></transactionManager>
<!--数据源配置 type对应的数据源连接方式,有三种
POOLED :连接池连接方式
UNPOOLED:非连接池,每次都会生成新的连接
JNDI:取决于你服务器所采用的连接方式
-->
<dataSource type="POOLED">
<!--相关属性配置-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql///test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--引入Mapper配置文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
测试 ctr+alt+v 快捷获得返回值
//读取文件
//构建工厂-抽象工厂模式
//生产对应的sqlSession执行对象
//动态代理处dao层接口的实现类
//调用方法,执行操作
//打印输出
四、完整测试代码
package Test;
import UserMain.UserInfo;
import com.qf.dao.UserInterDao;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* 功能描述
*
* @author fengzi
* 万物皆对象
* 代码里有对象,我敲代码我快乐
*/
public class Mybatis_Test {
//测试查询
@Test
public void TestSelectUser() throws IOException {
//读取配置文件--流读取
InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
//通过配置构建工厂-抽象工厂模式
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream);
//生产对应的sqlSession执行对象
SqlSession sqlSession = build.openSession();
//动态代理处dao层接口的实现类
UserInterDao user = sqlSession.getMapper(UserInterDao.class);
//调用方法,执行操作
List<UserInfo> userInfos = user.selectUser();
//打印输出
System.out.println(userInfos);
}
}
Mybatis相关的配置详解
<!--环境配置 default默认使用哪个环境 后期整合就删除-->
<environments default="mysql">
<!--具体单个环境配置 id环境名或者环境标示符-->
<!--事务管理器配置 JDBC原始的JDBC的事务管理,切记大写-->
<transactionManager type="JDBC"></transactionManager>
<!--引入Mapper配置文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
<!--mapper配置用来装sql语句 namespace指定dao层接口-->
<mapper namespace="com.qf.dao.UserInterDao">
//生产对应的sqlSession执行对象
SqlSession sqlSession = build.openSession();
//动态代理处dao层接口的实现类
//UserInterDao user = sqlSession.getMapper(UserInterDao.class);
//调用方法,执行操作
//List<UserInfo> userInfos = user.selectUser();
//底层写法相当于JDBC 中sta执行ExcuteQuery(sql)
List<UserInfo> list = sqlSession.selectList("selectUser");
//打印输出
System.out.println(list);
五、主配置文件中常见的注解配置
给类和包取别名
<!--Mybatis 当中常见的一些注解-->
<!--类型别名配置 在主文件当中取别名,在配置文件当中用-->
<typeAliases>
<!--给一个类取别名 type对应的类-->
<!--<typeAlias type="UserMain.UserInfo" alias="user">
</typeAlias>-->
<!--给包取别名 包下的所有类都有别名,别名为类名 name 为包的完整名字,别名不区分大小写-->
<package name="UserMain"/>
</typeAliases>
相当于定义对应变量或者属性
<!--用来导入外部配置的-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
</properties>
使用${名字}取值
<dataSource type="POOLED">
<!--相关属性配置-->
<property name="driver" value="${driver}"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
Mybatis中的CRUD
<!--mapper配置用来装sql语句 namespace指定dao层接口-->
<mapper namespace="com.qf.dao.UserInterDao">
<!--查询语句 id对应的是dao层接口的相关方法 |resultType设置返回值类型-->
<select id="selectUser" resultType="UserInfo">
select * from userinfo
</select>
<!--增删改 没有返回值类型默认返回Int类型 参数类型 lan的g包下基本数据类型,名字为类型名 int String byte-->
<!-- #{属性名}为占位符表达式-->
<insert id="addUser" parameterType="UserInfo">
INSERT INTO userinfo(username,userpass) VALUES(#{username},#{userpass})
</insert>
<!--修改方法-->
<update id="updateUser" parameterType="UserInfo">
update userinfo set username=#{username},userpass=#{userpass} where userid=#{userid}
</update>
<delete id="deleteUser">
delete from userinfo where userid=#{userid}
</delete>
</mapper>
在添加,删除,修改操作的时候默认不提交事务,要手动提交事务
@After
public void close() throws IOException {
sqlSession.close();
stream.close();
//事务提交
sqlSession.commit();
//事务回滚
//sqlSession.rollback();
}
总结
文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!