什么是mybatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
相比hibernate 的 优缺点
优点
1)不需要编写的SQL语句(不需要编辑JDBC),只需要操作相应的对象就可以了,就可以能够存储、更新、删除、加载对象,可以提高生产效
(2)使用Hibernate,移植性好(只要使用Hibernate标准开发,更换数据库时,只需要配置相应的配置文件就可以了,不需要做其它任务的操作)
(3)Hibernate实现了透明持久化。当保存一个对象时,这个对象不需要继承Hibernate中的任何类、实现任何接口,只是个纯粹的单纯对象—称为POJO对象(最纯粹的对象—这个对象没有继承第三方框架的任何类和实现它的任何接口)
(4)Hibernate是一个没有侵入性的框架,没有侵入性的框架我们一般称为轻量级框架
(5)Hibernate代码测试方便
(6)有更好的二级缓存机制,可以使用第三方缓存
缺点
(1)使用数据库特性的语句,将很难调优
(2)对大批量数据更新存在问题
(3)系统中存在大量的攻击查询功能
(4)缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。
下载地址: https://github.com/mybatis/mybatis-3
执行原理
加载配置
配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
SQL解析
当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
SQL执行
将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
结果映射
将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。
在传统的分层结构中 有大量的Dao层实现类 随着项目的扩展 这些类文件会越来越多 不方便维护MyBatis 提供一种Dao层解决方案 纯接口开发
只有接口 没有实现类 mybatis会自动生成代理对象 完成实现类
第一行代码
<?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>
<!-- 加载配置文件 必须放在src 下-->
<properties resource="db.properties"></properties>
<!-- 为类加上别名 用于简化书写 别名不区分大小写 -->
<typeAliases>
<typeAlias type="com.lanou.bean.Person" alias="person"></typeAlias>
</typeAliases>
<!-- 当前为开发管理 -->
<environments default="development">
<environment id="development">
<!-- 事物管理 -->
<transactionManager type="JDBC"/>
<!-- 数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<mapper resource="com/james/bean/Person.xml"></mapper>
<!-- 指定与映射文件关联的那个接口类名
要求:映射文件必须与接口名字相同 并且在同一级目录-->
<!--<mapper class=""></mapper>-->
<!-- 指定扫描某个包下所有的映射文件-->
<package name="com/james/dao" />
</mappers>
</configuration>
Dao层
PersonDao.xml
public interface PersonDao {
// 根据id 查询用户
public Person SelectPersonById(int id);
}
PersonDao.xml
<?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="com.lanou.dao.PersonDao">
<!-- 要求 id 必须和 方法名保存一致 且 区分大小写
返回值类型也必须一样
参数必须与接口方法中一致
-->
<select id="SelectPersonById" parameterType="int" resultType="com.lanou.bean.Person">
select * from person where id = #{id}
</select>
</mapper>
Daotest.java
@Test
public void testMain() throws Exception {
// 构造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 读取配置文件
InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
// 获取会话工厂
SqlSessionFactory factory = builder.build(input);
// 获取会话
SqlSession sqlSession = factory.openSession();
// crud
// selectOne 查询单个
// 指定Sql 的id 和需要的参数
Person person = sqlSession.selectOne("test.findPersonById", 1);
System.out.println(person);
}