Spring-boot-Mybaties快速入门
使用Mybatis查询所有用户数据
-
准备工作(创建springboot工程,数据库表格user,实体类User)
-
引入Mybatis的相关依赖,配置Mybatis(数据库连接信息)
-
编写SQL语句(注解/XML)
-
单元测试
package com.example; import com.example.mapper.UserMapper; import com.example.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; @SpringBootTest //springboot整合单元测试的注解 class SpringbootMybatiesQuickstartApplicationTests { //自动装配 @Autowired private UserMapper userMapper; @Test public void testListUser(){ //将查询到的数据 放到 userList里,之后通过 foreach遍历输出 List<User> userList=userMapper.list(); userList.stream().forEach(user -> { System.out.println(user); }); } }
lombok
-
使用前,先在pom中引用。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
-
注意事项:Lombok会在编译时,自动生成对应的java代码。我们在使用lombok时,还需要安装一个lombok的插件(idea自带)
-
Lombok是一个实用的Java类库,能通过注解的像是自动生成构造器,getter/setter,equals,hashcode,toString等方法,并可以自动化生成日志变量,简化java开发,提高效率。
注解 作用 @Getter/@Setter 为所有属性提供get/set方法 @ToString 会给类自动生成易阅读的toString方法 @EqualsAndHashCode 根据类所拥有的非静态字段自动重写equals方法和hashCode方法 !! @Data 提供了更综合的生成代码功能(@Getter +@Setter+@ToString +@EqualsAndHashCode) !! @noArgsConstructor 为实体类生成无参的构造器方法 !! @AllArgsConstructor 为实体类生成除了static修饰的字段之外带有各参数的构造器方法
-
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> 例如:添加该行 <version>2.2.6.RELEASE</version> 创建的项目中的 pom.xml依赖 爆红,解决办法是 在下面指定 版本号
Mybatis基本操作
输出mybatis日志
-
可以在application.properties中打开,打开mybaties的日志,并指定输出到控制台
#指定mybatis输出日志的位置,输出控制台 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
参数占位符
-
- 执行SQL时,会将#{...}替换为?,生成预编译SQL,会自动设置参数值
- 使用时机:参数传递,都使用#
- $
- 拼接SQL.直接将参数拼接到SQL语句中,存在SQL注入问题
- 使用时机:如果对表名,列表进行动态设置时使用。
根据主键删除
-
SQL语句:
delete from emp where id=9;
-
接口方法
@Delete("delete from emp where id=#{id}") //里面写sql语句。#{}为动态获取 public void delete(Integer id);
-
注意事项
如果mapper接口方法形参只有一个普通类型的参数,#{...}里面的属性名可以随便写,如#{id},#{value}
新增
-
SQL语句:
insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values('Tom','汤姆',1,'1.jpg',1,'2005-02-03',1,now(),now());
-
接口方法:
//新增用户信息 @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n" +"values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})") public void insert(Emp emp);
-
主键返回
描述:在数据添加成功后,需要获取插入数据库数据的主键。如:添加套餐数据时,还需要维护套餐菜品关系表数据。
-
实现:
@Options(keyProperty = "id",useGeneratedKeys = true) //返回插入内容的主键信息 添加该行内容 @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n" + "values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})") public void insert(Emp emp);
更新
-
SQL语句:
update emp set username ='',name='',gender='',image='',job='', entrydate='',dept_id='',update_time='' where id=1;
-
接口方法:
@Update("update emp set username =#{username},name=#{name},gender=#{gender},image=#{image},job=# {job},\n" +"entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}") public void update(Emp emp);
查询(根据ID查询)
-
SQL语句
select * from emp where id=10;
-
接口方法
@Select("select * from emp where id=#{id}") public Emp getByID(Integer id); //将返回值封装到一个对象中
-
数据封装
-
实体类属性名 和 数据库表查询返回的字段名一致,mybatis会自动封装
-
如果实体类属性名 和 数据库表查询返回的字段名不一致,不能自动封装
-
为解决不能封装的问题
-
方案一:起别名,在SQL语句中,对不宜阿姨那个的列名起别名,别名和实体类属性名一样。
@Select("select id, username, password, name, gender, image, job, " + "entrydate, dept_id deptId, create_time createTime, update_time updateTime from emp where id=#{id}") public Emp getByID(Integer id);
-
方案二:通过@Results,@Result注解手动映射封装
@Results({ @Result(column = "dept_id",property = "deptId"), //dept_id表中的字段名。 //property = "deptId" 指封装到 deptId @Result(column = "create_time",property = "createTime"), @Result(column = "update_time",property = "updateTime") }) @Select("select * from emp where id=#{id}") public Emp getByID(Integer id);
-
方案三:开启mybatis的驼峰命名自动映射开关 ---- a_cloumn ------->aCloumn。如果字段名与属性名符合驼峰命名规则,mybatis会通过驼峰命名规则映射。(强烈推荐)必须要遵守驼峰命名规则。
//开启mybatis的驼峰命名自动映射开关 ---- a_cloumn ------->aCloumn //需要在application.properties 中开启 mybatis.configuration.map-underscore-to-camel-case=true
-
-
查询(根据条件查询)
-
SQL语句
select * from emp where name like '%张%' and gender = 1 and entrydate between '2000-01-01' and '2025-05-06' order by update_time desc;
-
接口方法:
//未预编译。 性能低,不安全,存在SQL注入问题 @Select("select * from emp where name like '%${name}%' and gender = #{gender} and" + " entrydate between #{begin} and #{end} order by update_time desc") public List<Emp> list(String name, Integer gender, LocalDate begin,LocalDate end);
//通过sql自带的函数concat进行字符的拼接 !!!推荐使用 @Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and" + " entrydate between #{begin} and #{end} order by update_time desc") public List<Emp> list(String name, Integer gender, LocalDate begin, LocalDate end);
XML映射文件(特别重要)
规范
- XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
- XML映射文件的namespace属性为Mapper接口全限定名一致。 必须是完整的全类名。
- XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
Mybatis的动态SQL语句
随着用户的输入或外部条件的变化而变化的SQL语句,称之为动态SQL
-
:用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL <if test="name != null"> //如果;里面的语句判断为true,则拼接下面的SQL语句 name like concat('%', #{name}, '%') </if>
完整写法:
:where元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的AND或OR. <select id="list" resultType="com.example.pojo.Emp"> select * from emp <where> //mybatis的语法。可以根据下面的 情况自动添加 and. <if test="name != null"> name like concat('%', #{name}, '%') </if> <if test="gender != null"> and gender = #{gender} </if> <if test="begin != null and end != null"> and entrydate between #{begin} and #{end} </if> </where> order by update_time desc </select>
:动态地在行首插入SET关键字,并会删除额外的逗号。(用在update语句中) <update id="update2"> update emp <set> <if test="username != null">username = #{username},</if> <if test="name != null">name= #{name},</if> <if test="gender != null">gender = #{gender},</if> <if test="image != null">image = #{image},</if> <if test="job != null">job = #{job},</if> <if test="entrydate != null">entrydate = #{entrydate},</if> <if test="deptId != null">dept_id = #{deptId},</if> <if test="updateTime != null">update_time = #{updateTime}</if> </set> where id = #{id} </update>
-
-
SQl语句:
delete from emp where id in(1,2,3)
-
接口方法
//批量删除 @Test public void testDeleteByIds(){ List<Integer> ids= Arrays.asList(9,10); empMapper.deleteByIds(ids); }
-
XML映射文件
<!-- collection:遍历的集合 item:遍历出来的数据 separator:分隔符 open:遍历开始前拼接的SQl片段 close:遍历结束后拼接的SQL片段 --> <delete id="deleteByIds"> delete from emp where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete>
-
-
SQL片段
-
:定义可重用的SQL片段 -
:通过属性refid,指定包含的sql的片段 <sql id="commonSelect"> select id,username,password,name,gender,image,job,entrydate,dept_id,creat_time,update_time from emp </sql> <select id="list" resultType="com.example.pojo.Emp"> <include refid="commonSelect" /> <where> <if test="name != null"> name like concat('%', #{name}, '%') </if> <if test="gender != null"> and gender = #{gender} </if> <if test="begin != null and end != null"> and entrydate between #{begin} and #{end} </if> </where> order by update_time desc </select>
-