[MybatisReLearning]03.23Mybatis(简介+搭建+配置文件+CRUD+获取参数值)
MyBatis
简介
- Mybatis历史:最初是Apache的一个开源项目iBatis,2010年6月这个项目由Apache Software Foundation迁移到了Google Code 随着开发团队转到了Google Code旗下,iBatis 3.X正式改名为MyBatis,代码于2013年迁移到了Github
- iBatis这一个词来源于internet 和abatis的组合,是一个基于Java的持久层框架.iBatis提供的持久层框架包括SQL Maps和Data Access Object (DAO)
特性
- 支持定制化SQL,存储的过程和高级映射的优秀的持久层框架
- MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
- MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的entity(POJO普通的Java对象)映射成数据库中的记录
- MyBatis是一个半自动的ORM(Object Relation Mapping)对象关系映射框架
对比
- JDBC
- SQL夹杂在Java代码中耦合度高,导致硬编码内伤
- 维护不易且实际开发中需要SQL有变化,频繁修改的情况多件
- 代码冗场,开发效率低下
- Hibernate & JPA
- 操作简单,开发效率高
- 程序中长难复杂的SQL需要绕过框架执行
- 内部自动生产SQL,不容易做特殊的优化
- 基于全映射的全自动框架,大量字段的POJO进行不封映射时比较困难
- 反射操作太多,导致数据库性能下降
- MyBatis
- 轻量级,性能出色
- SQL和Java编码分开,功能的边界清晰,Java代码专注业务,SQL语句专注数据
- 开发效率稍逊与Hibernate,但是完全能够接受(对日开发建议对比学习)
搭建MyBatis
1. 创建maven工程导入依赖和配置打包方式
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
2. 创建MaBatis的核心配置文件
习惯命名为mybatis-config.xml,整合了spring之后可以省略这个配置文件转而使用bean.xml配置,也可以整合了SSM之后使用config来解决
核心配置文件放在
<?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>
<!--设置类型别名,因为select时候填写的resultType太麻烦
alias设置不设置都会有默认的值为类名的大写和小写
-->
<typeAliases>
<!--<typeAlias type="com.sli.com.sli.mybatis.entity.User" alias="User"></typeAlias>-->
<!--以包为单位,将包下面的所有类型设置默认的类型别名,且不区分大小写-->
<package name="com.sli.mybatis.entity"/>
</typeAliases>
<!--设置连接数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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="com/sli/mybatis/mapper/xml/ParameterMapper.xml"/>
<!--
以包为单位引入映射文件
1.mapper接口所在的包要和映射文件所在的包一致
2.mapper接口要和映射文件的名字一致
-->
<!--<package name="com/sli/mybatis/mapper/xml/*.xml"/>-->
</mappers>
</configuration>
3. 创建mapper接口
类似于springboot和Mybatis-Plus自动生成代码时的mapper->mapper.xml这种感觉,一般是自定义SQL使用(只是接口,不需要实现类)
public interface ParameterMapper {
/**
* 查询所有的员工信息
*/
List<User> selectAllUser();
}
4. 创建mapper接口的映射文件
1. 相关的概念:ORM(Object Relationship Mapping)关系对象映射
1. 对象: Java对象
2. 关系: 关系型数据库
3. 映射: 二者的对应关系(如下)
Java概念 | 数据库概念 |
---|---|
类 | 表 |
属性 | 字段/列 |
对象 | 记录/行 |
- 映射文件的命名规则
- 表所对应的实体类的类名+Mapper.xml
- 例如:表为t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
- 因此一个映射文件对应第一个实体类,对应一张表的操作
- MyBatis映射文件用于编写SQL,访问一级操作表中的数据
- MyBatis映射文件存放的位置一般位于Mapper接口的xml文件夹的下面
- MyBatis中可以面向接口数据 保证两个一直
- mapper接口的全类名和映射文件的命名空间(namespace)保持一致
- mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
<?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.sli.mybatis.mapper.ParameterMapper">
<!--List<User> selectAllUser();-->
<select id="selectAllUser" resultType="User">
select * from t_user;
</select>
</mapper>
5. 通过junit测试功能
- SqlSession(session会话控制):代表java和数据库之间的会话.HttpSession(java和浏览器之间的会话)
- SqlSessionFactory:是生产SqlSession的工厂
- 工厂模式:如果创建某一个对象,使用的过程基本固定,name我们就可以吧这个对象的相关代码封装到一个'工厂类'中,以后都使用这个工厂类来生产我们需要的对象
封装的utils
public class SqlSessionUtils {
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
try{
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
}catch (IOException e){
e.printStackTrace();
}
return sqlSession;
}
}
@Test
public void getAllUser() throws IOException {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
List<User> users = mapper.selectAllUser();
users.forEach(user -> System.out.println(user));
}
6.核心配置问价详解
<?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"></properties>
<settings>
<!--将表中字段的下划线自动转换为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<typeAliases>
<!--
typeAlias:设置某个具体的类型的别名
属性:
type:需要设置别名的类型的全类名
alias:设置此类型的别名,且别名不区分大小写。若不设置此属性,该类型拥有默认的别名,即类名
-->
<!--<typeAlias type="com.atguigu.mybatis.bean.User"></typeAlias>-->
<!--<typeAlias type="com.atguigu.mybatis.bean.User" alias="user">
</typeAlias>-->
<!--以包为单位,设置改包下所有的类型都拥有默认的别名,即类名且不区分大小写-->
<package name="com.atguigu.mybatis.bean"/>
</typeAliases>
<!--
environments:设置多个连接数据库的环境
属性:
default:设置默认使用的环境的id
-->
<environments default="mysql_test">
<!--
environment:设置具体的连接数据库的环境信息
属性:
id:设置环境的唯一标识,可通过environments标签中的default设置某一个环境的id,表示默认使用的环境
-->
<environment id="mysql_test">
<!--
transactionManager:设置事务管理方式
属性:
type:设置事务管理方式,type="JDBC|MANAGED"
type="JDBC":设置当前环境的事务管理都必须手动处理
type="MANAGED":设置事务被管理,例如spring中的AOP
-->
<transactionManager type="JDBC"/>
<!--
dataSource:设置数据源
属性:
type:设置数据源的类型,type="POOLED|UNPOOLED|JNDI"
type="POOLED":使用数据库连接池,即会将创建的连接进行缓存,下次使用可以从缓存中直接获取,不需要重新创建
type="UNPOOLED":不使用数据库连接池,即每次使用连接都需要重新创建
type="JNDI":调用上下文中的数据源
-->
<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"/> -->
<!--
以包为单位,将包下所有的映射文件引入核心配置文件
注意:
1. 此方式必须保证mapper接口和mapper映射文件必须在相同的包下
2. mapper接口要和mapper映射文件的名字一致
-->
<package name="com.atguigu.mybatis.mapper"/>
</mappers>
</configuration>
7.MyBatis的增删改查
- 注意
- 查询的标签select必须设置属性resultType和resultMap,用于实体类和数据库表的映射关系
- resultType:设置的是默认的映射关系(将查询出来的字段名和属性名去自动匹配,能匹配到就赋值,匹配不到就不赋值)
- resultMap:设置的是自定义的映射关系(多对一,一对多的时候,字段名和属性名匹配不到的时候)
- 当查询的数据为多条的时候,不能使用实体类作为返回值,只能使用集合,否则会抛出异常(TooManyResultsException);当查询数据为一条的时候可以使用实体类或者集合作为返回数据
- 查询的标签select必须设置属性resultType和resultMap,用于实体类和数据库表的映射关系
8.MyBatis获取参数值的两种方式重点
- Mybatis获取参数值的方式#{} ${}
- ${}本质就是字符串拼接,#{}的本质就是占位符赋值(#{}使用较多)
- 单个字面量类型的参数
- 若mapper接口中的方法参数为单个字面量类型,此时可以使用${}和#{}以任意的名称获取参数值(如下)
- 多个字面量类型的参数
- 若mapper接口中的方法参数为多个时,此时MyBatis会将这些参数放在一个map集合中
- 以arg0 arg1..为键,以参数为值
- 以param1 param2...为键,以参数为值
- 因此只要通过${}和#{}访问map集合的键就可以获取对应的值
- 使用arg或者param都可以,注意arg从0开始而param从1开始
- map集合类型的参数
- 若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,讲这些数据放在map中只需要通过${}或者#{}访问map集合的key就可以获取到value
- 实体类类型的参数(常用)
- 若mapper接口中的方法参数为实体类对象此时可以使用#{}或者${},通过访问实体类对象中的属性名获取属性值
- 使用@param标识参数
- 可以通过@Param注解来标识mapper接口中的方法参数,此时会将这些参数放在map集合中
- 可以@param注解的value属性值为键,以参数为值
- 以param1,param2..为键,以参数为值
- 只需要通过${},#{}访问map集合的键就可以获取对应的值
总结:
分为两种情况(1. 实体类参数 2. 使用@Param)