框架和什么是Mybatis
Mybatis学习
1. 框架
1.1 什么是框架
框架(framework)是整个或部分系统的可重用设计,表现为一组抽象及构建实例间交互的方法;另一种定义认为:框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成自己的系统。简单就是说使用别人搭好的五大,你来做表演。而且,框架一般是成熟的,不断升级的软件。
框架封装了很多的细节,使开发者可以使用极简的方式实现功能,大大提高开发效率。
1.2 框架要解决的问题
框架要解决的最重要的一个问题是技术整合的问题。在 J2EE 的框架中,有着各种各样的技术,不同的软件企业需要从 J2EE 中选择不同的技术,这样就使得软件企业最终的应用依赖于这些技术,技术自身的复杂性和技术的风险性会直接对应用造成冲击。而应用是软件公司的核心。是竞争力的关键所在,因此应该将应用自身的设计和具体的实现技术解耦。这样,软件企业的研发将集中在应用的设计上,而不是具体的技术的实现。技术实现是应用的底层支撑,它不应该直接对应用产生影响。
框架一般处于底层应用平台(如J2EE)和高层业务逻辑之间的中间层。
1.3 持久层技术解决方案
-
JDBC技术:
- Connection
- PreparedStatement
-
Spring 的jdbcTemplate
- Spring 中对 jdbc 的简单封装
-
Apache 的 DBUtils
- 它和Spring的 JdbcTemplate 很像,也是对Jdbc的简单封装。
但是以上这些都不是框架!
JDCB是规范,Spring的 JdBCTemplate 和 Apache 的 DBUtils 都是工具类。
2. 什么是 Mybatis
2.1 Mybatis
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
当前,最新版本是MyBatis 3.5.2 ,其发布时间是2019年7月15日。
2.2 基本信息
Mybatis 是一款优秀的基于 Java 持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
Mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 SQL 的动态参数进行映射生成最终执行的 sql 语句,最后由 Mybatis 框架执行 sql 并将结果映射为 Java 对象并返回。
采用 ORM(对象关系映射 Object Relational Mapping),思想解决了实体和数据库的映射问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
注:ORM:
Object Relational Mapping 对象关系映射
简单来说:
就是把数据库表和实体类及实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表。
2.3 特点
-
简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
-
灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
-
解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
-
提供映射标签,支持对象与数据库的orm字段关系映射
-
提供对象关系映射标签,支持对象关系组建维护
-
提供xml标签,支持编写动态sql。
3. Mybatis 入门
3.1 mybatis 的环境搭建
-
创建 maven 工程并导入坐标
-
创建实体类和 dao 的接口
-
创建 Mybatis 的主配置文件
- SqlMapConfig.xml
- SqlMapConfig.xml
-
创建映射配置文件
- IUserDao.xml, 其中 select id 应该和接口中的方法一样,同时,给出结果类型,让mybatis 框架将查询出的结果,封装到 User 对象中,并将这些对象 封装到 List 对象中。
- IUserDao.xml, 其中 select id 应该和接口中的方法一样,同时,给出结果类型,让mybatis 框架将查询出的结果,封装到 User 对象中,并将这些对象 封装到 List 对象中。
3.2 环境搭建的注意事项
- 创建IUserDao.xml 和 IUserDao.java 时, 名称只是为了保持一致。在 Mybatis 中它把持久层的操作接口名称和映射文件也叫作:Mapper。所以:IUserDao 和 IUserMapper 是一样的。
- 在 idea 中创建目录的时候,它和包是不一样的。包在创建时,com.alibaba.a 他是三级结构。而目录创建时,com.alibaba.a 是一级目录。
- mybatis 的映射配置文件位置,必须和接口的包结构相同。
- 映射配置文件的 mapper 标签 namespace 属性的取值必须是 dao 接口的全限定类名。
- 映射配置文件的操作配置, id 属性的取值必须是 dao 接口的方法名。
当我们遵从了 3,4,5 点之后,我们在开发中就无需再写 dao 的实现类。
4.mybatis 的入门案例
4.1 入门案例的创建过程和代码
- 在之前环境搭建的例子上面,我们编写一个 log4j.properities 文件放在 resources 文件夹下:
- 接着,在 test 文件夹下创建测试包,使用 main 函数来测试我们的结果:
- 结果如下:
4.2 mybatis 入门案例的代码分析
4.2.1 mybatis 使用步骤:
-
第一步:读取配置文件
-
第二步:创建 SqlSessionFactory 工厂
-
第三部:创建 SqlSession
-
第四部:创建 Dao 接口的代理对象
-
第五步:执行 Dao 中的方法
-
第六步:释放资源
-
注意事项:千万不要忘记在配置文件中告知 Mybatis 要封装到哪个实体类中。
配置的方式:指定实体类的全限定类名。
4.2.2 mybatis 入门案例的分析
5. mybatis 注解开发入门案例和编写dao实现类的方式
5.1 mybatis 注解开发入门案例
如果使用注解进行开发,我们可以:
- 将 resources 文件下和包名对应位置的配置文件删除。圈画的有些歪,不需要删除SqlMappingConfig.xml
- 将对应接口的方法上标注上 @Select 注解并制定 SQL 语句
@Select(“select * from user”)
- 然后,由于使用注解来配置,此处应该使用class属性指定被注解的dao全限定类名,之前使用的 resources 属性名。
5.2 编写dao实现类的方式
明确:
首先,mybatis 是支持编写 dao 的实现类的。但是我们在实际的开发中,都是越简单越好,所以都是采用不写 dao 类的方式。不管是用 XML 还是注解配置。
步骤:
-
首先配置好 pom.xml、SQLMapperConfig.xml、IUserDao.xml、log4j.properties、User实体类等内容同 Mybatis 入门案例
-
接着创建好 IUserDao 接口。内容同入门案例。
-
然后写好 IUserDao 的实现类:
import com.itheima.dao.IUserDao; import com.itheima.domain.User; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; public class UserDaoImp implements IUserDao { private SqlSessionFactory factory; public UserDaoImp(SqlSessionFactory factory) { this.factory = factory; } public List<User> findAll() { // 1. 使用工厂创建SQLSession对象 SqlSession session = factory.openSession(); // 2. 使用Session执行查询方法 List<User> objects = session.selectList("com.itheima.dao.IUserDao.findAll"); // 3. 关闭 session.close(); return objects; } }
-
最后写好测试类,测试与mybatis 入门的测试类稍有不同:
import com.itheima.dao.IUserDao; import com.itheima.dao.impl.UserDaoImp; import com.itheima.domain.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; import java.util.List; /** * @author 黑马程序员 * @Company http://www.ithiema.com * mybatis的入门案例 */ public class MybatisTest { /** * 入门案例 * @param args */ public static void main(String[] args)throws Exception { //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工厂创建 dao 对象 IUserDao userDao = new UserDaoImp(factory); //4.使用代理对象执行方法 List<User> users = userDao.findAll(); for(User user : users){ System.out.println(user); } //5.释放资源 in.close(); } }
-
结果
2019-08-16 16:11:32,980 0 [ main] DEBUG ache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter. 2019-08-16 16:11:33,128 148 [ main] DEBUG source.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 2019-08-16 16:11:33,128 148 [ main] DEBUG source.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 2019-08-16 16:11:33,128 148 [ main] DEBUG source.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 2019-08-16 16:11:33,129 149 [ main] DEBUG source.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections. 2019-08-16 16:11:33,194 214 [ main] DEBUG ansaction.jdbc.JdbcTransaction - Opening JDBC Connection 2019-08-16 16:11:34,178 1198 [ main] DEBUG source.pooled.PooledDataSource - Created connection 1818544933. 2019-08-16 16:11:34,179 1199 [ main] DEBUG ansaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6c64cb25] 2019-08-16 16:11:34,181 1201 [ main] DEBUG m.itheima.dao.IUserDao.findAll - ==> Preparing: select * from user 2019-08-16 16:11:34,214 1234 [ main] DEBUG m.itheima.dao.IUserDao.findAll - ==> Parameters: 2019-08-16 16:11:34,261 1281 [ main] DEBUG m.itheima.dao.IUserDao.findAll - <== Total: 6 2019-08-16 16:11:34,263 1283 [ main] DEBUG ansaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6c64cb25] 2019-08-16 16:11:34,264 1284 [ main] DEBUG ansaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6c64cb25] 2019-08-16 16:11:34,264 1284 [ main] DEBUG source.pooled.PooledDataSource - Returned connection 1818544933 to pool. User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京'} User{id=42, username='小二王', birthday=Fri Mar 02 15:09:37 CST 2018, sex='女', address='北京金燕龙'} User{id=43, username='小二王', birthday=Sun Mar 04 11:34:34 CST 2018, sex='女', address='北京金燕龙'} User{id=45, username='传智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龙'} User{id=46, username='老王', birthday=Wed Mar 07 17:37:26 CST 2018, sex='男', address='北京'} User{id=48, username='小马宝莉', birthday=Thu Mar 08 11:44:00 CST 2018, sex='女', address='北京修正'}
需要注意的是:我们在实现类中,如果需要使用到我们配置文件中 IUserDao.xml中的 sql 语句,我们必须要指定该 sql 语句所在的位置,即:“com.itheima.dao.IUserDao.findAll” 这个与Dao接口相对应的配置文件中。