持久层框架MyBatis
1. mybatis介绍
传统框架的缺点:
使用jdbc需要程序员创建连接,手写sql,处理结果集,使用了mybatis框架后,创建连接,结果集处理都由框架来完成。
mybatis它是轻量级持久层框架,由ibatis演化而来。它自动连接数据库,将数据库的结果集封装到对象中POJO。
2. 执行流程
Mybatis启动时:
读取application.yml中的数据库名称,username,password
读取所有xml
@mapperScan(“mapper”) ,为每个接口创建一个代理对象,放到spring容器中。
执行的流程:
Controller中通过autowired从spring容器中取到代理对象
catagoryMapper.selectByExample(),执行mybatis中的invoke(),连接数据库
得到方法名selectByExample,得到接口名,包名,namespace=包名+接口名,根据namespace找到xml文件
根据方法名找到sql语句
执行sql,得到resultSet
遍历,得到每一行数据,class.forname(实体类名),clazz.newInstance()(创建对象),把对象放到list中 return list
3. 使用步骤
使用逆向工程generater项目生成xml,接口,pojo,example
创建springboot项目,依赖web,mybatis,mysql driver
配置application.yml,配置数据库信息,xml的位置,日志log
Application添加 @MapperScan(“mapper包名”),mybatis框架会为包下的每个接口创建代理对象。
Controller通过@Autowried从spring容器中取到代理对象
代理对象有insert(),delete(),update(),查询用example,criteria(为每个列生成)
代码实现举例:商品分类CRUD操作
1、由逆向工程generater项目生成mapper.xml,接口,pojo,example
2、配置application.yml
1 server: 2 port: 8080 3 4 spring: 5 datasource: 6 driver-class-name: com.mysql.cj.jdbc.Driver 7 url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8 8 username: root 9 password: 123456 10 11 mybatis: 12 mapperLocations: classpath:com.tedu.mybatis01_crud.mapper/*.xml 13 14 logging: 15 path: ./logs 16 level: 17 com.tedu.mybatis01_crud.mapper: debug
Mybatis01CrudApplication.java
添加@MapperScan注解
1 package com.tedu.mybatis01_crud; 2 3 @SpringBootApplication 4 //@MapperScan:mybatis框架会自动为mapper包下的接口创建动态代理对象 5 //动态代理对象会自动连接数据库,找到sql,执行,把resultSet转成实体类 6 @MapperScan("com.tedu.mybatis01_crud.mapper") 7 public class Mybatis01CrudApplication { 8 9 public static void main(String[] args) { 10 SpringApplication.run(Mybatis01CrudApplication.class, args); 11 } 12 }
controller层
1 package com.tedu.mybatis01_crud.controller; 2 3 import java.util.List; 4 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.web.bind.annotation.CrossOrigin; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RestController; 9 10 import com.tedu.mybatis01_crud.mapper.CategoryMapper; 11 import com.tedu.mybatis01_crud.pojo.Category; 12 import com.tedu.mybatis01_crud.pojo.CategoryExample; 13 14 @RestController 15 @RequestMapping("/category") 16 public class CategoryController { 17 //接口没有实现类,mybatis框架会自动为mapper包下的所有接口创建代理类 18 //创建一个代理对象,把代理对象放到容器中 19 20 //从容器中取代理对象 21 @Autowired 22 CategoryMapper categoryMapper; 23 24 //添加 25 @RequestMapping("/insert") 26 @CrossOrigin 27 public String insert(Category category) { 28 return "添加的行="+categoryMapper.insert(category); 29 } 30 31 //修改 32 @RequestMapping("/update") 33 @CrossOrigin 34 public String update(Category category) { 35 //:8080/update?catagoryId=1&categoryName=笔记本 36 //:8080/selectDesc 37 //updateByPrimaryKey() 38 //updateByPrimaryKeySelective 属性为空,不生成desc=null 39 return "更新的行:"+categoryMapper.updateByPrimaryKeySelective(category); 40 } 41 42 //删除 43 @RequestMapping("/delete") 44 @CrossOrigin 45 public String delete(Integer categoryId) { 46 return "删除的行:"+categoryMapper.deleteByPrimaryKey(categoryId); 47 } 48 49 //升序 50 @RequestMapping("/selectAsc") 51 @CrossOrigin 52 public List<Category> selectAsc(){ 53 CategoryExample example = new CategoryExample(); 54 example.setOrderByClause("category_id asc"); 55 return categoryMapper.selectByExample(example); 56 } 57 58 //降序 59 @RequestMapping("selectDesc") 60 @CrossOrigin 61 public List<Category> selectDesc(){ 62 CategoryExample example = new CategoryExample(); 63 example.setOrderByClause("category_id desc"); 64 return categoryMapper.selectByExample(example); 65 } 66 67 //自动生成where 68 @RequestMapping("/selectByName") 69 @CrossOrigin 70 public List<Category> selectByName(String categoryName){ 71 CategoryExample example = new CategoryExample(); 72 example.setOrderByClause("category_id desc"); 73 //Criteria是CategoryExample中的内部类 74 //产生where语句 75 CategoryExample.Criteria criteria = example.or(); 76 criteria.andCategoryNameEqualTo(categoryName); 77 return categoryMapper.selectByExample(example); 78 } 79 80 @RequestMapping("/selectAll") 81 @CrossOrigin 82 public List<Category> selectAll(){ 83 System.out.println(categoryMapper); 84 return categoryMapper.selectByExample(null); 85 } 86 }
关联关系
Mybatis表现关联关系只有两种association(一对一)、collection(一对多),表现很简洁。
4.1 一对一
分析
代码实现
4.2 一对多
分析
代码实现
5. 参数占位符
mybatis本质就是拼接SQL语句。
#{name}
防止SQL注入;如果参数是一个字符串类型。chen 拼接SQL语句时会根据类型,自动加相关符号。例如字符串类型’chen’。
${orderby}
${} 原样输出,很危险,有SQL注入风险。
6. 复杂搜索
6.1 动态SQL语句
举例:
1 <mapper namespace="com.tedu.mybaits02_multiTableQuery.mapper.ItemMapper"> 2 <!-- resultType=集合中数据的类型 --> 3 <select id="selectByCategoryIdAndName" parameterType="com.tedu.mybaits02_multiTableQuery.pojo.Item" 4 resultType="com.tedu.mybaits02_multiTableQuery.pojo.Item"> 5 SELECT item_id as itemId,item_name as itemName,category_id as categoryId 6 from item 7 <where> 8 <if test="categoryId != null"> 9 category_id=#{categoryId} 10 </if> 11 <if test="itemName != null"> 12 AND item_name LIKE concat('%',#{itemName},'%') 13 </if> 14 </where> 15 </select> 16 </mapper>
6.2 集合参数
foreach的主要用在构建sql中的in条件中,它可以在SQL语句中进行迭代一个集合。
属性:
collection:表示传入的参数。该属性是必须指定
主要有以下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可
item:表示集合中每一个元素进行迭代时的别名。
open:表示该语句以什么开始
close:表示该语句以什么结束
separator:表示在每次进行迭代之间以什么符号作为分隔
1 <mapper namespace="com.tedu.mybaits02_multiTableQuery.mapper.ItemMapper"> 2 <select id="selectByList" parameterType="Integer" resultType="com.tedu.mybaits02_multiTableQuery.pojo.Item"> 3 SELECT item_id as itemId, 4 item_name as itemName, 5 category_id as categoryId 6 from item 7 <where> 8 <!-- itemId in (2,3) --> 9 item_id in 10 <foreach collection="list" item="itemId" open="(" separator="," close=")"> 11 #{itemId} 12 </foreach> 13 </where> 14 </select> 15 </mapper>
————————————————
版权声明:本文为CSDN博主「Like0217」的原创文章
原文链接:https://blog.csdn.net/weixin_46439070/article/details/109636528