MyBatis是一款基于ORM的持久层框架。
快速上手使用的方法
案例: 通过mybatis查询数据库user表的所有记录,封装到User对象中,打印到控制台上
步骤:
- 创建数据库及user表
- 创建maven工程,导入依赖(MySQL驱动、mybatis、junit)
- 编写User实体类
- 编写UserMapper.xml映射配置文件(ORM思想)
- 编写SqlMapConfig.xml核心配置文件
数据库环境配置
映射关系配置的引入(引入映射配置文件的路径) - 编写测试代码
// 1.加载核心配置文件
// 2.获取sqlSessionFactory工厂对象
// 3.获取sqlSession会话对象
// 4.执行sql
// 5.打印结果
// 6.释放资源
创建表
CREATE DATABASE `mybatis_db`;
USE `mybatis_db`;
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime default NULL COMMENT '生日',
`sex` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- insert....
insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'张三','2020-11-11 00:00:00','男','北京海淀'),(2,'李四','2020-12-12 00:00:00','男','北京海淀');
导入依赖(MyBatis相关的)
<!--指定编码和版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.11</java.version>
<maven.compiler.source>1.11</maven.compiler.source>
<maven.compiler.target>1.11</maven.compiler.target>
</properties>
<!--mybatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</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>
<scope>test</scope>
</dependency>
编写实体类
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// getter/setter 略
}
编写UserMapper映射文件
<?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="UserMapper">
<!--查询所有-->
<select id="findAll" resultType="com.lagou.domain.User">
select * from user
</select>
</mapper>
编写MyBatis核心文件
<?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 default="mysql">
<!--使用MySQL环境-->
<environment id="mysql">
<!--使用JDBC类型事务管理器-->
<transactionManager type="JDBC"></transactionManager>
<!--使用连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver">
</property>
<property name="url" value="jdbc:mysql:///mybatis_db">
</property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--加载映射配置-->
<mappers>
<mapper resource="com/lagou/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
编写测试类
@Test
public void testFindAll() throws Exception {
// 加载核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 获取SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(is);
// 获取SqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行sql
List<User> list = sqlSession.selectList("UserMapper.findAll");
for (User user : list) {
System.out.println(user);
}
// 释放资源
sqlSession.close();
}
映射配置文件解释说明
CUD的映射文件写法
<!--新增-->
<insert id="save" parameterType="com.lagou.domain.User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
<update id="update" parameterType="com.lagou.domain.User">
update user set username = #{username},birthday = #{birthday},
sex = #{sex},address = #{address} where id = #{id}
</update>
<!-- 只有1个参数的话 大括号里面的东西可以随便写-->
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
相应的java代码API
插入操作使用的API是sqlSession.insert(“命名空间.id”,实体对象);
插入操作涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即 sqlSession.commit()
修改操作使用的API是sqlSession.update(“命名空间.id”,实体对象);
删除操作使用的API是sqlSession.delete(“命名空间.id”,Object);
核心配置文件解释
注意顺序也要按着这个来,你不能把mapper写到environment前面
environments
- 其中,事务管理器(transactionManager)类型有两种:
- JDBC:
这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。 - MANAGED:
这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。
例如:mybatis与spring整合后,事务交给spring容器管理。
- 其中,数据源(dataSource)常用类型有三种:
UNPOOLED:
这个数据源的实现只是每次被请求时打开和关闭连接。
POOLED:
这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。- JNDI :
这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据
源,然后放置一个 JNDI 上下文的数据源引用
properties
typealias
别名。基础类型和String已经默认起好名了。比如Integer变成int,String变成string
<typeAliases>
<!-- 单个起别名-->
<!-- <typeAlias type="com.ning.entity.User" alias="User"></typeAlias>-->
<!-- 别名就是类名,不区分大小写-->
<package name="com.ning.entity"/>
</typeAliases>
mappers
<mappers>
<!-- <mapper resource="com/ning/mapper/UserMapper.xml"></mapper>-->
<!-- <mapper class="com.ning.mapper.UserMapper"></mapper>-->
<package name="com.ning.mapper"/>
</mappers>
其实最常用的就是package那种写法
MyBatis基本原理
MyBatis代理开发方式
要求:
Mapper.xml映射文件中的namespace与mapper接口的全限定名相同
Mapper接口方法名和Mapper.xml映射文件中定义的每个statement的id相同
Mapper接口方法的输入参数类型和mapper.xml映射文件中定义的每个sql的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml映射文件中定义的每个sql的resultType的类型相同
public interface UserMapper {
public List<User> findAll() throws Exception;
}
<?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.mapper.UserMapper">
<!--查询所有-->
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
配置好以后你只需要这样写代码
整合Spring可以更简单
@Test
public void testFindAll() throws Exception {
// 加载核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 获得SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(is);
// 获得SqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获得Mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询
List<User> list = userMapper.findAll();
for (User user : list) {
System.out.println(user);
}
// 释放资源
sqlSession.close();
}
对代理的说明
mapper类是JDK动态代理生成的。
对代理对象调用方法,其实起作用的是相对应的invoke。
而invoke底层调用的其实还是SQLSession,让它去调用对应的方法。