介绍
MyBatis是一款优秀的持久层(Dao层)框架,用于简化JDBC的开发。MyBatis 底层是基于 JDBC 实现的,它封装了 JDBC 的大部分功能,使得数据库操作更加便捷和高效。同时,MyBatis 也保留了 JDBC 的灵活性,允许开发者编写定制化的 SQL 语句,以满足复杂的业务需求。
创建Mybatis项目
新建模块
在idea中新建模块,命名为springboot-mybatis-quickstart作为Mybatis启动的练习,生成器类型选择Spring Intializr(用于创建springboot项目),类型选择Maven(用于管理项目),在下一步添加2个依赖MybatisFramework和MySQL Driver(Mybaits框架和MySQL驱动)
项目结构
创建好的springboot项目有以下重要结构:
1、src/main/java,
包含项目的所有Java源代码,是Java源代码目录
2、src/main/resources,
包含项目的配置文件、静态资源和模板文件
3、src/main/java
,包含项目的测试代码
pom.xml文件中则引入了各种依赖。
使用Mybatis操作数据库
数据库连接
在src/main/resources/application.properties中配置数据库连接信息
创建UseMapper接口
我们在src/main/java下新建UseMapper接口
package com.itheima.mapper;
import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper //在运行时,会自动生成该接口的实现类对象(代理对象), 并且将该对象交给IOC容器管理
public interface UserMapper {
//查询全部用户信息
@Select("select * from user")
public List<User> list();//此方法包含在@Select注解之中
}
UserMapper接口被标记为@Mapper,MyBatis会自动为其生成实现类(程序在运行时会自动创建该接口的代理对象,并且会将代理对象放到IOC容器中),开发者可以通过UserMapper接口直接调用数据库操作。
在接口内编写对数据库的操作,要进行什么操作就加入相应的注解(比如要进行查询操作,则在方法上加@Select注解),在注解后括号内写入SQL语句,随后声明方法。
这么做就相当于注解的SQL语句是方法体,调用方法时会自动执行这个SQL语句。比如调用list方法,就会直接从数据库中查询数据并自动封装到list集合中
创建User类
由于要把查询到的数据封装到list集合中,那么就可以定义一个类接收集合中的每一个元素
@Data
@NoArgsConstructor//无参构造注解
@AllArgsConstructor//全参构造注解
public class User {
private Integer id;
private String name;
private Short age;
private Short gender;
private String phone;
}
操作数据库
我们在test包中的SpringbootMybatisQuickstartApplicationTests(测试类)中,先创建userMapper的实体类对象,随后调用userMapper中的list方法,就会查询数据库中的所有数据并封装到userList集合中
SpringBootTest //springboot整合单元测试注解
class SpringbootMybatisQuickstartApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testListUser(){
List<User> userList = userMapper.list();
userList.stream().forEach(user -> {
System.out.println(user);
});
}
}
user表中的原始数据如下:
运行测试类中的方法,结果如下:
已经查询到了user表中的所有数据 ,这就是一个简单的Mybatis运用实例
使用Mybatis进行增删改查
先在数据库中创建dept(部门表)和emp(员工表)
然后在pojo包下创建Emp员工对象,用来和数据库的员工相匹配
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
private Integer id;
private String username;
private String password;
private String name;
private Short gender;
private String image;
private Short job;
private LocalDate entrydate;
private Integer deptId;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
然后在mapper包下创建EmpMapper接口(加@Mapper注解),在此接口内实现增删改查的SQL操作
参数占位符
#{...}
执行SQL时,会将#{….}替换为?,生成预编译SQL,会自动设置参数值。
使用时机:参数传递
${...}
拼接SQL。直接将参数拼接在SQL语句中,存在SQL注 入问题。
使用时机:如果对表名、列表进行动态设置时使用。
增加
在EmpMapper接口中声明函数。
在数据添加成功后,需要获取插入数据库数据的主键则要加@Options注释。
@Options(keyProperty = "id"/*返回的主键封装到id字段中*/,useGeneratedKeys = true/*获取返回的主键*/)
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
" VALUES (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
public void insert(Emp emp);
随后在测试类中调用insert方法。
//新增员工
@Test
public void testInsert(){
//构造员工对象
Emp emp = new Emp();
emp.setUsername("Tom3");
emp.setName("汤姆3");
emp.setImage("1.jpg");
emp.setGender((short)1);
emp.setJob((short)1);
emp.setEntrydate(LocalDate.of(2000,1,1));
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
emp.setDeptId(1);
//执行新增员工信息操作
empMapper.insert(emp);
System.out.println(emp.getId());
}
随后表中插入相关数据,并在控制台打印出了Tom3的id
删除
在EmpMapper中声明函数
//根据ID删除数据
@Delete("delete from emp where id = #{id}")
public void delete(Integer id);
//#{id}是占位符,delete方法形参id传递后会赋值给这个占位符
在测试类中调用此方法 ,则会将id为16的数据删除
/根据ID删除
@Test
public void testDelete(){
//int delete = empMapper.delete(16);
//System.out.println(delete);
empMapper.delete(16);
}
修改
在EmpMapper中声明函数,根据id修改员工信息
//更新员工
@Update("update emp set username = #{username}, name = #{name}, gender = #{gender}, image = #{image}," +
" job = #{job}, entrydate = #{entrydate}, dept_id = #{deptId},update_time = #{updateTime} where id = #{id}")
public void update(Emp emp);
在测试类中调用此方法 ,id为10的员工信息将会被更新
//更新员工
@Test
public void testUpdate(){
//构造员工对象
Emp emp = new Emp();
emp.setId(10);
emp.setUsername("Tom1");
emp.setName("汤姆1");
emp.setImage("1.jpg");
emp.setGender((short)1);
emp.setJob((short)1);
emp.setEntrydate(LocalDate.of(2000,1,1));
emp.setUpdateTime(LocalDateTime.now());
emp.setDeptId(1);
//执行更新员工操作
empMapper.update(emp);
}
查询
在EmpMapper中声明函数,根据id查询员工信息,将员工信息封装到Emp类作为返回值
@Select("select * from emp where id = #{id}")
public Emp getById(Integer id);
注:由于字段名和类中变量名不一定相同(字段名有_变量名是小驼峰),所以有些字段数据无法正确封装到类中的变量中
解决方式:开启mybatis的驼峰命名自动映射开关,在application.properties文件中配置mybaits驼峰命名自动映射开关
随后在测试类中调用此方法,将查询到的员工信息封装到Emp对象中并返回
@Test
public void testGetById(){
Emp emp = empMapper.getById(20);
System.out.println(emp);
}
控制台中正确打印出id为10的员工信息