一、MyBatis的介绍
1.1 回顾一下JDBC
下面这个代码是使用JDBC实现基于id查询员工信息,我们来分析分析有什么弊端。
public Employee selectById(Long id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
ps = conn.prepareStatement("select * from employee where id = ?");
ps.setLong(1,id);
rs = ps.executeQuery();
if (rs.next()){
Employee employee = new Employee();
employee.setId(rs.getLong("id"));
employee.setName(rs.getString("name"));
employee.setAge(rs.getInt("age"));
employee.setSex(rs.getInt("sex"));
employee.setPhone(rs.getString("phone"));
employee.setAddress(rs.getString("address"));
employee.setCreatedate(rs.getTimestamp("createdate"));
return employee;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(conn,ps,rs);
}
return null;
}
弊端如下:
1、SQL代码耦合在Java代码中。
2、SQL中的参数需要自己手动设置,获得结果集后需要自己进行结果的封装。
3、每次需要自己获取连接,用完以后关闭连接。(需要Spring帮助解决)
而这些问题,都可以使用mybatis框架来解决。
2.1 MyBatis的介绍
MyBatis官网英文版:https://mybatis.org/mybatis-3
MyBatis官网中文版:https://mybatis.org/mybatis-3/zh/index.html
MyBatis整合Spring:http://mybatis.org/spring/zh/index.html
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 MyBatis底层封装了JDBC。
同时MyBatis也是一款半ORM映射的框架。
2.2 ORM介绍
ORM 是 Object Relational Mapping 的缩写,译为“对象关系映射”,它解决了对象和关系型数据库之间的数据交互问题。
在操作数据库的过程中,我们一般会为表创建一个与之对应的实体类,该类中的属性和表中的字段对应。查询一行记录时会转换为一个对象,查询多条记录时会转换为List集合。就如下图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/c0d92d26e4b643c09bdf7618c9215ff9.png)
按照传统思路,比如在JDBC中,我们就得手动编写 SQL 语句,并且传递参数和结果集的封装都需要自己手动完成,而有了ORM,编程人员只要提前配置好对象和数据库表之间的映射关系,ORM 就可以自动生成 SQL 语句,并将对象中的数据自动存储到数据库中,查询的结果集也会自动封装为对象返回,无需我们进行相关的操作。
早先的Hibernate框架就是一种全自动的 ORM 框架。他能做到一行SQL都不用我们写,仅需进行表和对象关系的配置,就可以完成数据库操作。如下图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/d8aafc4c8c3541a291b54fb4fa1daa79.png)
而MyBatis是一个半ORM框架,因为SQL需要我们自己写。
二、MyBatis基础入门
提前准备数据库表
库名:mytest
表名:user
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`password` varchar(100) DEFAULT NULL,
`username` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
2.1 导入依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
2.2 创建SqlSessionFactory
咱们使用从 XML 中构建 SqlSessionFactory对象的方式。
① 准备配置文件:在resources
目录中新建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:MyBatis可以配置多种连接环境(开发,测试,线上)
default属性关联具体配置的id-->
<environments default="development">
<!--具体的环境配置,id必须唯一 -->
<environment id="development">
<!--配置事务管理器,MyBatis中有两种类型的事务管理器:JDBC和MANAGED
JDBC: 使用了JDBC的提交和回滚功能
MANAGED:不使用事务
-->
<transactionManager type="JDBC"/>
<!--数据源相关配置
type="POOLED" 使用mybatis自己带连接池
type="UNPOOLED" 不使用连接池,每次都新建连接,用完关闭连接
type="JNDI" 采用服务器提供的JNDI技术实现,获取DataSource
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mytest?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
② 读取配置文件,创建SqlSessionFactory
对象
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建Sql会话工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
③ 还可以将数据库连接参数(driver,url,username,password)抽离出去,职责单一化。
在resources
目录中新建db.propertis
内容如下:
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username=root
password=123456
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>
<!--引入配置文件-->
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--使用: ${key}的方式取值即可-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>
2.3 获取SqlSession并执行SQL
① 创建User实体类
package cn.mybatis.domain;
public class User {
private Integer id;
private String password;
private String username;
//省略 get set toString
}
② 编写映射文件Mapper.xml,将SQL语句抽离到映射文件中。
在resources
目录新建mapper
目录,在其中创建UserMapper.xml
即:resources/mapper/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">
<!-- namespace:命名空间,可以任意取名,但必须唯一 -->
<mapper namespace="cn.mybatis.mapper.UserMapper">
<!-- id:用于区分sql,在当前命名空间下必须唯一,与命名空间配合定位sql。语法:命名空间.id
parameterType:参数类型
resultType:返回值类型
-->
<select id="selectById" parameterType="int" resultType="cn.mybatis.domain.User">
select * from user where id = #{id}
</select>
</mapper>
<!--
说明:
#{id} 是参数的占位符,调用时会替换为真实的id值。
-->
③ 加载UserMapper.xml
文件
在 mybatis-config.xml
中添加配置,加载mapper映射文件
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
④ 使用SqlSession执行sql
//1.读取mybatis配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建sql会话工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建sql会话对象
SqlSession session = sqlSessionFactory.openSession();
//4.执行sql
// 参数1:定位sql,命名空间.id
// 参数2:执行sql时的参数
User user = session.selectOne("cn.mybatis.mapper.UserMapper.selectById", 1);
System.out.println(user);
//5.关闭会话
session.close();
三、MyBatis实现CRUD
3.1 新增User
① 映射文件编写sql
<?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="cn.mybatis.mapper.UserMapper">
<insert id="insert" parameterType="cn.mybatis.pojo.User">
insert into user(username,password) values(#{username},#{password})
</insert>
</mapper>
② 执行sql
//1.读取mybatis配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建sql会话工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//3.创建sql会话对象
SqlSession session = sqlSessionFactory.openSession();
//4.执行sql
User user = new User();
user.setUsername("张三");
user.setPassword("123456");
// 参数1:定位sql,命名空间.id
// 参数2:执行sql时的参数
session.insert("cn.mybatis.mapper.UserMapper.insert",user);
//5.提交事务(mybatis需要手动提交事务)
session.commit();
//6.关闭会话
session.close();
3.2 修改User
① 映射文件编写sql
<?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="cn.mybatis.mapper.UserMapper">
<update id="update" parameterType="cn.mybatis.domain.User">
update user set username=#{username},password=${password} where id = #{id}
</update>
</mapper>
<!--
说明:
#{username}等占位符,取值时调用的是对象相应的get方法,#{username}就是调用getUsername()
-->
② 执行sql
//1.读取mybatis配置文件
InputStream in = Resources