MyBatis框架及ORM
- MyBatis框架是一个数据库持久层框架。它内部封装了JDBC访问数据库的操作,支持普通的SQL操作,还有存储过程和高级映射,使用这个框架能大大减少不必要的一些JDBC代码和结果校验。简单一点来说,就是不要把SQL写在源代码中,把SQL语句抽取出来放在配置文件中,把SQL语句与代码分离。
- ORM:对象关系映射,就是在对象和关系型数据库直接建立对应关系,数据表对应一个类,每一条数据对应一个对象实例,表中字段对应类中属性。有了ORM我们就可以在操作数据库时采用面向对象的思路对数据进行增删改查。具体使用上是用XML还是注解看具体框架。
使用MyBatis
- 新建数据库mybatis,并建一张表user
CREATE DATABASE `mybatis`;
USER `mybatis`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`birthday` date DEFAULT NULL COMMENT '生日',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', '张三', '男', '2018-07-10', '北京');
INSERT INTO `user` VALUES ('2', '李四', '男', '2018-07-10', '上海');
INSERT INTO `user` VALUES ('3', '王五', '男', '2018-07-10', '广州');
INSERT INTO `user` VALUES ('4', '王六', '女', '2018-07-10', '深圳');
INSERT INTO `user` VALUES ('27', '刘备', '男', '2020-07-20', '大树刘桑');
INSERT INTO `user` VALUES ('29', '赵云', '男', '2020-07-20', '长板坡');
- 导入Maven依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
- 配置数据源:MyBatis是持久层框架,使用需要配置数据库的相关信息。在项目resource目录下新建配置文件MyBatis-config.xml和jdbc.properties
jdbc.properties中配置连接数据库的信息
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
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="jdbc.properties"></properties>
<settings>
<!--使用日志打印信息-->
<setting name="logImpl" value="LOG4J"></setting>
</settings>
<!--配置mybatis环境,可以配置多套不同的环境,如测试数据库,生产数据库,开发数据库,但会使用配置的默认数据库,这里配置了一个development数据库-->
<environments default="development">
<environment id="development">
<!--配置JDBC事务管理-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--配置映射文件所在包,mybatis会去这个地方找SQL映射包-->
<mappers>
<package name="gdut\iot\dao"></package>
</mappers>
</configuration>
- 创建持久层对象,用来与数据表映射
在java文件夹下新建User类
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
新建持久层接口
- 配置SQL映射:完成映射,创建名为UserMapper.xml,在resource中创建,记住这个包路径要跟上面配置的mapper路径一样。
<?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="gdut.iot.dao.UserMapper">
<select id="count" resultType="int">
select count(1) as count from user
</select>
</mapper>
其中namespace用来区分不同mapper,全局唯一,select标签的id要跟接口提供方法一样
- 测试
@Test
public void test1() throws IOException {
// 读取数据源配置文件
InputStream inputStream = Resources.getResourceAsStream("MyBatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlsession对象
SqlSession sqlsession = factory.openSession();
int count = sqlsession.getMapper(UserMapper.class).count();
System.out.println(count);
sqlsession.close();
- 打印结果
MyBatis核心对象
- 使用MyBatis时,每个应用都把SqlSessionFactory对象为核心。
- 而这需要先获取SqlSessionFactoryBuilder对象,这个需要提供一个全局配置文件XML或配置类
- 然后获取SqlSessionFactory对象,这个对象可以用来获取SqlSession对象,该对象中完全包含了以数据库为背景的所有执行SQL的方法。用这个实例来直接执行已映射的SQL元素。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder可以通过调用以下方法来获取SqlSessionFactory对象
打开这些方法可以看到,这些方法调用的是同一个签名方法,其中environment和properties是可以为null的,那么方法应该有以下几种重载
build(InputStream inputStream,String environment,Properties properties)
build(Reader reader,String environment,Properties properties)
build(InputStream inputStream,String environment,Properties)
build(Configuration config)
可以看出传进去配置信息有三种方式,字符流,字节流,类,字节流和字符流都属于读配置文件的方式,我们可以采用读xml和配置类的方式来构造SqlSessionFactory。
SqlSessionFactoryBuilder生命周期
- SqlSessionFactoryBuilder的特点是用过即丢,所以该对象最佳使用范围是方法体内做局部变量。
SqlSessionFactory
- SqlSessionFactory就是创建SqlSession实例的工厂,是mybatis应用的核心
2. openSession的参数为boolean时,传入true表示关闭事务控制,默认为true
生命周期和作用域
- SqlSessionFactory在应用整个运行过程中都存在,不要去销毁或再创建它,作用域是整个应用,建议单例使用,在spring集成时默认使用单例。
SqlSession的作用
SqlSession是用于执行持久化操作的对象,类似于JDBC中的Connection,提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句。
SqlSession的生命周期和作用域
- SqlSession对应于一次数据库会话,由于数据库会话不是永久的,SqlSession的生命周期不是永久的,被关闭后就需要重新创建。
- SqlSession实例不能被线程共享,也不是线程安全的。因此最佳的作用域范围是request。