一、首先让我们需要清楚原始JDBC存在哪些问题:
1、数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。如果使用数据库连接池可解决此问题。
2、Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。
3、使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成POJO对象解析比较方便。
二、Mybatis架构:
关于Mybatis中,SqlMapConfig.xml是一个全局的配置,它的下面有很多的Mapper.xml,我们需要配置完Mapper.xml之后,配置加载到SqlMapConfig.xml中,之后能够根据配置生成SqlSessionFactory会话工厂,由会话工厂可以创建会话SqlSession,在会话下面有executor执行器(基本执行器和缓冲执行器),执行器下面有mappedStatement,它是用来接收输入参数的映射的,然后执行器根据输入的java对象映射到SQL中,关于输出参数的时候,是在执行完SQL之后将输出结果映射到java对象中;
在了解到Mybatis的整体的架构之后,下面让我们来搭建一个简单的项目
首先,官网上下载Mybatis:
解压之后:
我们在Eclipse中new一个工程,命名为MybatisDemo,在lib下导入jar包:
接下来我们创建一个数据库Mybatis,创建两个表User和orders:
根据数据库中各个属性书写User.java和Order.java并利用IDE生成get和set方法;
在src下面创建SqlMapConfig.xml:用于全局配置
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> |
在src下面创建log4j.properties;用于打印日志;
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n |
在src下面建立一个com.xmlfolder包,里面放入UserMapper.xml,配置完成后将其引入到SqlMapConfig.xml下;
写一个简单的功能,根据用户ID查询用户的信息:
关于UserMaper.xml中的配置如下:
根据用户名进行模糊查询:使用like以及连接符;
关于占位符和连接符:
插入数据:
更新数据:
根据用户ID删除数据:
关于Mybatis解决JDBC的问题如下:
Mybatis和Hibernate的不同:
Mybatis不完全是一个ORM框架,因为Mybatis需要自己编写SQL语句,Mybatis可以通过xml或者注解的方式灵活使用SQL语句,并将java对象和SQL语句映射生成最终的SQL语句,最后将SQL执行的结果再映射生成java对象;Mybatis更容易学习,支持程序员书写原生SQL,灵活性比较好,适合对关系数据模型要求不高的软件开发,Mybatis无法做到数据库无关性;
Hibernate对象/关系映射能力强,数据无关性比较好,对于关系模型要求比较高的软件,如果使用hibernate开发可以节省更多的代码,提高效率;但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好;
使用Mybatis开发Dao,通常有两个方法,原始Dao开发和Mapper动态代理开发方法;
原始开发Dao;定义一个接口UserDao,如下:
书写接口的实现方法
注入到service层中:(用一个简单的Junit代替)
Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。
SQLSession的使用范围:
SQLSession中封装了对数据库的操作,如增删改查;
SQLSession是通过SQLSessionFactory来创建的;
SQLSessionFactory是通过SqlSessionFactoryBuilder创建的;
SqlSessionFactoryBuilder用于创建一个SQLSessionFactory,SQLSessionFactory一旦创建就不需要SqlSessionFactoryBuilder了,因为SQLsession是通过SQLSessionFactory创建的,因此可以把SqlSessionFactoryBuilder当成一个工具类进行使用,最佳使用范围即方法体内使用局部变量;
Mapper动态代理方式:遵守四个原则
当在定义接口的过程中满足上面的四个要求(namespace的名称和接口绑定,id名称等于方法名称,入参类型以及出参类型和Xml中保持一致的时候),Mapper的动态代理就会自动生成代理对象,不需要在去new实现类;
SqlMapConfig.xml配置文件中,两个常见属性:properties和typeAliases
mappers(映射器):