1.什么是MyBatis
MyBatis 是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,它消除了几乎所有的JDBC 代码和参数的手动设置以及对结果集的检索,并使用简单的XML 或注解进行配置和原始映射,用以将接口和Java的POJO(Plain Old Java Object,普通Java 对象)映射成数据库中的记录,使得Java开发人员可以使用面向对象的编程思想来操作数据库。
归纳总结一下
- MyBatis是一个持久层框架
- 支持普通SQL查询,存储过程,还有ORM
- ORM=>app不用再直接访问数据库,而是以面向对象的方式来操作持久化对象PO(Persisten Object),ORM框架会通过映射关系将这些操作转化为SQL操作
- 支持普通SQL查询=>可以优化SQL
- 支持存储过程=>同样可以优化SQL性能
- 消除了繁琐的JDBC操作和配置
2.怎么使用MyBatis
- 在pom.xml引入mybatis依赖
- (在mysql建个表,插入些数据,等等用)
CREATE TABLE users( id int(32) PRIMARY KEY AUTO_INCREMENT, username varchar(50), job varchar(50), phone varchar(16) ); INSERT INTO users VALUES(1,'f','b','110'); INSERT INTO users VALUES(2,'fo','ba',120); INSERT INTO users VALUES(3,'foo','bar',119);
- 在classpath下配置log4j.properties配置文件<=MyBatis使用log4j输出日志信息
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration log4j.logger.com.ssm=DEBUG 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
- 写个持久化类/POJO(属性字段与数据库中的表字段对应)
- 创建UserMapper映射文件
<?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="tech.rpish.mapper.UserMapper">
<select id="findUserById" parameterType="Integer" resultType="tech.rpish.po.User">
select * from users where id=#{id} </select>
</mapper>
- 创建MyBatis核心配置文件mybatis-config.xml
<?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>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/spring_db" />
<property name="username" value="root" />
<property name="password" value="pass" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="tech.rpish.mapper.UserMapper.xml"/>
</mappers>
</configuration>
- 编写测试类
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 tech.rpish.po.User;
import java.io.InputStream;
public class MyBatisTest {
@Test
public void findUserByIdTest() throws Exception {
// 读配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 根据配置文件构建SqlSessionFactory Instance
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 公共SqlSessionFactory创建SqlSession Instance
SqlSession sqlSession = sqlSessionFactory.openSession();
// sqlSession执行映射文件中定义的sql,并返回结果
User user = sqlSession.selectOne("tech.rpish.mapper.UserMapper.findUserById", 1);
// 输出结果
System.out.println(user);
// 关闭sqlSession
sqlSession.close();
}
}
调试运行,就能查询到结果了.
-
注意目录结构
这边需要注意的是目录结构
在IDEA中,UserMapper.xml必须放到resources目录下,否则无法加载资源
我尝试按照网上的教程修改pom.xml,手动添加build资源和很多其他方法都无济于事
所以这边特地指出来,给大家避个坑
然后记得要修改mybatis配置文件中mapper的资源路径
Okay,这就是大致的一个过程,然后上面这是findUserById的Demo,那大家可以仿照着写下findAllUsers,addUser,deleteUser,updateUser
(只要修改mapper.xml,然后写测试类就可以了)
然后,如果遇到卡壳,可以参考下我发到github的demo
3.MyBatis核心配置
3.1 MyBatis核心对象
- SqlSessionFactory
- SqlSessionFactory是单个数据库映射关系经过编译后的内存镜像,用于创建 SqlSession.
- SqlSessionFactory对象的实例通过 SqlSessionFactoryBuilder 对象来构建,通过 XML配置文件或一个预先定义好的Configuration 实例构建出 SqlSessionFactory 的实例
- 通过 XML 配置文件构建出SqlSessionFactory demo
InputStream inputStream = Resources.getResourceAsStream("ConfigurationFile"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)
- SqlSessionFactory 对象是线程安全的,一旦被创建,在整个应用执行期间都会存在
- 如果多次创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽=>在构建SqlsessionFactory 实例时,建议使用单例模式
- SqlSession
- SqlSession 是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作
- SqiSession对象包含数据库中所有执行SQL操作的方法,底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句
- SqlSession实例是不能被共享的,也是线程不安全的,因此其使用范围最好限定在一次请求或一个方法中,绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围中使用=>使用完SqlSession对象之后,要及时将它关闭,通常可以将其放在finally块中关闭
- 常用方法:
- selectOne,selectList,select,insert,update,delete,commit,rollback,close,getMapper,getConnection
- For More:SqlSession (mybatis 3.5.7 API)
3.2 MyBatis配置文件
- 配置文件-结构
<configuration xmlns="http://mybatis.org/schema/mybatis-config">
<!-- 属性-->
<properties></properties>
<!-- 设置-->
<settings></settings>
<!-- 类型命名-->
<typeAliases></typeAliases>
<!-- 类型处理器-->
<typeHandlers></typeHandlers>
<!-- 对象工厂-->
<objectFactory type=""></objectFactory>
<!-- 插件-->
<plugins></plugins>
<!-- 配置环境(事务管理器,数据源)-->
<environments default="">
<environment id="">
<transactionManager type=""></transactionManager>
<dataSource type=""></dataSource>
</environment>
</environments>
<!-- 数据库厂商标识符-->
<databaseIdProvider type=""></databaseIdProvider>
<!-- 映射器-->
<mappers></mappers>
</configuration>
- 配置文件-主要元素
- <properties>:通过外部配置资源,动态替换内部定义的属性
- <settings>:改变mybatis运行时的行为(开启cache,lazyloading)
- <typeAliases>:为配置文件中的po类型设置一个别名=>可开启自动扫包,会自动给它们定义别名(首字母小写的非限定类名)
- <typeHandler>:对mybatis的prepared statement的参数和结果集进行java type和jdbc type之间的转换
- <objectFactory>:实例化目标类,通常用来实例化mybatis的结果对象
- <plugins>:配置用户所开发的插件=>在已映射语句执行过程中的某一点进行拦截调用
- <environments>:配置环境=>主要是数据源和事务管理器
- <mappers>:指定mybatis配置文件位置
- 类路径
<mapper resource="tech/rpish/mapper/Mapper.xml" />
- 本地文件路径
<mapper url=file:///C:/SSM-bootstrap/mapper/Mapper.xml />
- 接口类
<mapper class="tech.rpish.mapper.Mapper" />
- 包名
<package name"tech.rpish.mapper" />
- 类路径
3.3 MyBatis Mapper配置
- <select>
- <insert>
- <update>
- <delete>
- <sql>:sql代码片段,可在其他语句include复用
- <resultMap>:结果映射集,定义映射规则,级联更新,类型转化器
4.动态SQL
mybatis的动态sql就是对sql语句动态组装的功能.
通过使用OGNL Expression+tags 对sql语句进行逻辑判断,代替开发人员手动拼接sql语句.
大致有如下几类:
- <if>:单条件分支判断
- <chose>(<when>,<otherwise>):多条件分支判断
- <where>,<trim>:辅助元素,用于处理sql拼装,特殊字符处理
- <set>:和if配合,实现对一个对象特定字段的更新,代替update对所有字段的更新
- <foreach>:循环语句,常和in联用
- <bind>:从OGNL express创建一个变量,绑定到上下文(常用于模糊查询的sql中)=>不考虑数据库进行字符串拼接
具体demo,详见:Commit:MyBatis-2 动态SQL · rpishgithub/SSM-bootstrap@d314427
4.关联映射
我们常用的查询不可能总像getUsernameById这么简单,时常要处理复杂类型和多张表多个对象间的复杂的关系.
这时候就要用到mybatis的关联映射来处理对象间的一对一,一对多,多对多关联关系了.
mybatis有两种加载关联关系的方式:
- 嵌套查询:在查询的resultMap中嵌套一个子查询
- 嵌套结果:在查询的resultMap中对子集进行解析
一对一关系通常在resultMap中添加association嵌套查询或嵌套结果
一对多和多对多则是利用resultMap中的collection,它的大部分属性association相同,不同的是它的ofType属性,它与javaType属性对应,用于指定实体对象中集合类属性所包含的元素类型.
具体使用,详见:
然后提一下注意事项
- 写完mapper记得在mybatis配置文件中注册mapper
- 记得检查mapper的拼写
6.mybatis和spring的整合
- 传统DAO方式
- 通过 DAO实现类 实现对应DAO接口定义的方法,同时extend SqlSessionDaoSupport,通过getSqlSession()方法获取spring注入的sqlSessionFactory获取session,调用mapper定义的查询 (详见SSM-bootstrap/MyBatis-04)
- 缺点:实现类会出现大量重复代码;需要指定映射文件中执行语句的id(运行才能知道正确性)
- Mapper接口方式
- 基于mapperFactoryBean的整合
- 编辑
mapper.xml
namespace同名的mapper接口,声明一方法与查询名参数返回类型对应 - 在spring配置文件创建mapperFactoryBean类型的bean/mapper代理(注入上述mapper interface 和 sqlSessionFactory)
- 编写测试类,通过Mapper取代Dao接口实例调用查询方法
- 编辑
- 基于mapperScannerConfiguration的整合
- 像上面这样每个mapper都要写个bean注册还是很麻烦,特别是Dao层有很多接口时,这时候就得用MapperScannerConfigurer类,来自动扫描接口,为它们创建对应mapper的bean
- 只需要在spring配置文件中配置mapperScannerConfigurer bean,再指定basePackage (详见:SSM-bootstrap/MyBatis-04)
- 基于mapperFactoryBean的整合
7.更多内容
这上边只是我看书上讲mybatis做的笔记,更多具体内容还得看官方文档.
mybatis – MyBatis 3 | 简介
然后,肯定会接触到一些sql语句,这部分可以看菜鸟教程
MySQL 教程 | 菜鸟教程 (runoob.com)