文章目录

  • 前言
  • 五、配置文件完成增删改查
    • 1.学习目标
    • 2.入门案例环境准备
    • 3.查询–查询所有
    • 4.查询–根据id查询
    • 5. 查询–条件查询
    • 6.查询–多条件动态查询
    • 7.条件查询–单条件动态查询
    • 8.添加(增)
    • 9.修改–改所有参数
    • 10.修改–动态修改
    • 11.删除–删除单条记录
    • 12.删除–删除多条记录
    • 13.mybatis注解开发
  • 总结

前言

为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)


五、配置文件完成增删改查

1.学习目标

2.入门案例环境准备

(详细代码可以在作者主页的mybatisy源码re_crud_demo模块里找到)

  1. 在数据库创建实体类表tb_brand
  • 代码
-- 删除tb_brand表drop table if exists tb_brand;-- 创建tb_brand表create table tb_brand(-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20),-- 排序字段orderedint,-- 描述信息descriptionvarchar(100),-- 状态:0:禁用1:启用status int);-- 添加数据insert into tb_brand (brand_name, company_name, ordered, description, status)values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0), ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1), ('小米', '小米科技有限公司', 50, 'are you ok', 1);SELECT * FROM tb_brand;
  • 效果

  1. 创建对应的实体类brand
package org.example.pojo;//此处省略getter、setter和toString方法public class Brand {// id 主键private Integer id;// 品牌名称private String brandName;// 企业名称private String companyName;// 排序字段private Integer ordered;// 描述信息private String description;// 状态:0:禁用1:启用private Integer status;
  1. 在test包下的test文件下创建测试样例MybatisTest

  1. 安装MybatisX插件

  1. 文件结构预览

3.查询–查询所有

  1. 操作步骤

  1. 编写接口方法:Mapper接口
public interface BrandMapper {/** * 查询所有 */List<Brand> selectAll();}
  1. 编写SQL语句:SQL映射文件
<" />="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间--><mapper namespace="org.example.mapper.BrandMapper"><select id="selectAll" resultMap="brandResultMap">select *from tb_brand;</select></mapper>
  1. 编写测试样例
public class MyBatisTest {@Testpublic void testSelectAll() throws IOException {//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法List<Brand> brands = brandMapper.selectAll();System.out.println(brands);//5. 释放资源sqlSession.close();}}
  1. 运行结果

  1. 小结

  1. 问题
  • 问题描述: 查询出来的brandName和companyName为空

  • 原因: 数据库表的字段名称 和 实体类的属性名称 不一样,则不能自动封装数据

(实体类属性名)

(数据库名称)

  • 解决方案一

    起别名:对不一样的列名起别名,让别名和实体类的属性名一样 * 缺点:每次查询都要定义一次别名 * sql片段* 缺点:不灵活


(sql片段):

<!--sql片段--><sql id="brand_column"> id, brand_name as brandName, company_name as companyName, ordered, description, status </sql> <select id="selectAll" resultType="brand"> select <include refid="brand_column" /> from tb_brand; </select>

运行结果:

  • 解决方案二:resultMap

     resultMap: 1. 定义标签 2. 在标签中,使用resultMap属性替换 resultType属性

对应的xml配置文件:

<" />="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间--><mapper namespace="org.example.mapper.BrandMapper"><!--id属性 ,resultMap标签的标识。--><!--type属性 ,返回值的全限定类名,或类型别名。--><resultMap id="brandResultMap" type="brand"><!--id:完成主键字段的映射column:表的列名property:实体类的属性名result:完成一般字段的映射column:表的列名property:实体类的属性名--><result column="brand_name" property="brandName"/><result column="company_name" property="companyName"/></resultMap><select id="selectAll" resultMap="brandResultMap">select *from tb_brand;</select></mapper>

运行结果:

4.查询–根据id查询

  1. 操作步骤


2. 编写接口方法:Mapper接口

package org.example.mapper;import org.example.pojo.Brand;import java.util.List;public interface BrandMapper {/** * 查询所有 */List<Brand> selectAll();/** * 查看详情:根据Id查询 */Brand selectById(int id);}package org.example.mapper;import org.example.pojo.Brand;import java.util.List;public interface BrandMapper {/** * 查看详情:根据Id查询 */Brand selectById(int id);}
  1. 编写SQL语句:SQL映射文件
<" />="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间--><mapper namespace="org.example.mapper.BrandMapper"><resultMap id="brandResultMap" type="brand"><result column="brand_name" property="brandName"/><result column="company_name" property="companyName"/></resultMap><select id="selectById" resultMap="brandResultMap">select *from tb_brand where id = #{id};</select></mapper>
  1. 编写测试样例
public class MyBatisTest {@Testpublic void testSelectById() throws IOException {//接收参数int id = 1;//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法Brand brand = brandMapper.selectById(id);System.out.println(brand);//5. 释放资源sqlSession.close();}}
  1. 运行结果

