0


MyBatis 核心文件配置并完成CRUD。

一、MyBatis 配置

1、核心配置文件

▶ 官网上可以看配置

** 注意:配置各个标签需要遵循官网的配置顺序,否则会报错。**

▶ 环境配置

2、配置别名


二、配置文件完成CRUD

1、查询操作

▶ 查询所有数据

▷ 书写步骤

  1. 编写接口方法:Mapper接口
  2. * 参数:无,(查询所有数据功能是不需要根据任何条件进行查询的,所以此方法不需要参数)。

  1. * 结果:List<Brand> ,(我们会将查询出来的每一条数据封装成一个 `Brand` 对象,而多条数据封装多个 `Brand` 对象,需要将这些对象封装到List集合中返回)。
  2. * 编写SQL语句:SQL映射文件

  1. * 执行方法、测试

** ▷ 编写接口**

  1. `com.itheima.mapper` 包写创建名为 `BrandMapper` 的接口。并在该接口中定义 `List<Brand> selectAll()` 方法。自己写的时候注意接口的位置写到什么地方。
  1. public interface BrandMapper {
  2. List<Brand> selectAll();
  3. }

▷ 编写SQL语句

  1. `reources` 下创建 `com/itheima/mapper` 目录结构,并在该目录下创建名为 `BrandMapper.xml` 的映射配置文件。自己写的时候找到对应的SQL书写映射文件。
  1. <mapper namespace="com.itheima.mapper.BrandMapper">
  2. <select id="selectAll" resultType="brand">
  3. select *
  4. from tb_brand;
  5. </select>
  6. </mapper>

▷ 测试方法

  1. `MybatisTest` 类中编写测试查询所有的方法,在测试类中进行测试。
  1. public void testSelectAll() throws IOException {
  2. //1. 获取SqlSessionFactory
  3. String resource = "mybatis-config.xml";
  4. InputStream inputStream = Resources.getResourceAsStream(resource);
  5. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  6. //2. 获取SqlSession对象
  7. SqlSession sqlSession = sqlSessionFactory.openSession();
  8. //3. 获取Mapper接口的代理对象
  9. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
  10. //4. 执行方法
  11. List<Brand> brands = brandMapper.selectAll();
  12. System.out.println(brands);
  13. //5. 释放资源
  14. sqlSession.close();
  15. }

** ▷ 执行结果**

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

** ▷ 解决方式**

  1. **数据库表的字段名称 实体类的属性名称 不一样,则不能自动封装数据:
  2. ①起别名:对不一样的列名起别名,让别名和实体类的属性名一样。缺点:每次查询都要定义一次别名**
  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>
  1. **sql片段,缺点:不灵活**
  1. <sql id="brand_column">
  2. id, brand_name as brandName, company_name as companyName, ordered, description, status
  3. </sql>
  4. <select id="selectAll" resultType="brand">
  5. select
  6. <include refid="brand_column" />
  7. from tb_brand;
  8. </select>
  1. **②resultMap
  2. 1. 定义<resultMap>标签
  3. 2. 在<select>标签中,使用resultMap属性替换 resultType属性**
  1. <!-- id:唯一标识,type:映射的类型,支持别名 -->
  2. <resultMap id="brandResultMap" type="brand">
  3. <result column="brand_name" property="brandName"/>
  4. <result column="company_name" property="companyName"/>
  5. </resultMap>
  6. <select id="selectAll" resultMap="brandResultMap">
  7. select *
  8. from tb_brand;
  9. </select>
  1. ** id:完成主键字段的映射
  2. column:表的列名
  3. property:实体类的属性名
  4. result:完成一般字段的映射
  5. column:表的列名
  6. property:实体类的属性名**

▶ 查询详情

▷ 编写步骤

编写接口方法:Mapper接口

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

  1. * 结果:Brand
  2. 根据id查询出来的数据只要一条,而将一条数据封装成一个Brand对象即可
  3. * 编写SQL语句:SQL映射文件

  1. * 执行方法、进行测试

