Mybatis
从概念原理到源码分析,Mybatis是一款优秀的基于ORM的半自动轻量级的持久层框架,它支持sql定制化,存储过程,以及高级映射。
Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。可以使用简单的XML或者注解来配置和映射原生类型,接口和Java的POJO(Plain Old Java Object即普通老式Java对象)为数据库中的记录。
对象/关系数据库映射(ORM)
ORM全称Object/Relation Mapping:表示对象-关系映射的缩写
ORM完成面向对象的编程语言到关系数据库的映射。当ORM框架完成映射后,程序员既可以利用面向对象程序设计语言的简单易用性,又可以利用关系数据库的技术优势。ORM把关系数据库包装成面向对象的模型。ORM框架是面向对象设计语言与关系数据库发展不同步时的中间解决方案。采用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的放松来操作持久化对象,而ORM框架则将这些面向对象的操作转换成底层SQL操作。ORM框架实现的效果:把对持久化对象的保存、修改、删除 等操作,转换为对数据库的操作
Mybatis简介
MyBatis是一款优秀的基于ORM的半自动轻量级持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO (Plain Old Java Objects,普通老式Java对 象)为数据库中的记录。
自动
自动分为半自动和全自动,其中Mybatis属于半自动框架,而同为持久层框架的Habernate属于全自动框架,这里Mybatis的优势就是更加高效,而高效主要体现在全自动框架中没法进行手动的sql优化
量级
量级分为重量级和轻量级框架,顾名思义重量级框架所依赖的环境相比轻量级框架要大,启动过程所需要的资源要相对多很多。
像Mybatis,Spring等就是轻量级框架,而像老式的EJB就属于重量级框架。
Mybatis对JDBC的优化
- 解决规避了JDBC频繁创建数据库连接的问题
- 解决硬编码问题
- 手动封装返回结果集等
Mybatis的历史
首先Mybatis的前身是由Apache公司的一个开源项目iBatis,2010年6月由ApacheSoftware Foundtion迁移到Google Code,随着开发团队转投Google Code旗下更名为Mybatis。代码与2013年11月迁到GitHub。
iBatis->internet和abatis的组合,是基于Java的持久层框架。
Mybatis的优势
核心sql需要自己进行优化,sql和java代码分开,功能边界清晰,一个专注业务,一个专注数据。
分析图示如下:
使用Mybatis开发步骤
入门案例CRUD
1. 添加Mybatis
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!--引入依赖-->
<dependencies>
<!--mybatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<!--单元测试坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2. 创建数据表
3. 编写表对应实体类
public class User {
private Integer id;
private String username;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
4. 编写映射文件…Mapper.xml
mapper.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">
编写UserMapper.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.lagou.dao.IUserDao">
<!--namespace : 名称空间:与id组成sql的唯一标识
resultType: 表明返回值类型-->
<!--查询用户-->
<select id="findAll" resultType="uSeR">
<include refid="selectUser"></include>
</select>
<!--添加用户-->
<!--parameterType:参数类型-->
<insert id="saveUser" parameterType="user" >
insert into user values(#{id},#{username})
</insert>
<!--修改-->
<update id="updateUser" parameterType="user">
update user set username = #{username} where id = #{id}
</update>
<!--删除-->
<delete id="deleteUser" parameterType="int">
delete from user where id = #{abc}
</delete>
</mapper>
5. 编写核心文件sqlMapConf.xml
核心配置文件不一定取名为sqlMapConf.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">
编写sqlMapConfig.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>
<!--加载外部的properties文件-->
<properties resource="jdbc.properties"></properties>
<!--给实体类的全限定类名给别名-->
<!--<typeAliases>-->
<!--给单独的实体起别名-->
<!-- <typeAlias type="com.lagou.pojo.User" alias="user"></typeAlias>-->
<!--批量起别名:该包下所有的类的本身的类名:别名还不区分大小写-->
<!-- <package name="com.lagou.pojo"/>
</typeAliases>-->
<!--environments:运行环境-->
<environments default="development">
<environment id="development">
<!--当前事务交由JDBC进行管理-->
<transactionManager type="JDBC"></transactionManager>
<!--当前使用mybatis提供的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--引入映射配置文件-->
<mappers>
<mapper resource="UserMapper.xml"></mapper>
</mappers>
</configuration>
environments里边可以配置多个运行环境environment,比如开发、测试、生产等多规格环境,其中environments中的default属性标识默认的运行环境,而在上面代码中的transactionManager属于设置事务管理类别,这里是当前事务交由JDBC进行管理,dataSource标签中的type标识链接池类型,POOLED表示使用当前mybatis提供的连接池,UNPOOLED表示不使用连接池。
6. 编写测试类
在Mybatis的测试类中需要:
1. 加载核心配置文件
2. 获取sqlSession工厂对象
3. 获取sqlSession对象
4. 执行sql语句
5. 打印结果
6. 释放资源
具体代码如下:
public class MybatisTest {
@Test
public void test1() throws IOException {
//1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2.解析了配置文件,并创建了sqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.生产sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();// 默认开启一个事务,但是该事务不会自动提交
//在进行增删改操作时,要手动提交事务
//4.sqlSession调用方法:查询所有selectList 查询单个:selectOne 添加:insert 修改:update 删除:delete
List<User> users = sqlSession.selectList("user.findAll");
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void test2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//事务自动提交
User user = new User();
user.setId(6);
user.setUsername("tom");
sqlSession.insert("user.saveUser",user);
sqlSession.close();
}
@Test
public void test3() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(4);
user.setUsername("lucy");
sqlSession.update("user.updateUser",user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test4() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("com.lagou.dao.IUserDao.deleteUser",6);
sqlSession.commit();
sqlSession.close();
}
}