第三部分:Mybatis基本应⽤
3.1 快速⼊⻔
3.1.1 开发步骤:
- 添加MyBatis的坐标
- 创建user数据表
- 编写User实体类
- 编写映射⽂件UserMapper.xml
- 编写核⼼⽂件SqlMapConfig.xml
- 编写测试类
3.1.2 环境搭建:
导⼊MyBatis的坐标和其他相关坐标
<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.48</version>
<scope>runtime</scope>
</dependency>
<!--单元测试坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--⽇志坐标-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
创建user数据表
编写User实体
public class User {
private Integer id;
private String username;
private String password;
}
编写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="com.tyf.mapper.UserMapper">
<select id="findAll" resultType="com.tyf.pojo.User">
select * from User
</select>
<insert id="add" parameterType="com.tyf.pojo.User">
insert into user values(#{id},#{username},#{password})
</insert>
<delete id="delete" parameterType="com.tyf.pojo.User">
delete from user where id = #{id}
</delete>
<delete id="update" parameterType="com.tyf.pojo.User">
update user set username = #{username} where id = #{id}
</delete>
</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>
<!-- 加载外部的properties文件 -->
<properties resource="jdbc.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"/>
<!-- 当前使用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 resource="UserDao.xml"/>
</mappers>
</configuration>
编写测试代码
@Test
public void testSelect() throws IOException {
//加载核⼼配置⽂件
InputStream resourceAsStream = Resources.class.getResourceAsStream("/SqlMapConfig.xml");
//InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession⼯⼚对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执⾏sql语句
List<User> userList = sqlSession.selectList("userMapper.findAll");
//打印结果
System.out.println(userList);
//释放资源
sqlSession.close();
}
jdbc文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
3.1.3 MyBatis的增删改查操作
MyBatis的插⼊数据操作: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="com.tyf.mapper.UserMapper">
<insert id="add" parameterType="com.tyf.pojo.User">
insert into user values(#{id},#{username},#{password})
</insert>
</mapper>
编写插⼊实体User的代码
@Test
public void testAdd() throws IOException {
//加载核⼼配置⽂件
InputStream resourceAsStream = Resources.class.getResourceAsStream("/SqlMapConfig.xml");
//InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession⼯⼚对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsername("yyyy");
user.setPassword("2222");
int insert = sqlSession.insert("userMapper.add", user);
//提交事务
sqlSession.commit();
//打印结果
System.out.println(insert);
//释放资源
sqlSession.close();
}
插⼊操作注意问题
插⼊语句使⽤insert标签
在映射⽂件中使⽤parameterType属性指定要插⼊的数据类型
Sql语句中使⽤#{实体属性名}⽅式引⽤实体中的属性值
插⼊操作使⽤的API是sqlSession.insert(“命名空间.id”,实体对象);
插⼊操作涉及数据库数据变化,所以要使⽤sqlSession对象显示的提交事务,即sqlSession.commit()
3.1.4 MyBatis的修改数据操作
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="com.tyf.mapper.UserMapper">
<select id="findAll" resultType="com.tyf.pojo.User">
select * from User
</select>
<insert id="add" parameterType="com.tyf.pojo.User">
insert into user values(#{id},#{username},#{password})
</insert>
<delete id="delete" parameterType="com.tyf.pojo.User">
delete from user where id = #{id}
</delete>
<delete id="update" parameterType="com.tyf.pojo.User">
update user set username = #{username} where id = #{id}
</delete>
</mapper>
//加载核⼼配置⽂件
InputStream resourceAsStream = Resources.class.getResourceAsStream("/SqlMapConfig.xml");
//InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession⼯⼚对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(2);
user.setUsername("666666");
int insert = sqlSession.update("userMapper.update", user);
//提交事务
sqlSession.commit();
//打印结果
System.out.println(insert);
//释放资源
sqlSession.close();
修改操作注意问题
修改语句使⽤update标签
修改操作使⽤的API是sqlSession.update(“命名空间.id”,实体对象);
3.1.5 MyBatis的删除数据操作
//加载核⼼配置⽂件
InputStream resourceAsStream = Resources.class.getResourceAsStream("/SqlMapConfig.xml");
//InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession⼯⼚对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(6);
int insert = sqlSession.delete("userMapper.delete", user);
//提交事务
sqlSession.commit();
//打印结果
System.out.println(insert);
//释放资源
sqlSession.close();
删除操作注意问题
删除语句使⽤delete标签
Sql语句中使⽤#{任意字符串}⽅式引⽤传递的单个参数
删除操作使⽤的API是sqlSession.delete(“命名空间.id”,Object);
3.1.6 MyBatis的映射⽂件概述
MyBatis核⼼配置⽂件层级关系
MyBatis常⽤配置解析
1)environments标签
数据库环境的配置,⽀持多环境配置
其中,事务管理器(transactionManager)常用类型有两种:
•JDBC:这个配置就是直接使⽤了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作⽤域。
•MANAGED:这个配置⼏乎没做什么。它从来不提交或回滚⼀个连接,⽽是让容器来管理事务的整个⽣命周期(⽐如 JEE 应⽤服务器的上下⽂)。 默认情况下它会关闭连接,然⽽⼀些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻⽌它默认的关闭⾏为。
2)mapper标签
该标签的作⽤是加载映射的,加载⽅式有如下⼏种:
•使⽤相对于类路径的资源引⽤,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
•使⽤完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
•使⽤映射器接⼝实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
•将包内的映射器接⼝实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>
3.1.7 Mybatis相应API介绍
SqlSession⼯⼚构建器SqlSessionFactoryBuilder
常⽤API:SqlSessionFactory build(InputStream inputStream)
通过加载mybatis的核⼼⽂件的输⼊流的形式构建⼀个SqlSessionFactory对象
//加载核⼼配置⽂件
InputStream resourceAsStream = Resources.class.getResourceAsStream("/SqlMapConfig.xml");
//InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession⼯⼚对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
其中, Resources ⼯具类,这个类在 org.apache.ibatis.io 包中。Resources 类帮助你从类路径下、⽂件系统或⼀个 web URL 中加载资源⽂件。
SqlSession⼯⼚对象SqlSessionFactory
SqlSessionFactory 有多个个⽅法创建SqlSession 实例。常⽤的有如下两个
SqlSession会话对象
SqlSession 实例在 MyBatis 中是⾮常强⼤的⼀个类。在这⾥你会看到所有执⾏语句、提交或回滚事务和获取映射器实例的⽅法。
执⾏语句的⽅法主要有:
操作事务的⽅法主要有:
3.2 Mybatis的Dao层实现
3.2.1 传统开发⽅式
编写UserDao接⼝
package com.tyf.mapper;
import com.tyf.pojo.User;
import java.io.IOException;
import java.util.List;
public interface IUserDao {
List<User> findAll() throws IOException;
}
编写UserDaoImpl实现
package com.tyf.mapper;
import com.tyf.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @Author tyf
* @DATE 2022/8/8 8:55
**/
public class UserDaoImpl implements IUserDao{
@Override
public List<User> findAll() throws IOException {
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("userMapper.findAll");
sqlSession.close();
return userList;
}
}
测试传统⽅式
@Test
public void testTraditionDao() throws IOException {
IUserDao userDao = new UserDaoImpl();
List<User> all = userDao.findAll();
System.out.println(all);
}
3.2.2 代理开发⽅式
代理开发⽅式介绍
采⽤ Mybatis 的代理开发⽅式实现 DAO 层的开发,这种⽅式是我们后⾯进⼊企业的主流。
Mapper 接⼝开发⽅法只需要程序员编写Mapper 接⼝(相当于Dao 接⼝),由Mybatis 框架根据接⼝
定义创建接⼝的动态代理对象,代理对象的⽅法体同上边Dao接⼝实现类⽅法。
Mapper 接⼝开发需要遵循以下规范:
1) Mapper.xml⽂件中的namespace与mapper接⼝的全限定名相同
2) Mapper接⼝⽅法名和Mapper.xml中定义的每个statement的id相同
3) Mapper接⼝⽅法的输⼊参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
4) Mapper接⼝⽅法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
编写UserMapper接⼝
@Test
public void testDao() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.findAll();
users.forEach(e-> System.out.println(e));
sqlSession.close();
}