  1. BrandMapper.xml中的sql语句的参数占位符

1. #{}:会将其替换为 " />

2. ${}:拼sql。会存在SQL注入问题

3. 使用时机:* 参数传递的时候:#{}* 表名或者列名不固定的情况下:${} 会存在SQL注入问题
  1. BrandMapper.xml配置文件中sql语句select标签中的参数类型

 * 参数类型:parameterType:可以省略
  1. sql语句中的特殊字符处理

 * 特殊字符处理:1. 转义字符:

2. CDATA区:

5. 查询–条件查询

  1. 操作步骤

  1. 编写接口方法:Mapper接口
public interface BrandMapper {/** * 条件查询 ** 参数接收 *1. 散装参数:如果方法中有多个参数,需要使用@Param("SQL参数占位符名称") *2. 对象参数:对象的属性名称要和参数占位符名称一致 *3. map集合参数:map集合的键值要和参数占位符名称一致 * */ //方式一:接收散装参数List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);//放肆二:接收对象参数//List selectByCondition(Brand brand);//方式三:接收map集合参数//List selectByCondition(Map map);}
  1. 编写SQL语句:SQL映射文件
<" />="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间--><mapper namespace="org.example.mapper.BrandMapper"><resultMap id="brandResultMap" type="brand"><result column="brand_name" property="brandName"/><result column="company_name" property="companyName"/></resultMap><!--条件查询--><select id="selectByCondition" resultMap="brandResultMap">select *from tb_brandwhere status = #{status}and company_name like #{companyName}and brand_name like #{brandName}</select></mapper>
  1. 编写测试样例
public class MyBatisTest {@Testpublic void testSelectByCondition() throws IOException {//方式一: 接收散装参数//接收参数int status = 1;String companyName = "华为";String brandName = "华为";// 处理参数companyName = "%" + companyName + "%";brandName = "%" + brandName + "%";//方式二:接收对象参数//封装对象//Brand brand = new Brand();//brand.setStatus(status);//brand.setCompanyName(companyName);//brand.setBrandName(brandName);//方式三:接收散装参数//Map map = new HashMap();//map.put("status" , status);//map.put("companyName", companyName);//map.put("brandName" , brandName);//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法//方式一:接收散装参数List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);//方式二:接收对象参数//List brands = brandMapper.selectByCondition(brand);//方式三:接收集合参数//List brands = brandMapper.selectByCondition(map);System.out.println(brands);//5. 释放资源sqlSession.close();}}
  1. 运行结果

  1. 小结

6.查询–多条件动态查询

(在多条件查询的基础上修改BrandMapper.xml中的SQL语句的书写部分)

  1. 情景导入


在多条件查询的基础案例中我们发现,查询多条件的sql语句需要获取当前状态status,企业名称companyname,品牌名称brandname三个参数,缺一不可。如果只输入品牌名称,该查询无法完成,不符合实际需求,报错实例(在传参代码书写时将status和companyname的部分注释掉)如下:


因此,我们需要动态SQL来辅助我们解决类似的问题。动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

  1. 操作步骤

  1. 编写SQL语句:SQL映射文件
 <select id="selectByCondition" resultMap="brandResultMap">select *from tb_brandwhere<if test="status != null">status = #{status}</if><if test="companyName != null and companyName != '' ">and company_name like #{companyName}</if><if test="brandName != null and brandName != '' ">and brand_name like #{brandName}</if></select>
  1. 编写测试样例

  1. 运行结果

  1. 存在问题

当我们把where后面的第一个参数也注释掉我们发现程序就会报错,原因查看运行结果中的sql语句就一目了然了,如下:

(sql语句)

(测试样例)

(运行结果)

  1. 改进方式一

(sql语句书写改进)

(运行结果)

  1. 改进方式二

(sql语句书写改进)


(运行结果)

  1. 小结

7.条件查询–单条件动态查询

  1. 操作步骤

  1. 编写接口方法:Mapper接口
List<Brand> selectByConditionSingle(Brand brand);
  1. 编写SQL语句:SQL映射文件(注意区分,没用and连接)

otherwrise:不传参搜索的情况,相当于switch语句中的default

