文章目录
前言
Mybatis快速构建,基本使用
一、Mybatis
一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO为数据库中的记录。
二、快速构建
1、依赖导入pom.xml
<dependencies>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
2、准备实体类
@Data //lombok设置getxx()和setxx()方法
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
}
3、Mapper接口和MapperXML文件
Mybatis 中的 Mapper 接口相当于以前的 Dao。但是区别在于,Mapper 仅仅只是建立接口即可,我们不需要提供实现类,具体的SQL写到对应的Mapper文件
a. 定义mapper接口
package com.atguigu.mapper;
import com.atguigu.pojo.Employee;
/**
* t_emp表对应数据库SQL语句映射接口!
* 接口只规定方法,参数和返回值!
* mapper.xml中编写具体SQL语句!
*/
public interface EmployeeMapper {
/**
* 根据员工id查询员工数据方法
* @param empId 员工id
* @return 员工实体对象
*/
Employee selectEmployee(Integer empId);
}
b. 定义mapper xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.atguigu.mapper.EmployeeMapper">
<!-- 查询使用 select标签
id = 方法名
resultType = 返回值类型
标签内编写SQL语句
-->
<select id="selectEmployee" resultType="com.atguigu.pojo.Employee">
<!-- #{empId}代表动态传入的参数,并且进行赋值! -->
select emp_id empId,emp_name empName, emp_salary empSalary from
t_emp where emp_id = #{empId}
</select>
- 方法名和SQL的id一致
- 方法返回值和resultType一致
- 方法的参数和SQL的参数一致
- 接口的全类名和映射配置文件的名称空间一致
</mapper>
4、MyBatis配置文件 mybatis-config.xml
整合 Spring 之后,这个配置文件可以省略。
5、测试
public class MyBatisTest {
@Test
public void testSelectEmployee() throws IOException {
// 1.创建SqlSessionFactory对象
// ①声明Mybatis全局配置文件的路径
String mybatisConfigFilePath = "mybatis-config.xml";
// ②以输入流的形式加载Mybatis配置文件
InputStream inputStream = Resources.getResourceAsStream(mybatisConfigFilePath);
// ③基于读取Mybatis配置文件的输入流创建SqlSessionFactory对象(工厂模式)
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.使用SqlSessionFactory对象开启一个会话
SqlSession session = sessionFactory.openSession();
// 3.根据EmployeeMapper接口的Class对象获取Mapper接口类型的对象(动态代理技术)
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
// 4. 调用代理类方法既可以触发对应的SQL语句
Employee employee = employeeMapper.selectEmployee(1);
System.out.println("employee = " + employee);
// 4.关闭SqlSession
session.commit(); //提交事务 [DQL不需要,其他需要]
session.close(); //关闭会话
}
}
三、基本使用
1. #{} 和 ${}
Mybatis会将SQL语句中的#{}转换为问号占位符。
${}形式传参,底层Mybatis做的是字符串拼接操作。
结论:实际开发中,能用#{}实现的,肯定不用${}。
动态的不是值,是列名或者关键字,需要使用${}拼接
2. 数据输入
2.1 单个简单类型参数
这里数据输入具体是指上层方法(例如Service方法)调用Mapper接口时,数据传入的形式。
Employee selectEmployee(Integer empId);
//EmployeeMapper.xml
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
</select>
#{}中可以随意命名,通常还是使用和接口方法参数同名
2.2 实体类类型参数
int insertEmployee(Employee employee);
<insert id="insertEmployee">
insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>
Mybatis会根据#{}中传入的数据,加工成getXxx()方法,通过反射在实体类对象中调用这个方法,从而获取到对应的数据。填充到#{}解析后的问号占位符这个位置。
2.3 零散的简单类型数据
2.4 Map类型参数
int updateEmployeeByMap(Map<String, Object> paramMap);
<update id="updateEmployeeByMap">
update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}
</update>
@Test //测试类
public void testUpdateEmpNameByMap() {
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("empSalaryKey", 999.99);
paramMap.put("empIdKey", 5);
int result = mapper.updateEmployeeByMap(paramMap);
log.info("result = " + result);
}
#{}中写Map中的key
3. 数据输出
(1)增删改操作返回的受影响行数:直接使用 int 或 long 类型接收即可
(2)查询操作的查询结果
3.1 单个简单类型
Employee selectEmployee(Integer empId);
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
<!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
<!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
</select>
//通过配置mybatis-config.xml,select语句中可以不给字段设置别名
<setting name="mapUnderscoreToCamelCase" value="true"/>
3.2 Map类型
<!-- Map<String,Object> selectEmpNameAndMaxSalary(); -->
<!-- 返回工资最高的员工的姓名和他的工资 -->
<select id="selectEmpNameAndMaxSalary" resultType="map">
SELECT
emp_name 员工姓名,
emp_salary 员工工资,
(SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
FROM t_emp WHERE emp_salary=(
SELECT MAX(emp_salary) FROM t_emp)
</select>
3.3 List类型
查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。在resultType属性中还是设置实体类类型即可。
<!-- List<Employee> selectAll(); -->
<select id="selectAll" resultType="com.atguigu.mybatis.entity.Employee">
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp
</select>
3.4 返回主键值
自增长类型主键
<!-- int insertEmployee(Employee employee); -->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
insert into t_emp(emp_name,emp_salary)
values(#{empName},#{empSalary})
</insert>
非自增长类型主键
<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" resultType="java.lang.String"
order="BEFORE">
SELECT UUID() as id
</selectKey>
INSERT INTO user (id, username, password)
VALUES (#{id}, #{username}, #{password})
</insert>