1.什么是mybatis
Mybatis是持久层的框架;Mybatis免除了几乎所有的jdbc代码以及设置参数和获取结果集的工作(封装了preparedStatement resultSet等代码);Mybatis通过xml配置文件(用于获取SqlSessionFactory对象)或者注解和映射文件(类似接口的实现类)以及相应的接口类实现了数据库的CRUD操作。
1.1什么是持久化
持久化即将数据从瞬时状态转化为永久状态。一方面由于内存价格高昂,另一方面由于内存有断电即丢失的缺陷,数据一般不会保存在内存里而是存放在数据库里实现数据的永久保存。
2.案例解析
2.1核心配置文件解析
<?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为环境设置,环境也可以设置为<environment id="test"> 一个SqlSessionFactory只可以有一个环境,通过default属性选择程序环境-->
<environments default="development">
<environment id="development">
<!--这里是事务管理器,类型除了JDBC还可以是MANAGED-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--这里为数据源配置,类型可以是连接池POOLED (有连接池可以避免频繁的连接对象的创建和销毁) 也可以是无连接池UNPOOLED、JNDI-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/xxx?useSSL=true&useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="xxx"/>
<property name="password" value="xxx"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper.xml都需要在核心配置文件中注册,有三种方式:resource class package-->
<mappers>
<mapper resource="com/kuang/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>
2.2通过创建工具类获取SqlSession对象
public class MybatisUtils {
static InputStream inputStream;
static SqlSessionFactory sqlSessionFactory;
//使用mybatis的第一步:获取sqlSessionFactory对象
static {
try {
String resource = "mybatis-config.xml";
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取sqlSesssion对象
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
2.3创建pojo类User
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
2.4创建接口类
public interface UserDao {
List<User> selectAll();
}
2.5创建映射文件
<?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.kuang.dao.UserDao">
<select id="selectAll" resultType="com.kuang.pojo.User">
select * from user
</select>
</mapper>
2.6创建测试类
public class UserDaoTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
/*这里可以直接使用sqlSession对象执行相应的数据库操作方法,但是一般不建议这么使用,推荐使用通过getMapper方法获取接口引用对象映射SQL语句;这里类似于使用接口的引用对象指向实现接口的类对象*/
List<User> users = mapper.selectAll();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
}
3.配置解析
3.1核心配置文件
configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
3.2环境配置
上述案例中已描述
3.3属性Properties
properties属性可以通过引入外部配置文件到核心配置文件中,也可以直接设置。
- 方式一:通过外部引入配置文件(可以灵活修改属性值)
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/xxx?useSSL=true&useUnicode=true&characterEncoding=utf-8
username=xxx
password=xxx
核心配置文件
<properties resource="db.properties"> //这里是外部文件路径
<property name="username" value="xxx"/>
<property name="password" value="xxx"/>
<!- 当这里的属性和外部配置文件的属性同名时,优先级是外部配置文件高于此处;如果这里的属性在外部文件中没有,那么会形成互补-->
</properties>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<!- 通过如此可以减低程序的耦合性-->
</dataSource>
- 方式二:直接在核心配置文件里设置属性
<environment id="test"> //开发环境,也可以设置测试环境
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/xxx?useSSL=true&useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="xxx"/>
<property name="password" value="xxx"/>
</dataSource>
</environment>
3.4类型别名typeAliases
通过别名的设置可以减少代码的容易(要不然就需要写类的全限定类名)
方式一:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
这种方式可以对每一个类自定义别名
方式二:
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
这种方式不可以自定义别名,别名只可以是首字母小写的类名;如果需要自定义别名,可以通过在实体类上添加注解的方式设置。
3.5生命周期和作用域
变量的生命周期和作用域涉及到并发问题,因此需要重视。
-
SqlSessionFactoryBuilder 局部变量,创建完SqlSessionFactory就不需要了
-
SqlSessionFactory 程序运行期间一直存在,类似连接池的存在
-
SqlSession 每个线程都有一个SqlSession,SqlSession实例是不安全的,因此不能作为共享变量,在响应请求之后需要关闭