MyBatis
是一个半ORM的数据库持久化框架,底层还是JDBC,所以单用Mybatis时,事务需要手动提交
历史扩展:它本是apache的一个开源项目iBatis,所以很多jar的名字还是iBatis
ORM:对象关系映射(Object Relational Mapping),一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术;
操作数据库关系方式有很多种,常用的是这两种:
1、半映射:把SQL写在配置文件中,通过不同SQL中完成对象实体和数据库关系相互转换的操作,如Mybatis
2、完整映射:直接使用对象实体和数据库关系进行映射,不用写SQL(简单的操作),由框架自己生成,如JPA、Hibenate
(P.S:就是需要写sql的就是半映射,不需要的就是完整映射,但是完整映射的sql也只是简单级别的,复杂度高的还是要自己写 )
=============================================================
1、核心配置文件:MyBatis-Config.xml,放在Source Folder下(这种文件夹下的文件,项目启动后会自动去读取)
<configuration>
<!-- 引入配置文件信息,这里不能加classpath:。
resource:引入类路径下的资源,即classpath,所以不需要写classpath:
url:引入网络路径或磁盘路径下的资源
-->
<properties resource="db.properties"></properties>
<!-- 环境们 (很多环境的意思,就是可以配置很多个数据库连接)
default:默认使用哪一个环境(必须对应一个环境的id)
-->
<environments default="development">
<!-- 一个环境 id:为这个环境取唯一一个id名称 -->
<environment id="development">
<!-- 事务管理 type:JDBC(支持事务)/MANAGED(什么都不做) -->
<transactionManager type="JDBC" />
<!-- 数据源, 连接池 type(POOLED):MyBatis自带的连接池 -->
<dataSource type="POOLED">
<!-- 连接数据库的参数:使用属性文件的方式 -->
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" /> <!-- 加前缀,是因为电脑环境中可能会有username,比如电脑的账户名-->
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="cn/itsource/domain/ProductMapper.xml" />
</mappers>
</configuration>
2、映射文件:关于配置文件,都放在resource文件下,包和java的要相同,这样在硬盘中是在同一目录下的
<?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的主要功能就是写sql
mapper:根
namespace:命令空间 (用来确定唯一)以前这个是可以不加的,现在必需加,xml之间通过这个来执行相互之间的方法,不是去接口里
namespace的值:接口的完全限定名
-->
<mapper namespace="cn.itsource.dao.IProductDao">
<!--
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace + id
例: cn.itsource.mybatis.day1._1_hello.IProductDao.findById
parameterType : 传入的参数类型,只有一个的时候最好不写,因为不写一定不会错,写了反而可能会错
resultType : 结果类型(第一条数据返回的对象类型)自己的对象一定是完全限定类名,
如果查询记录是多条,接口中方法的返回值是集合,但是返回类型还是写对象,而不是集合,因为myBatis会帮我们将多条数据放入集合中
#{}:底层调get方法,当传入参数只有一个时,里面写啥都可以,并不需要和参数名相同
-->
<select id="findById" parameterType="long" resultType="cn.itsource.domain.Product">
select * from product where id = #{id}
</select>
</mapper>
3、抽取工具
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession opSession() {
if (sqlSessionFactory != null) {
return sqlSessionFactory.openSession();
}
return null;
}
}
4、测试:执行xml中的sql语句
4.1、传统方式:
@Test
public void testFindAll() throws Exception{
//获取到会话对象
SqlSession session = MybatisUtils.opSession();
//通过命名空间+id,调用sql
Product product = session.findById(“cn.itsource.dao.IProductDao”,1L);
}
4.2、映射器Mapper
创建条件:
(1)Mapper映射文件(.xml)的命名空间,必须和接口的"完全限定名"一致;
(2)定义sql标签的id,需要和"接口的方法名"一致;
@Test
public void testFindAll() throws Exception{
//获取到会话对象
SqlSession session = MybatisUtils.opSession();
//拿到映射对象,是通过mybatis自动创建的指定接口代理对象
ProductMapper mapper = session.getMapper(ProductMapper.class);
List<Product> products = mapper.findById(1L);
//如果是增删改操作,事务需要手动提交
//session.commit()
//lambda表达式
products.forEach(System.out::println);
}