• Mybatis---CRUD案例


    目录

    1.目标

    1.1环境准备

    1.1.1Maven环境的搭建

    1.1.2数据库表(tb_brand)及数据准备

    1.1.3创建实体类Brand

    1.1.4编写测试用例

    1.1.5安装MyBatisX插件

    1.2查询所有数据

    1.2.1编写接口方法

    1.2.2编写SQL语句

    1.2.3编写测试方法

    1.2.4起别名解决数据封装失败问题

    1.2.5使用resultMap解决上述问题

    1.2.6小结

     1.3查询详情

    1.3.1编写接口方法

    1.3.2编写SQL语句

    1.3.3编写测试方法

    1.3.4参数占位符

    1.3.5parameterType使用

    1.3.6SQL语句中特殊字段处理

     1.4多条件查询

    1.4.1编写接口方法

    1.4.2编写SQL语句

    1.4.3编写测试方法

     1.4.4动态SQL

    1.5单个条件(动态SQL)

    1.5.1编写接口方法

    1.5.2编写SQL语句

    1.5.3编写测试方法

     1.6添加数据

    1.6.1编写接口方法

    1.6.2编写SQL语句

    1.6.3编写测试方法

    1.6.4添加-主键返回

    1.7修改

    1.7.1编写接口方法

    1.7.2编写SQL语句

    1.7.3编写测试方法

    1.8删除一行数据

    1.8.1编写接口方法

    1.8.2编写SQL语句

    1.8.3编写测试方法

    1.9批量删除

    1.9.1编写接口方法

    1.9.2编写SQL语句

    1.9.3编写测试方法

    1.10Mybatis参数传递

    1.10.1多个参数

    1.11注解实现CRUD


    1.目标

    能够使用映射配置文件实现 CRUD 操作
    能够使用注解实现 CRUD 操作

    1.1环境准备

    1.1.1Maven环境的搭建

    文件👉Maven👉不勾选(从原型创建)👉下一步👉自主配置👉完成

    设置👉搜索maven👉选择版本,覆盖用户设置文件(settings.xml),覆盖本地存储库👉应用👉确定

     

     

    1.1.2数据库表(tb_brand)及数据准备

    1. -- 删除tb_brand表
    2. drop table if exists tb_brand;
    3. -- 创建tb_brand表
    4. create table tb_brand
    5. (
    6. -- id 主键
    7. id int primary key auto_increment,
    8. -- 品牌名称
    9. brand_name varchar(20),
    10. -- 企业名称
    11. company_name varchar(20),
    12. -- 排序字段
    13. ordered int,
    14. -- 描述信息
    15. description varchar(100),
    16. -- 状态:0:禁用 1:启用
    17. status int
    18. );
    19. -- 添加数据
    20. insert into tb_brand (brand_name, company_name, ordered, description, status)
    21. values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
    22. ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
    23. ('小米', '小米科技有限公司', 50, 'are you ok', 1);
    24. SELECT * FROM tb_brand;

    1.1.3创建实体类Brand

    1. package com.itheima.pojo;
    2. /**
    3. * 品牌
    4. *
    5. * alt + 鼠标左键:整列编辑
    6. *
    7. * 在实体类中,基本数据类型建议使用其对应的包装类型
    8. */
    9. public class Brand {
    10. // id 主键
    11. private Integer id;
    12. // 品牌名称
    13. private String brandName;
    14. // 企业名称
    15. private String companyName;
    16. // 排序字段
    17. private Integer ordered;
    18. // 描述信息
    19. private String description;
    20. // 状态:0:禁用 1:启用
    21. private Integer status;
    22. public Integer getId() {
    23. return id;
    24. }
    25. public void setId(Integer id) {
    26. this.id = id;
    27. }
    28. public String getBrandName() {
    29. return brandName;
    30. }
    31. public void setBrandName(String brandName) {
    32. this.brandName = brandName;
    33. }
    34. public String getCompanyName() {
    35. return companyName;
    36. }
    37. public void setCompanyName(String companyName) {
    38. this.companyName = companyName;
    39. }
    40. public Integer getOrdered() {
    41. return ordered;
    42. }
    43. public void setOrdered(Integer ordered) {
    44. this.ordered = ordered;
    45. }
    46. public String getDescription() {
    47. return description;
    48. }
    49. public void setDescription(String description) {
    50. this.description = description;
    51. }
    52. public Integer getStatus() {
    53. return status;
    54. }
    55. public void setStatus(Integer status) {
    56. this.status = status;
    57. }
    58. @Override
    59. public String toString() {
    60. return "Brand{" +
    61. "id=" + id +
    62. ", brandName='" + brandName + '\'' +
    63. ", companyName='" + companyName + '\'' +
    64. ", ordered=" + ordered +
    65. ", description='" + description + '\'' +
    66. ", status=" + status +
    67. '}';
    68. }
    69. }

    1.1.4编写测试用例

    测试代码需要在 test/java 目录下创建包及测试用例。项目结构如下:

     

    1.1.5安装MyBatisX插件

    MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
    主要功能:
    XML映射配置文件 和 接口方法 间相互跳转
    根据接口方法生成 statement
    安装方式:
    点击 file ,选择 settings ,就能看到如下图所示界面
    注意:安装完毕后需要重启 IDEA

    插件效果:

     

    红色头绳的表示映射配置文件蓝色头绳的表示 mapper 接口。在 mapper 接口点击红色头绳的小鸟图标会自动跳转到对应的映射配置文件,在映射配置文件中点击蓝色头绳的小鸟图标会自动跳转到对应的 mapper 接口。也可以在mapper 接口中定义方法,自动生成映射配置文件中的 statement ,如图所示:

     

    1.2查询所有数据

    步骤:

    1.编写接口方法: Mapper 接口
    2.参数:无
    查询所有数据功能是不需要根据任何条件进行查询的,所以此方法不需要参数。
    1. //在BrandMapper接口中创建该方法
    2. List selectAll();
    3. 结果: List
    我们会将查询出来的每一条数据封装成一个 Brand 对象,而多条数据封装多个 Brand 对象,需要将这些对象封装到 List 集合中返回。
    1. <select id="selectAll" resultType="brand">
    2. select * from tb_brand;
    3. select>
    4.执行方法、测试

    1.2.1编写接口方法

    com.itheima.mapper 包写创建名为 BrandMapper 的接口。并在该接口中定义 List selectAll() 方法。
    1. pubic interface BrandMapper{
    2. List selectAll();
    3. }

    1.2.2编写SQL语句

    reources 下创建 com/itheima/mapper 目录结构,并在该目录下创建名为 BrandMapper.xml 的映射配置文件
    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.itheima.mapper.BrandMapper">
    6. <select id="selectAll" resultMap="brandResultMap">
    7. select *
    8. from tb_brand;
    9. select>
    10. mapper>

    1.2.3编写测试方法

    在 MybatisTest 类中编写测试查询所有的方法

    1. @Test
    2. public void testSelectAll() throws IOException {
    3. //1. 获取SqlSessionFactory
    4. String resource = "mybatis-config.xml";
    5. InputStream inputStream = Resources.getResourceAsStream(resource);
    6. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    7. //2. 获取SqlSession对象
    8. SqlSession sqlSession = sqlSessionFactory.openSession();
    9. //3. 获取Mapper接口的代理对象
    10. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    11. //4. 执行方法
    12. List brands = brandMapper.selectAll();
    13. System.out.println(brands);
    14. //5. 释放资源
    15. sqlSession.close();
    16. }

    1.2.4起别名解决数据封装失败问题

    从上面结果可以看到 brandName companyName 这两个属性的数据没有封装成功,查询 实体类 和 表中的字段 发现,在实体类中属性名是 brandName companyName ,而表中的字段名为 brand_name company_name ,如下图所示 。那么我们只需要保持这两部分的名称一致这个问题就迎刃而解。

    方式一:as,我们可以在写sql语句时给这两个字段起别名,将别名定义成和属性名一致即可。

    1. <select id="selectAll" resultType="brand">
    2. select
    3. id, brand_name as brandName, company_name as companyName, ordered,description,status
    4. from tb_brand;
    5. select>

    方式二:SQL片段

    将需要复用的 SQL 片段抽取到 sql 标签中
    1. <sql id="brand_column">
    2. id, brand_name as brandName, company_name as companyName, ordered, description, status
    3. sql>
    id 属性值是唯一标识,引用时也是通过该值进行引用。
    在原 sql 语句中进行引用
    使用 include 标签引用上述的 SQL 片段,而 refid 指定上述 SQL 片段的 id
    1. <select id="selectAll" resultType="brand">
    2. select
    3. <include refid="brand_column" />
    4. from tb_brand;
    5. select>

    1.2.5使用resultMap解决上述问题

    起别名 + sql片段的方式 可以解决上述问题,但是它也存在问题。如果还有功能只需要查询部分字段,而不是查询所有字段,那么我们就需要再定义一个 SQL 片段,这就显得不是那么灵活。
    那么我们也可以使用 resultMap 来定义字段和属性的映射关系的方式解决上述问题。
    在映射配置文件中使用 resultMap 定义 字段 和 属性 的映射关系
    1. <resultMap id="brandResultMap" type="brand">
    2. <result column="brand_name" property="brandName"/>
    3. <result column="company_name" property="companyName"/>
    4. resultMap>

    SQL语句正常编写

    1. <select id="selectAll" resultMap="brandResultMap">
    2. select *
    3. from tb_brand;
    4. select>

    1.2.6小结

    实体类属性 和 数据库表列名不一致,不能自动封装数据
    起别名: SQL 语句中,对不一样的列名起别名,别名和实体类属性名一样
    可以定义 片段,提升复用性
    resultMap 定义完成不一致的属性名和列名的映射(as+SQL片段)
    而我们最终选择使用 resultMap 的方式。查询映射配置文件中查询所有的 statement 书写如下:
    1. <resultMap id="brandResultMap" type="brand">
    2. <result column="brand_name" property="brandName"/>
    3. <result column="company_name" property="companyName"/>
    4. resultMap>
    5. <select id="selectAll" resultMap="brandResultMap">
    6. select *
    7. from tb_brand;
    8. select>

    mybatis的主要思路:

    获取sqlSession对象,调用该对象中的getMapper()传入BrandMapper.Class参数即反射过去一个BrandMapper接口成为一个接口对象,该接口中有List selectAll();方法,该方法的方法名就是BrandMapper.xml映射文件中的id名(selectAll),然后sqlSession对象执行该映射文件中的sql语句,并且返回一个List集合,元素类型为Brand。

     1.3查询详情

    步骤:

    编写接口方法: Mapper 接口
    Brand SelectById(int id);

    参数:id

    查看详情就是查询某一行数据,所以需要根据id进行查询。而id以后是由页面传递过来。

    结果: Brand
    根据 id 查询出来的数据只要一条,而将一条数据封装成一个 Brand 对象即可
    编写 SQL 语句: SQL 映射文件
    1. <select id="selectById"parameterType="int" resultType="brand">
    2. select * from tb_brand where id = #{id};
    3. select>
    执行方法、进行测试

    1.3.1编写接口方法

    BrandMapper 接口中定义根据id查询数据的方法

    Brand selectById(int id);

    1.3.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写 statement ,使用 resultMap 而不是使用 resultType
    1. <select id="selectById" resultMap="brandResultMap">
    2. select * from tb_brand where id = #{id};
    3. select>

    1.3.3编写测试方法

    1. @Test
    2. public void testSelectById() throws IOException {
    3. //接收参数
    4. int id = 1;
    5. //1. 获取SqlSessionFactory
    6. String resource = "mybatis-config.xml";
    7. InputStream inputStream = Resources.getResourceAsStream(resource);
    8. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    9. //2. 获取SqlSession对象
    10. SqlSession sqlSession = sqlSessionFactory.openSession();
    11. //3. 获取Mapper接口的代理对象
    12. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    13. //4. 执行方法
    14. Brand brand = brandMapper.selectById(id);
    15. System.out.println(brand);
    16. //5. 释放资源
    17. sqlSession.close();
    18. }
    执行测试方法结果如下:

     

    1.3.4参数占位符

    查询到的结果很好理解就是 id 1 的这行数据。而这里我们需要看控制台显示的 SQL 语句,能看到使用?进行占位。说明我们在映射配置文件中的写的 #{id} 最终会被?进行占位。接下来我们就聊聊映射配置文件中的参数占位符。
    mybatis 提供了两种参数占位符:
    #{} :执行SQL时,会将 #{} 占位符替换为?,将来自动设置参数值。从上述例子可以看出使用#{} 底层使用的是 PreparedStatement。
    ${} :拼接SQL。底层使用的是 Statement ,会存在SQL注入问题。如下图将 映射配置文件中的 #{} 替换成 ${} 来看效果。
    1. <select id="selectById" resultMap="brandResultMap">
    2. select * from tb_brand where id = ${id};
    3. select>

     注意:从上面两个例子可以看出,以后开发我们使用 #{} 参数占位符。

    1.3.5parameterType使用

    对于有参数的 mapper 接口方法,我们在映射配置文件中应该配置 ParameterType 来指定参数类型。只不过该属性都可以
    省略。如下图:
    1. <select id="selectById" parameterType="int" resultMap="brandResultMap"> s
    2. elect * from tb_brand where id = ${id};
    3. select>

    1.3.6SQL语句中特殊字段处理

    可以看出报错了,因为映射配置文件是 xml 类型的问题,而 > < 等这些字符在 xml 中有特殊含义,所以此时我们需要将这些符号进行转义,可以使用以下两种方式进行转义。

     转义字符与

     1.4多条件查询

    步骤:

    编写接口方法
    参数:所有查询条件
    结果: List
    在映射配置文件中编写 SQL 语句
    编写测试方法并执行

    1.4.1编写接口方法

    BrandMapper 接口中定义多条件查询的方法。
    而该功能有三个参数,我们就需要考虑定义接口时,参数应该如何定义。 Mybatis 针对多参数有多种实现:
    方式一:使用 @Param(" 参数名称 ") 标记每一个参数,在映射配置文件中就需要使用 #{ 参数名称 } 进行占位。
    1. List selectByCondition(@Param("status") int status,
    2. @Param("companyName") String companyName,@Param("brandName") String brandName);

    方式二将多个参数封装成一个实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{} 时,里面的内容必须和实体类属性名保持一致。

    List selectByCondition(Brand brand);

    方式三将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和map集合中键的名称一致。

    List selectByCondition(Map map);

    1.4.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写 statement ,使用 resultMap 而不是使用 resultType。
    因为实体类属性名与数据库属性名不一致,故使用resultMap标签。
    1. <select id="selectByCondition" resultMap="brandResultMap">
    2. select *
    3. from tb_brand
    4. where status = #{status}
    5. and company_name like #{companyName}
    6. and brand_name like #{brandName}
    7. select>

    1.4.3编写测试方法

    test/java 下的 com.itheima.mapper 包下的 MybatisTest 类中 定义测试方法
    1. @Test
    2. public void testSelectByCondition() throws IOException {
    3. //接收参数
    4. int status = 1;
    5. String companyName = "华为";
    6. String brandName = "华为";
    7. // 处理参数
    8. companyName = "%" + companyName + "%";
    9. brandName = "%" + brandName + "%";
    10. //封装对象
    11. /* Brand brand = new Brand();
    12. brand.setStatus(status);
    13. brand.setCompanyName(companyName);
    14. brand.setBrandName(brandName);*/
    15. Map map = new HashMap();
    16. // map.put("status" , status);
    17. map.put("companyName", companyName);
    18. // map.put("brandName" , brandName);
    19. //1. 获取SqlSessionFactory
    20. String resource = "mybatis-config.xml";
    21. InputStream inputStream = Resources.getResourceAsStream(resource);
    22. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    23. //2. 获取SqlSession对象
    24. SqlSession sqlSession = sqlSessionFactory.openSession();
    25. //3. 获取Mapper接口的代理对象
    26. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    27. //4. 执行方法
    28. //List brands = brandMapper.selectByCondition(status, companyName, brandName);
    29. // List brands = brandMapper.selectByCondition(brand);
    30. List brands = brandMapper.selectByCondition(map);
    31. System.out.println(brands);
    32. //5. 释放资源
    33. sqlSession.close();
    34. }

     1.4.4动态SQL

    上述功能实现存在很大的问题。用户在输入条件时,肯定不会所有的条件都填写,这个时候我们的 SQL语句就不能那样写的。Mybatis 对动态 SQL 有很强大的支撑:

    标签一:if

    if 标签:条件判断
    test 属性:逻辑表达式
    1. <select id="selectByCondition" resultMap="brandResultMap">
    2. select *
    3. from tb_brand
    4. where
    5. <if test="status != null">
    6. and status = #{status}
    7. if>
    8. <if test="companyName != null and companyName != '' ">
    9. and company_name like #{companyName}
    10. if>
    11. <if test="brandName != null and brandName != '' ">
    12. and brand_name like #{brandName}
    13. if>
    14. select>
    这种SQL语句就会根据传递的参数值进行动态的拼接。但假设第一个if不成立,则第二个if中的and则会报错,则这时候可以使用where标签解决。

    标签二:where 标签

    作用:
    替换where关键字
    会动态的去掉第一个条件前的 and
    如果所有的参数没有值则不加where关键字
    1. <select id="selectByCondition" resultMap="brandResultMap">
    2. select *
    3. from tb_brand
    4. /* where 1 = 1*/
    5. <where>
    6. <if test="status != null">
    7. and status = #{status}
    8. if>
    9. <if test="companyName != null and companyName != '' ">
    10. and company_name like #{companyName}
    11. if>
    12. <if test="brandName != null and brandName != '' ">
    13. and brand_name like #{brandName}
    14. if>
    15. where>
    16. select>

    注意:需要给每个条件前都加上 and 关键字。

    1.5单个条件(动态SQL)

     

    在查询时只能选择 品牌名称 当前状态 企业名称 这三个条件中的一个,但是用户到底选择哪儿一个,我们并不能确定。这种就属于单个条件的动态 SQL语句。
    这种需求需要使用到 choose (when otherwise )标签 实现, 而 choose 标签类似于 Java 中的 switch 语句。
    方式三:choose(when,otherwise)
    作用:
     
    choose类似于switch
    when类似于case
    otherwise类似于default

    1.5.1编写接口方法

    BrandMapper 接口中定义单条件查询的方法。
    List selectByConditionSingle(Brand brand);

    1.5.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写 statement ,使用 resultMap 而不是使用 resultType
    1. <select id="selectByConditionSingle" resultMap="brandResultMap">
    2. select *
    3. from tb_brand
    4. <where>
    5. <choose>
    6. <when test="status != null">
    7. status = #{status}
    8. when>
    9. <when test="companyName != null and companyName != '' ">
    10. company_name like #{companyName}
    11. when>
    12. <when test="brandName != null and brandName != ''">
    13. brand_name like #{brandName}
    14. when>
    15. choose>
    16. where>
    17. select>

    1.5.3编写测试方法

    test/java 下的 com.itheima.mapper 包下的 MybatisTest 类中 定义测试方法
    1. @Test
    2. public void testSelectByConditionSingle() throws IOException {
    3. //接收参数
    4. int status = 1;
    5. String companyName = "华为";
    6. String brandName = "华为";
    7. // 处理参数
    8. companyName = "%" + companyName + "%";
    9. brandName = "%" + brandName + "%";
    10. //封装对象
    11. Brand brand = new Brand();
    12. //brand.setStatus(status);
    13. brand.setCompanyName(companyName);
    14. //brand.setBrandName(brandName);
    15. //1. 获取SqlSessionFactory
    16. String resource = "mybatis-config.xml";
    17. InputStream inputStream = Resources.getResourceAsStream(resource);
    18. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    19. //2. 获取SqlSession对象
    20. SqlSession sqlSession = sqlSessionFactory.openSession();
    21. //3. 获取Mapper接口的代理对象
    22. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    23. //4. 执行方法
    24. //List brands = brandMapper.selectByCondition(status, companyName, brandName);
    25. // List brands = brandMapper.selectByCondition(brand);
    26. List brands = brandMapper.selectByConditionSingle(brand);
    27. System.out.println(brands);
    28. //5. 释放资源
    29. sqlSession.close();
    30. }
    执行测试方法结果如下:

     1.6添加数据

    步骤:

    编写接口方法

    void add(Brand brand);

    参数:除了id之外的所有的数据。id对应的是表中主键值,而主键我们是 自动增长 生成的。

    编写 SQL 语句
    1. <insert id="add">
    2. insert into tb_brand (brand_name, company_name, ordered, description, status)
    3. values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
    4. insert>
    编写测试方法并执行

    1.6.1编写接口方法

    BrandMapper 接口中定义添加方法。
    void add(Brand brand);

    1.6.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写添加数据的 statement
    1. <insert id="add">
    2. insert into tb_brand (brand_name, company_name, ordered, description, status)
    3. values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
    4. insert>

    1.6.3编写测试方法

    test/java 下的 com.itheima.mapper 包下的 MybatisTest 类中 定义测试方法
    1. @Test
    2. public void testAdd() throws IOException {
    3. //接收参数
    4. int status = 1;
    5. String companyName = "波导手机";
    6. String brandName = "波导";
    7. String description = "手机中的战斗机";
    8. int ordered = 100;
    9. //封装对象
    10. Brand brand = new Brand();
    11. brand.setStatus(status);
    12. brand.setCompanyName(companyName);
    13. brand.setBrandName(brandName);
    14. brand.setDescription(description);
    15. brand.setOrdered(ordered);
    16. //1. 获取SqlSessionFactory
    17. String resource = "mybatis-config.xml";
    18. InputStream inputStream = Resources.getResourceAsStream(resource);
    19. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    20. //2. 获取SqlSession对象
    21. SqlSession sqlSession = sqlSessionFactory.openSession();
    22. //SqlSession sqlSession = sqlSessionFactory.openSession(true);
    23. //3. 获取Mapper接口的代理对象
    24. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    25. //4. 执行方法
    26. brandMapper.add(brand);
    27. //提交事务
    28. sqlSession.commit();
    29. //5. 释放资源
    30. sqlSession.close();
    31. }
    执行结果如下:

    ​注意:MyBatis框架是对JDBC的封装,MyBatis中的事务控制方式其本质也是JDBCsetAutoCommit()方法来设置事务提交的方式的。故需要手动提交事务,但也可以在
    SqlSession sqlSession = sqlSessionFactory.openSession(true);设置自动提交事务。

    1.6.4添加-主键返回

    在数据添加成功后,有时候需要获取插入数据库数据的主键(主键是自增长)。
    比如:添加订单和订单项,如下图就是京东上的订单

    订单数据存储在订单表中,订单项存储在订单项表中。
    添加订单数据
    我们将上面添加品牌数据的案例中映射配置文件里 statement 进行修改,如下
    1. <insert id="add" useGeneratedKeys="true" keyProperty="id">
    2. insert into tb_brand (brand_name, company_name, ordered, description, status)
    3. values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
    4. insert>
    insert 标签上添加如下属性:
    useGeneratedKeys:是够获取自动增长的主键值。 true 表示获取
    keyProperty 指定将获取到的主键值封装到哪儿个属性里
    通过以上两个属性的设定,可以将自增长的id绑定到对象brand上面,从而方便以后信息的获取

    1.7修改

    在修改页面,用户在该页面书写需要修改的数据,点击 提交 按钮,就会将数据库中对应的数据进行修改。注意一 点,如果哪儿个输入框没有输入内容,我们是将表中数据对应字段值替换为空白还是保留字段之前的值?答案肯定是保留之 前的数据。

    1.7.1编写接口方法

    BrandMapper 接口中定义修改方法。
    void update(Brand brand);
    上述方法参数 Brand 就是封装了需要修改的数据,而 id 肯定是有数据的,这也是和添加方法的区别。

    1.7.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写修改数据的 statement
    1. <update id="update">
    2. update tb_brand
    3. <set>
    4. <if test="brandName != null and brandName != ''">
    5. brand_name = #{brandName},
    6. if>
    7. <if test="companyName != null and companyName != ''">
    8. company_name = #{companyName},
    9. if>
    10. <if test="ordered != null">
    11. ordered = #{ordered},
    12. if>
    13. <if test="description != null and description != ''">
    14. description = #{description},
    15. if>
    16. <if test="status != null">
    17. status = #{status}
    18. if>
    19. set>
    20. where id = #{id};
    21. update>
    set 标签可以用于动态包含需要更新的列,忽略其它不更新的列。

    1.7.3编写测试方法

    test/java 下的 com.itheima.mapper 包下的 MybatisTest 类中 定义测试方法
    1. @Test
    2. public void testUpdate() throws IOException {
    3. //接收参数
    4. int status = 0;
    5. String companyName = "波导手机";
    6. String brandName = "波导";
    7. String description = "波导手机,手机中的战斗机";
    8. int ordered = 200;
    9. int id = 6;
    10. //封装对象
    11. Brand brand = new Brand();
    12. brand.setStatus(status);
    13. // brand.setCompanyName(companyName);
    14. // brand.setBrandName(brandName);
    15. // brand.setDescription(description);
    16. // brand.setOrdered(ordered);
    17. brand.setId(id);
    18. //1. 获取SqlSessionFactory
    19. String resource = "mybatis-config.xml";
    20. InputStream inputStream = Resources.getResourceAsStream(resource);
    21. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    22. //2. 获取SqlSession对象
    23. SqlSession sqlSession = sqlSessionFactory.openSession();
    24. //SqlSession sqlSession = sqlSessionFactory.openSession(true);
    25. //3. 获取Mapper接口的代理对象
    26. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    27. //4. 执行方法
    28. int count = brandMapper.update(brand);
    29. System.out.println(count);
    30. //提交事务
    31. sqlSession.commit();
    32. //5. 释放资源
    33. sqlSession.close();
    34. }
    执行测试方法结果如下:
    从结果中 SQL 语句可以看出,只修改了 status 字段值,因为我们给的数据中只给 Brand 实体对象的 status 属性设置值了。这就是 set 标签的作用。

    1.8删除一行数据

    通过主键 id 删除,因为 id 是表中数据的唯一标识。

    1.8.1编写接口方法

    BrandMapper 接口中定义根据 id 删除方法
    void deleteById(int id);

    1.8.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写删除一行数据的 statement
    1. <delete id="deleteById">
    2. delete from tb_brand where id=#{id};
    3. delete>

    1.8.3编写测试方法

    test/java 下的 com.itheima.mapper 包下的 MybatisTest 类中 定义测试方法
    1. @Test
    2. public void testDeleteById() throws IOException {
    3. //接收参数
    4. int id = 6;
    5. //1. 获取SqlSessionFactory
    6. String resource = "mybatis-config.xml";
    7. InputStream inputStream = Resources.getResourceAsStream(resource);
    8. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    9. //2. 获取SqlSession对象
    10. SqlSession sqlSession = sqlSessionFactory.openSession();
    11. //SqlSession sqlSession = sqlSessionFactory.openSession(true);
    12. //3. 获取Mapper接口的代理对象
    13. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    14. //4. 执行方法
    15. brandMapper.deleteById(id);
    16. //提交事务
    17. sqlSession.commit();
    18. //5. 释放资源
    19. sqlSession.close();
    20. }
    运行过程只要没报错,直接到数据库查询数据是否还存在。

    1.9批量删除

    同时删除多条数据

    1.9.1编写接口方法

    BrandMapper 接口中定义删除多行数据的方法。
    void deleteByIds(int [] ids);//参数是一个数组,数组中存储的是多条数据的id

    1.9.2编写SQL语句

    BrandMapper.xml 映射配置文件中编写删除多条数据的 statement
    编写 SQL 时需要遍历数组来拼接 SQL 语句。 Mybatis 提供了 foreach 标签供我们使用
    foreach 标签
    用来迭代任何可迭代的对象(如数组,集合)。
    1.collection 属性:
    mybatis 会将数组参数,封装为一个 Map 集合。
    默认: array = 数组
    使用 @Param 注解改变 map 集合的默认 key 的名称(arg0...)
    2.item 属性:本次迭代获取到的元素。
    3.separator 属性:集合项迭代之间的分隔符。 foreach 标签不会错误地添加多余的分隔符。也就是 最后一次迭代不会加 分隔符。
    4.open 属性:该属性值是在拼接 SQL 语句之前拼接的语句,只会拼接一次
    5.close 属性:该属性值是在拼接 SQL 语句拼接后拼接的语句,只会拼接一次
    1. <delete id="deleteByIds">
    2. delete from tb_brand where id
    3. in
    4. <foreach collection="array" item="id" separator="," open="(" close=")">
    5. #{id}
    6. foreach>
    7. ;
    8. delete>

    1.9.3编写测试方法

    test/java 下的 com.itheima.mapper 包下的 MybatisTest 类中 定义测试方法
    1. @Test
    2. public void testDeleteByIds() throws IOException {
    3. //接收参数
    4. int[] ids = {5,7,8};
    5. //1. 获取SqlSessionFactory
    6. String resource = "mybatis-config.xml";
    7. InputStream inputStream = Resources.getResourceAsStream(resource);
    8. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    9. //2. 获取SqlSession对象
    10. SqlSession sqlSession = sqlSessionFactory.openSession();
    11. //SqlSession sqlSession = sqlSessionFactory.openSession(true);
    12. //3. 获取Mapper接口的代理对象
    13. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    14. //4. 执行方法
    15. brandMapper.deleteByIds(ids);
    16. //提交事务
    17. sqlSession.commit();
    18. //5. 释放资源
    19. sqlSession.close();
    20. }

    1.10Mybatis参数传递

    Mybatis 接口方法中可以接收各种各样的参数,如下:
    多个参数
    单个参数:单个参数又可以是如下类型:
            POJO 类型
            Map 集合类型
            Collection 集合类型
            
            List 集合类型
            Array 类型
            其他类型

    1.10.1多个参数

    如下面的代码,就是接收两个参数,而接收多个参数需要使用 @Param 注解,那么为什么要加该注解呢?这个问题要弄明白就必须来研究 Mybatis 底层对于这些参数是如何处理的。
    User select(@Param("username") String username,@Param("password") String password);
    1. <select id="select" resultType="user">
    2. select *
    3. from tb_user
    4. where
    5. username=#{username}
    6. and password=#{password}
    7. select>
    我们在接口方法中定义多个参数, Mybatis 会将这些参数封装成 Map 集合对象,值就是参数值,而键在没有使用 @Param注解时有以下命名规则:
    arg 开头 :第一个参数就叫 arg0 ,第二个参数就叫 arg1 ,以此类推。如:

    map.put("arg0" ,参数值 1);
    map.put("arg1" ,参数值 2);
    param 开头 : 第一个参数就叫 param1 ,第二个参数就叫 param2 ,依次类推。如:

    map.put("param1" ,参数值 1);
    map.put("param2" ,参数值 2);
    在映射配合文件的SQL语句中使用用 arg 开头的和 param 书写,代码的可读性会变的特别差,此时可以使用 @Param注解。在接口方法参数上使用 @Param 注解,Mybatis 会将 arg 开头的键名替换为对应注解的属性值。
    结论:以后接口参数是多个时,在每个参数上都使用 @Param 注解。这样代码的可读性更高。
    1.10.2单个参数
    POJO 类型
    直接使用。要求 属性名 参数占位符名称 一致
    Map 集合类型
    直接使用。要求 map集合的键名 参数占位符名称 一致
    Collection 集合类型
    Mybatis 会将集合封装到 map 集合中,如下:
    map.put("arg0" collection 集合 );
    map.put("collection" collection 集合 ;
    可以使用 @Param 注解替换 map 集合中默认的 arg 键名。
    List 集合类型
    Mybatis 会将集合封装到 map 集合中,如下:
    map.put("arg0" list 集合 );
    map.put("collection" list 集合 );
    map.put("list" list 集合 );
    可以使用 @Param 注解替换 map 集合中默认的 arg 键名。
    Array 类型
    Mybatis 会将集合封装到 map 集合中,如下:
    map.put("arg0" ,数组 );
    map.put("array" ,数组 );
    可以使用 @Param 注解替换 map 集合中默认的 arg 键名。
    其他类型

    比如int类型, 参数占位符名称 叫什么都可以。尽量做到见名知意

    1.11注解实现CRUD

    使用注解开发会比配置文件开发更加方便。如下就是使用注解进行开发
    1. @Select(value = "select * from tb_user where id = #{id}")
    2. public User select(int id);
    Mybatis 针对 CURD 操作都提供了对应的注解,已经做到见名知意。如下:
    查询 : @Select
    添加 : @Insert
    修改 : @Update
    删除 : @Delete

     总结:注解完成简单功能,配置文件完成复杂功能。

  • 相关阅读:
    CVPR 2018 基于累积注意力的视觉定位 Visual Grounding via Accumulated Attention 详解
    大饼简记.
    Windows Server 2008安装.NET Framework 3.5
    POS系统完整体系的介绍 Pos终端主密钥MK、DUKPT、PEK、DEK、MEK、TUSN的含义 ---安全行业基础篇7
    分布式任务调度平台XXL-JOB安装及使用
    windows机器配置自签名ssl证书,部署文件服务器
    Collection集合 迭代器 增强for List集合 LinkedList集合详解
    SSM框架学习——Spring之核心容器总结
    Vue学习之--------消息订阅和发布、基础知识和实战应用(2022/8/24)
    STM32--人体红外感应开关
  • 原文地址:https://blog.csdn.net/weixin_65440201/article/details/126445567