 <select id="selectByConditionSingle" resultType="org.example.pojo.Brand">select *from tb_brand<where><choose><when test="status != null">status = #{status}</when><when test="companyName != null and companyName != '' ">;company_name like #{companyName}</when><when test="brandName != null and brandName != ''">;brand_name like #{brandName}</when><otherwise>1 = 1</otherwise></choose></where></select>
  1. 编写测试样例
 @Testpublic void testSelectByConditionSingle() throws IOException {//接收参数int status = 1;String companyName = "华为";String brandName = "华为";// 处理参数companyName = "%" + companyName + "%";brandName = "%" + brandName + "%";//封装对象Brand brand = new Brand();//brand.setStatus(status);brand.setCompanyName(companyName);//brand.setBrandName(brandName);//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法List<Brand> brands = brandMapper.selectByConditionSingle(brand);System.out.println(brands);//5. 释放资源sqlSession.close();}}
  1. 运行结果

8.添加(增)

  1. 操作步骤

  1. 编写接口方法:Mapper接口
 /** * 添加 */void add(Brand brand);
  1. 编写SQL语句:SQL映射文件
<insert id="add">insert into tb_brand (brand_name, company_name, ordered, description, status)values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});</insert>
  1. 编写测试样例

(默认需要手动提交事务: sqlSession.commit();)

 @Testpublic void testAdd() throws IOException {//接收参数int status = 1;String companyName = "波导手机";String brandName = "波导";String description = "手机中的战斗机";int ordered = 100;//封装对象Brand brand = new Brand();brand.setStatus(status);brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setDescription(description);brand.setOrdered(ordered);//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//SqlSession sqlSession = sqlSessionFactory.openSession(true);//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法brandMapper.add(brand);//提交事务sqlSession.commit();//5. 释放资源sqlSession.close();}
  1. 运行结果


  1. 添加–主键返回

(无法通过brand对象直接获取id值)

  1. 获取brand对象的id



9.修改–改所有参数

  1. 操作步骤

  1. 编写接口方法:Mapper接口
 /** * 修改 */int update(Brand brand);
  1. 编写SQL语句:SQL映射文件
<update id="update">update tb_brandset brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status}where id = #{id};</update>
  1. 编写测试样例
@Testpublic void testUpdate() throws IOException {//接收参数int status = 0;String companyName = "波导手机";String brandName = "波导";String description = "波导手机,手机中的战斗机666";int ordered = 200;int id = 4;//封装对象Brand brand = new Brand();brand.setStatus(status);brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setDescription(description);brand.setOrdered(ordered);brand.setId(id);//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//SqlSession sqlSession = sqlSessionFactory.openSession(true);//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法int count = brandMapper.update(brand);System.out.println(count);//提交事务sqlSession.commit();//5. 释放资源sqlSession.close();}
  1. 运行结果


10.修改–动态修改

  1. 操作步骤

(在修改的代码基础的基础上编码)
如果只传了密码,其他值不传,执行完其他值会变成null,这时需要动态字段解决该类问题

  1. 编写SQL语句:SQL映射文件
<update id="update">update tb_brand<set><if test="brandName != null and brandName != ''">brand_name = #{brandName},</if><if test="companyName != null and companyName != ''">company_name = #{companyName},</if><if test="ordered != null">ordered = #{ordered},</if><if test="description != null and description != ''">description = #{description},</if><if test="status != null">status = #{status}</if></set>where id = #{id};</update>
  1. 编写测试样例

  1. 运行结果


11.删除–删除单条记录

  1. 操作步骤

  1. 编写接口方法:Mapper接口
/** * 根据id删除 */void deleteById(int id);
  1. 编写SQL语句:SQL映射文件
<delete id="deleteById">delete from tb_brand where id = #{id};</delete>
  1. 编写测试样例
 @Testpublic void testDeleteByIds() throws IOException {//接收参数int id = 4;//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//SqlSession sqlSession = sqlSessionFactory.openSession(true);//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法brandMapper.deleteById(id);//提交事务sqlSession.commit();//5. 释放资源sqlSession.close();}
  1. 运行结果


12.删除–删除多条记录

  1. 操作步骤


2. 编写接口方法:Mapper接口

/** * 批量删除 */void deleteByIds(int[] ids);
  1. 编写SQL语句:SQL映射文件
<!--mybatis会将数组参数,封装为一个Map集合。* 默认:array = 数组* 使用@Param注解改变map集合的默认key的名称--><delete id="deleteByIds">delete from tb_brand where idin<foreach collection="array" item="id" separator="," open="(" close=")">#{id}</foreach>;</delete>
  1. 编写测试样例
 @Testpublic void testDeleteByIds() throws IOException {//接收参数int[] ids = {1,2};//1. 获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2. 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//SqlSession sqlSession = sqlSessionFactory.openSession(true);//3. 获取Mapper接口的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//4. 执行方法brandMapper.deleteByIds(ids);//提交事务sqlSession.commit();//5. 释放资源sqlSession.close();}
  1. 运行结果


13.mybatis注解开发

总结

欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)