邯郸网站建设提供商,建筑培训,顺德人才市场招聘信息,php网站安装说明书MyBatis 中使用XML映射文件
什么是XML映射
使用注解的映射SQL的问题#xff1a;
长SQL需要折行#xff0c;不方便维护动态SQL查询拼接复杂源代码中的SQL#xff0c;不方便与DBA协作
MyBatis建议使用XML文件映射SQL才能最大化发挥MySQL的功能
统一管理SQL#xff0c; 方…MyBatis 中使用XML映射文件
什么是XML映射
使用注解的映射SQL的问题
长SQL需要折行不方便维护动态SQL查询拼接复杂源代码中的SQL不方便与DBA协作
MyBatis建议使用XML文件映射SQL才能最大化发挥MySQL的功能
统一管理SQL 方便协作不需要 “ ” 等语法方便“长”SQL方便处理动态SQL连接
参考连接 https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
HelloWorld
开发步骤
创建项目不要使用Spring Boot 3, 选择依赖 配置application.properties, 设置数据库连接 spring.datasource.urljdbc:mysql://localhost:3306/bootdb?characterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghairewriteBatchedStatementstrue
spring.datasource.usernameroot
spring.datasource.passwordroot# 设定 mapper xml 文件的位置, classpath 就是指 resources 位置
mybatis.mapper-locationsclasspath:mappers/*.xml
# 查看MyBatis执行的SQL
logging.level.cn.tedu.boot2209.mapperdebug创建文件夹 /resources/mappers 添加一个XML文件文件从doc.canglaoshi.org 下载 改名为 DemoMapper.xml ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
!-- namespace 的值设定为被映射的包名.类名 --
mapper namespacecn.tedu.boot2209.mapper.DemoMapper!-- select 元素用于映射查询语句到方法id值必须和mapper接口中的方法名一致需要设定返回值类型resultType类型与方法返回值类型一致select 元素中定义SQLSQL查询结果将自动映射到方法返回值 不要使用分号结尾--select idhello resultTypejava.lang.StringSELECT Hello World!/select
/mapper 创建mapper.DemoMapper接口: 接口名和 xml文件的namespace 一致方法名和xml文件的select元素的id一致方法返回值类型和 resultType 的值一致 /*** 编写Mapper接口用于映射SQL语句*/
Mapper
public interface DemoMapper {String hello();
}编写MyBatis配置文件 config.MyBatisConfig 包名、文件名没有限制文件中使用 MapprScan 扫描 Mapper包
/*** 创建一个配置文件MyBatisConfig* 在配置文件中启动Mapper接口扫描功能* Mapper 接口扫描功能会自动创建 Mapper接口的实现对象使用的JDK动态代理技术*/
MapperScan(basePackages cn.tedu.boot2209.mapper)
Configuration
public class MyBatisConfig {
}测试案例: 测试结果说明SQL被执行了方法返回了SQL语句的结果 SpringBootTest
public class DemoMapperTests {AutowiredDemoMapper demoMapper;Testvoid test(){String str demoMapper.hello();System.out.println(str);}
}Spring Boot 中的配置类配置文件
Configuration 用于声明新的配置文件类。
Spring Boot 中的主配置文件就是Spring Boot 的启动类可以作为配置文件使用。如果将全部配置信息放到主配置文件就会很混乱。一般在开发中将配置文件分开放置相关的放到一起。
MyBatis 放到一个文件中安全配置放到一个文件中… …
创建一个配置包 config 管理全部的配置然后创建MyBatis的配置类, 配置类需要标注 Configuration
/*** 创建一个配置文件MyBatisConfig* 在配置文件中启动Mapper接口扫描功能* Mapper 接口扫描功能会自动创建 Mapper接口的实现对象使用的JDK动态代理技术*/
MapperScan(basePackages cn.tedu.boot2209.mapper)
Configuration
public class MyBatisConfig {
}MyBatis XML映射文件工作原理 关于XML语法
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecn.tedu.boot2209.mapper.ProductMapperselect idcountProduct resultTypejava.lang.IntegerSELECT COUNT(*) FROM product/select
/mapper处理节点 ?xml version1.0 encodingUTF-8 ? 从来没有变过 可以省略但是不建议省略 文档定义 ”DOCTYPE“ 用于约定XML文件中的 元素、属性、嵌套关系 可以约束标签和属性 标签/标记 mapper 必须成对使用有开启标签就必须结束标签 mapper/mapper 开始标签上可以定义属性 idcountProduct 属性名不可以重复属性无顺序 XML文件只能有唯一的根元素XML 可扩展的标记语言 标签可以任意名称标签名可以扩展标签嵌套关系可以扩展标签可以任意嵌套属性可以扩展 XML 中大小写敏感不同
有参数的查询
处理一个参数查询
例子
SELECT count(*) FROM product WHERE price ?处理多个参数查询 处理实体类型返回值
使用 Product 实体类作为返回值 在resultType上指定实体类型就可以了 desc product;
---------------------------------------------------------
| Field | Type | Null | Key | Default | Extra |
---------------------------------------------------------
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(50) | YES | | NULL | |
| price | double(10,2) | YES | | NULL | |
| num | int(11) | YES | | NULL | |
---------------------------------------------------------定义实体类型 Product
/*** 产品实体类型*/
public class Product {private Integer id;private String title;private Double price;private Integer quantity; //数量public Product() {}public Product(Integer id, String title, Double price, Integer quantity) {this.id id;this.title title;this.price price;this.quantity quantity;}public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getTitle() {return title;}public void setTitle(String title) {this.title title;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price price;}public Integer getQuantity() {return quantity;}public void setQuantity(Integer quantity) {this.quantity quantity;}Overridepublic String toString() {return Product{ id id , title title \ , price price , quantity quantity };}
}编写ProductMapper接口方法
/*** 根据ID返回一个对象*/
Product findById(Integer id);编写映射文件 ProductMapper.xml
select idfindById resultTypecn.tedu.boot2209.entity.ProductSELECT id, title, price, num AS quantityFROM productWHERE id #{id}
/select测试ProductMapperTests
Test
void findById(){Product product productMapper.findById(4);System.out.println(product);
}返回实体集合
在ProductMapper接口中添加方法
/*** 返回一组实体对象* param title %手机* return 匹配的一组对象*/
ListProduct findByTitle(String title);在 ProductMapper.xml 添加SQL语句
!-- 返回一组实体对象必须有 resultType 值是返回集合中的元素类型--
select idfindByTitle resultTypecn.tedu.boot2209.entity.ProductSELECT id, title, price, num AS quantityFROM productWHERE title LIKE #{title}
/select测试方法 ProductMapperTests
Test
void findByTitle(){ListProduct products productMapper.findByTitle(%手机);for (Product product : products){System.out.println(product);}
}插入和更新
使用变量传递参数
参数少没有问题但是参数多了以后就麻烦了书写繁琐复杂
插入数据SQL
INSERT INTO product (id, title, price, num ) VALUES (null, ?, ? ,?)ProductMapper接口插入、更新、删除方法只有一个默认返回int值表示SQL影响行数
Integer saveProduct(Param(title) String title,Param(price) Double price,Param(quantity) Integer quantity);在MyBatis ProductMapper.xml:
!-- insert 插入语句不需要定义 resultType默认就有int返回值 --
insert idsaveProductINSERT INTO product (id, title, price, num ) VALUES (null, #{title}, #{price}, #{quantity})
/insert测试ProductMapperTests
Test
void saveProduct(){Integer n productMapper.saveProduct(大力手机, 2000.0, 100);System.out.println(n);
}使用POJO对象打包传递参数
POJO 就是传统Java对象实体对象 Product 对象就是 POJO。 使用POJO对象作为Mapper方法参数: ProductMapper, 无需定义Parm
Integer saveProductItem(Product product);MyBatis 自动将POJO对象的属性 映射传递到 #{占位符}
!-- MyMatis 会自动的将 product 的属性 映射到#{title}, #{price}, #{quantity}要求 #{title}, #{price}, #{quantity} 占位符必须和 product 的属性getXXX一致--
insert idsaveProductItemINSERT INTO product (id, title, price, num ) VALUES (null, #{title}, #{price}, #{quantity})
/insert测试
Test
void saveProductItem(){Product product new Product(null, 大力手机, 2000.0, 100);Integer n productMapper.saveProductItem(product);System.out.println(n);
}返回自动增加的ID
使用POJO作为参数插入数据时候可以返回自增的ID
useGeneratedKeys“true” 使用生成的keykeyProperty“id” key 的属性名
!-- useGeneratedKeystrue 使用生成的keykeyPropertyid key 的属性名 --
insert idsaveProductItem useGeneratedKeystrue keyPropertyidINSERT INTO product (id, title, price, num)VALUES (null, #{title}, #{price}, #{quantity})
/insert测试
Test
void saveProductItem(){Product product new Product(null, 他的手机, 3000.0, 100);Integer n productMapper.saveProductItem(product);System.out.println(n);System.out.println(product); //输出刚刚生成的 ID
}更新数据 update
更新数据 SQL, 更新一行的全部数据
UPDATE product SET title?, price?, num? WHERE id?ProductMapper接口
Integer updateProduct(Product product);ProductMapper.xml:
update idupdateProductUPDATE product SET title#{title}, price#{price}, num#{quantity} WHERE id#{id}
/update测试:
Test
void updateProduct(){Product product new Product(12, 老虎的手机, 100.99, 10);Integer num productMapper.updateProduct(product);System.out.println(product);System.out.println(num);
}MyBatis 动态SQL拼接
根据参加参数条件动态生成SQL提示SQL效率。
动态SQL标签 if choose when for 等
/*** 动态SQL更新* param product* return*/
Integer updateProductPart(Product product);XML:
!-- 检查参数动态拼接SQL --
!-- testtitle ! null 检查title不为空这拼接一段SQL title#{title}set 标签会自动删除多余的逗号 --
update idupdateProductPartUPDATE productsetif testtitle ! nulltitle#{title},/ifif testprice ! nullprice#{price},/ifif testquantity ! nullnum#{quantity}/if/setWHERE id #{id}
/update测试
Test
void updateProductPart(){Product product new Product(10, null, 1500.0, null);Integer num productMapper.updateProductPart(product);System.out.println(product);System.out.println(num);//一定要检查 SQL 处理结果不是1就是更新失败
}