** ▷ 编写接口**

  1. Brand selectById(int id);

** ▷ 编写SQL语句**

  1. <select id="selectById" resultMap="brandResultMap">
  2. select * from tb_brand
  3. where id = #{id};
  4. </select>

** ▷ 测试方法**

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

▷ 参数占位符
1. #{}: 会将其替换为 ?,为了防止SQL注入
2. ${}:拼sql。会存在SQL注入问题
3. 使用时机:
* 参数传递的时候:#{}
* 表名或者列名不固定的情况下:${} 会存在SQL注入问题

  1. 4.参数类型:parameterType:可以省略
  2. 5.特殊字符处理:(比如:<
  3. * 转义字符:&lt;
  4. * CDATA : <![CDATA[ < ]]>

▶ 多条件查询

** ▷ 书写步骤**

  1. 1、编写接口方法
  2. * 参数:所有查询条件
  3. * 结果:List<Brand>
  4. 2、在映射配置文件中编写SQL语句
  5. 3、编写测试方法并执行

▷ 编写接口

①使用 @Param("参数名称") 标记每一个参数,在映射配置文件中就需要使用 #{参数名称} 进行占位

  1. List<Brand> selectByCondition(@Param("status") int status,
  2. @Param("companyName") String companyName,
  3. @Param("brandName") String brandName);

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

  1. List<Brand> selectByCondition(Brand brand);

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

  1. List<Brand> selectByCondition(Map map);

** ▷ 编写SQL语句**

  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. public void testSelectByCondition() throws IOException {
  2. //接收参数
  3. int status = 1;
  4. String companyName = "华为";
  5. String brandName = "华为";
  6. // 处理参数
  7. companyName = "%" + companyName + "%";
  8. brandName = "%" + brandName + "%";
  9. //1. 获取SqlSessionFactory
  10. String resource = "mybatis-config.xml";
  11. InputStream inputStream = Resources.getResourceAsStream(resource);
  12. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  13. //2. 获取SqlSession对象
  14. SqlSession sqlSession = sqlSessionFactory.openSession();
  15. //3. 获取Mapper接口的代理对象
  16. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
  17. //4. 执行方法
  18. List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
  19. System.out.println(brands);
  20. //5. 释放资源
  21. sqlSession.close();
  1. //封装对象
  2. Brand brand = new Brand();
  3. brand.setStatus(status);
  4. brand.setCompanyName(companyName);
  5. brand.setBrandName(brandName);
  6. //4.执行方法
  7. List<Brand> brands = brandMapper.selectByCondition(brand);
  1. Map map = new HashMap();
  2. map.put("status" , status);
  3. map.put("companyName", companyName);
  4. map.put("brandName" , brandName);
  5. //4.执行方法
  6. List<Brand> brands = brandMapper.selectByCondition(map);

** ▷ 动态SQL**

① 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>

② where 标签,作用: 替换where关键字, 会动态的去掉关键字 ,* 如果所有的参数没有值则不加where关键字**

  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. </where>
  15. </select>

▶ 单个条件的动态SQL

** ▷ 编写接口**

  1. List<Brand> selectByConditionSingle(Brand brand);

** ▷ 编写SQL**

  1. <select id="selectByConditionSingle" resultMap="brandResultMap">
  2. select *
  3. from tb_brand
  4. <where>
  5. <choose><!--相当于switch-->
  6. <when test="status != null"><!--相当于case-->
  7. status = #{status}
  8. </when>
  9. <when test="companyName != null and companyName != '' "><!--相当于case-->
  10. company_name like #{companyName}
  11. </when>
  12. <when test="brandName != null and brandName != ''"><!--相当于case-->
  13. brand_name like #{brandName}
  14. </when>
  15. </choose>
  16. </where>
  17. </select>

** ▷ 测试方法**

  1. public void testSelectByConditionSingle() throws IOException {
  2. //接收参数
  3. int status = 1;
  4. String companyName = "华为";
  5. String brandName = "华为";
  6. // 处理参数
  7. companyName = "%" + companyName + "%";
  8. brandName = "%" + brandName + "%";
  9. //封装对象
  10. Brand brand = new Brand();
  11. brand.setCompanyName(companyName);
  12. //1. 获取SqlSessionFactory
  13. String resource = "mybatis-config.xml";
  14. InputStream inputStream = Resources.getResourceAsStream(resource);
  15. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  16. //2. 获取SqlSession对象
  17. SqlSession sqlSession = sqlSessionFactory.openSession();
  18. //3. 获取Mapper接口的代理对象
  19. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
  20. //4. 执行方法
  21. List<Brand> brands = brandMapper.selectByConditionSingle(brand);
  22. System.out.println(brands);
  23. //5. 释放资源
  24. sqlSession.close();
  25. }

2、添加操作

** ▶ 编写接口**

  1. void add(Brand brand);

** ▶ 编写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. public void testAdd() throws IOException {
  2. //接收参数
  3. int status = 1;
  4. String companyName = "波导手机";
  5. String brandName = "波导";
  6. String description = "手机中的战斗机";
  7. int ordered = 100;
  8. //封装对象
  9. Brand brand = new Brand();
  10. brand.setStatus(status);
  11. brand.setCompanyName(companyName);
  12. brand.setBrandName(brandName);
  13. brand.setDescription(description);
  14. brand.setOrdered(ordered);
  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. brandMapper.add(brand);
  25. //提交事务
  26. sqlSession.commit();
  27. //5. 释放资源
  28. sqlSession.close();
  29. }

▶ 主键返回

  1. 在数据添加成功后,有时候需要获取插入数据库数据的主键(主键是自增长)。比如:
  • 添加订单数据

  • 添加订单项数据,订单项中需要设置所属订单的id

  1. 更改SQL
  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>
  1. insert 标签上添加如下属性:
  2. * useGeneratedKeys:是够获取自动增长的主键值。true表示获取
  3. * keyProperty :指定将获取到的主键值封装到哪儿个属性里

3、修改操作

** ▶ 编写接口**

  1. void update(Brand brand);

** ▶ 编写SQL**

  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>

** ▶ 测试方法**

  1. public void testUpdate() throws IOException {
  2. //接收参数
  3. int status = 0;
  4. int id = 6;
  5. //封装对象
  6. Brand brand = new Brand();
  7. brand.setStatus(status);
  8. brand.setId(id);
  9. //1. 获取SqlSessionFactory
  10. String resource = "mybatis-config.xml";
  11. InputStream inputStream = Resources.getResourceAsStream(resource);
  12. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  13. //2. 获取SqlSession对象
  14. SqlSession sqlSession = sqlSessionFactory.openSession();
  15. //3. 获取Mapper接口的代理对象
  16. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
  17. //4. 执行方法
  18. int count = brandMapper.update(brand);
  19. System.out.println(count);
  20. //提交事务
  21. sqlSession.commit();
  22. //5. 释放资源
  23. sqlSession.close();
  24. }

4、删除操作

▶ 单行删除

** ▷ 编写接口**

  1. void deleteById(int id);

** ▷ 编写SQL**

  1. <delete id="deleteById">
  2. delete from tb_brand where id = #{id};
  3. </delete>

** ▷ 测试方法**

  1. public void testDeleteById() throws IOException {
  2. //接收参数
  3. int id = 6;
  4. //1. 获取SqlSessionFactory
  5. String resource = "mybatis-config.xml";
  6. InputStream inputStream = Resources.getResourceAsStream(resource);
  7. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  8. //2. 获取SqlSession对象
  9. SqlSession sqlSession = sqlSessionFactory.openSession();
  10. //SqlSession sqlSession = sqlSessionFactory.openSession(true);
  11. //3. 获取Mapper接口的代理对象
  12. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
  13. //4. 执行方法
  14. brandMapper.deleteById(id);
  15. //提交事务
  16. sqlSession.commit();
  17. //5. 释放资源
  18. sqlSession.close();
  19. }

▶ 批删除除

** ▷ 编写接口**

  1. void deleteByIds(int[] ids);

** ▷ 编写SQL:foreach 标签**

用来迭代任何可迭代的对象(如数组,集合):

①collection 属性:
* mybatis会将数组参数,封装为一个Map集合。
* 默认:array = 数组
* 使用@Param注解改变map集合的默认key的名称
②item 属性:本次迭代获取到的元素。
③separator 属性:集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。
④open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次
⑤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. public void testDeleteByIds() throws IOException {
  2. //接收参数
  3. int[] ids = {5,7,8};
  4. //1. 获取SqlSessionFactory
  5. String resource = "mybatis-config.xml";
  6. InputStream inputStream = Resources.getResourceAsStream(resource);
  7. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  8. //2. 获取SqlSession对象
  9. SqlSession sqlSession = sqlSessionFactory.openSession();
  10. //SqlSession sqlSession = sqlSessionFactory.openSession(true);
  11. //3. 获取Mapper接口的代理对象
  12. BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
  13. //4. 执行方法
  14. brandMapper.deleteByIds(ids);
  15. //提交事务
  16. sqlSession.commit();
  17. //5. 释放资源
  18. sqlSession.close();
  19. }

5、MyBatis参数传递

▶ 多个参数

我们在接口方法中定义多个参数,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);

① 验证一:

接口:

  1. User select(String username,String password);

SQL:

  1. <select id="select" resultType="user">
  2. select *
  3. from tb_user
  4. where
  5. username=#{arg0}
  6. and password=#{arg1}
  7. </select>

  1. <select id="select" resultType="user">
  2. select *
  3. from tb_user
  4. where
  5. username=#{param1}
  6. and password=#{param2}
  7. </select>

结果:

② 验证二:

  1. 将接口更改:
  1. User select(@Param("username") String username, String password);
  1. 则会看到下列运行结果

结论:以后接口参数是多个时,在每个参数上都使用 @Param 注解。这样代码的可读性更高。

▶ 单个参数

▷ POJO 类型

  1. 直接使用。要求 `属性名` `参数占位符名称` 一致

▷ Map 集合类型

  1. 直接使用。要求 `map集合的键名` `参数占位符名称` 一致

▷ Collection 集合类型

  1. Mybatis 会将集合封装到 map 集合中,如下:
  2. * map.put("arg0"collection集合);
  3. * map.put("collection"collection集合;
  4. ==》可以使用 `@Param` 注解替换map集合中默认的 arg 键名。

▷ List 集合类型

  1. Mybatis 会将集合封装到 map 集合中,如下:
  2. * map.put("arg0"list集合);
  3. * map.put("collection"list集合);
  4. * map.put("list"list集合);
  5. ==》可以使用 `@Param` 注解替换map集合中默认的 arg 键名。

▷ Array 类型

  1. Mybatis 会将集合封装到 map 集合中,如下:
  2. * map.put("arg0",数组);
  3. * map.put("array",数组);
  4. ==》可以使用 `@Param` 注解替换map集合中默认的 arg 键名。==

▷ 其他类型

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

三、注解实现CRUD

▷ 注解实现

  1. @Select(value = "select * from tb_user where id = #{id}")
  2. public User select(int id);

▷ 注意

  1. 注解是用来替换映射配置文件方式配置的,所以使用了注解,就不需要再映射配置文件中书写对应的 `statement`

▷ Mybatis 针对 CURD 操作都提供了对应的注解。如下:

  1. 查询 @Select
  2. 添加 @Insert
  3. 修改 @Update
  4. 删除 @Delete

** ▷ 注解实现方式**

在接口中直接这样写:

  1. @Select(value = "select * from tb_user where id = #{id}")
  2. public User select(int id);

而编写SQL语句的那个配置文件就不需要在写SQL语句了。

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

标签: mybatis java mysql

本文转载自: https://blog.csdn.net/yzh2776680982/article/details/126728008
版权归原作者 小黎的培培笔录 所有, 如有侵权,请联系我们删除。

“MyBatis 核心文件配置并完成CRUD。”的评论:

还没有评论