mybatis(4) 代理机制以及小技巧

mybatis

  • 1、 问题
  • 2、使用
  • 3、#与$
    • 3.1 例子
    • 3.2什么情况下必须使用${}
  • 4、别名机制
  • 5 、Mapper配置
  • 6、配置模板文件
  • 7、使用自动生成的主键

1、 问题

在上一篇mybtis的web项目中,我们最后有一个问题没有解决,就是dao的实现类,其代码很类似,只是具体执行的sql语句不同,那么我们是否可以只编写dao的接口,而不用编写其具体实现类呢?
当然可以,mybaits已经二次封装了javassist来帮助我们自动生成实现类。
但是如果我们要使用这一机制,就要注意:
我们xxxmapper.xml 文件的namespace必须是 dao的接口全限定符,并且sql的id必须与接口的方法名一致。这有助于我们使用javassist这一辅助工具生成代理类是其可以帮助我们自动去实现接口的方法,并且调用我们自己编写的sql语句。

2、使用

1、首先 导入mybatis mysql logback junit依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.cky</groupId><artifactId>proxy</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><!--  mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version></dependency><!--    mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><!--    logback--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.11</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies></project>

2、写pojo 类

package com.cky.pojo;public class Car {private Integer id;private String carNum;private String brand;private Double guidePrice;private  String produceTime;private String carType;public Car(Integer id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {this.id = id;this.carNum = carNum;this.brand = brand;this.guidePrice = guidePrice;this.produceTime = produceTime;this.carType = carType;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getCarNum() {return carNum;}public void setCarNum(String carNum) {this.carNum = carNum;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public Double getGuidePrice() {return guidePrice;}public void setGuidePrice(Double guidePrice) {this.guidePrice = guidePrice;}public String getProduceTime() {return produceTime;}public void setProduceTime(String produceTime) {this.produceTime = produceTime;}public String getCarType() {return carType;}public void setCarType(String carType) {this.carType = carType;}@Overridepublic String toString() {return "Car{" +"id=" + id +", carNum='" + carNum + '\'' +", brand='" + brand + '\'' +", guidePrice=" + guidePrice +", produceTime='" + produceTime + '\'' +", carType='" + carType + '\'' +'}';}
}

3、写mapper接口

package com.cky.Mapper;import com.cky.pojo.Car;import java.util.List;public interface CarMapper {List<Car> selectAllCar();int deletebyId(int id);
}

4、写工具类 获得session

package com.cky.utils;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;public class MybatisUtils {private  static SqlSessionFactory sqlSessionFactory;/*** 类加载时初始化sqlSessionFactory对象*/static {SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();try {sqlSessionFactory=sqlSessionFactoryBuilder.build(Resources.getResourceAsReader("mybatis-config.xml"));} catch (IOException e) {e.printStackTrace();}}/*** 每调用一次openSession()可获取一个新的会话,该会话支持自动提交。** @return 新的会话对象*/public static SqlSession openSession(){return sqlSessionFactory.openSession(true);}
}

5、写mapper.xml文件

注意namespace 和 id

<?xml version="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="com.cky.Mapper.CarMapper"><select id="selectAllCar" resultType="com.cky.pojo.Car">select id,car_num,brand,guide_price,produce_time,car_type from t_car ;</select><delete id="deletebyId">delete from t_car where id=#{id};</delete>
</mapper>

6、写mybaits.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="jdbc.properties"></properties>
<!--一个数据库对应一个一个环境,一个数据库对应一个sqlSessionFactory对象-->
<!--    即一个环境 对应一个sqlSessionFactory对象-->
<!--    默认 使用的是defalut的数据库--><environments default="mybatisDB"><environment id="mybatisDB"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.name}"/><property name="password" value="${jdbc.pwd}"/></dataSource></environment></environments><mappers><!--sql映射文件创建好之后,需要将该文件路径配置到这里--><mapper resource="CarMapping.xml"/></mappers>
</configuration>

7 、测试
使用以下代码的前提是:CarMapper.xml文件中的namespace必须和dao接口的全限定名称一致,id必须和dao接口中方法名一致。

package com.cky;import com.cky.Mapper.CarMapper;
import com.cky.pojo.Car;
import com.cky.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;public class test {@Testpublic void tesr(){SqlSession sqlSession = MybatisUtils.openSession();//getMapper()  参数传入我们要代理的接口类 之后底层 会调用javassist 自动帮助我们生成 实现类 并将实现类返回 我们可以直接调用接口类的方法CarMapper mapper = sqlSession.getMapper(CarMapper.class);List<Car> cars = mapper.selectAllCar();cars.forEach(car -> System.out.println(car));int i = mapper.deletebyId(6);System.out.println(i);sqlSession.commit();sqlSession.close();}
}

3、#与$

3.1 例子

比如 我们需要根据汽车类型来查询汽车

   List<Car> selectbyCarType(String type);
    <select id="selectbyCarType" resultType="com.cky.pojo.Car">select * from t_car where car_type=${cartype}</select>

如果使用${}
则会报错 在这里插入图片描述

因为${} 是先进行sql语句的拼接,然后再编译,出现语法错误是正常的,因为 燃油车 是一个字符串,在sql语句中应该添加单引号

如果使用#{}在这里插入图片描述
则正确.
通过执行可以清楚的看到,sql语句中是带有 ? 的,这个 ? 就是大家在JDBC中所学的占位符,专门用来接收值的。把“电车”以String类型的值,传递给 ? 这就是 #{},它会先进行sql语句的预编译,然后再给占位符传值

3.2什么情况下必须使用${}

当需要进行sql语句关键字拼接的时候。必须使用${}
需求:通过向sql语句中注入asc或desc关键字,来完成数据的升序或降序排列。

 <select id="selectAll" resultType="com.cky.pojo.Car">selectid,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carTypefromt_carorder by carNum #{key}</select>
@Testpublic void testCartype1(){SqlSession sqlSession = MybatisUtils.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);List<Car> cars = mapper.selectAll("desc");cars.forEach(desc-> System.out.println(desc));}

使用#{}
在这里插入图片描述

错误,因为会先预编译,在赋值,这时候 会将其作为一个字符串常量传进去,但是是错误的 decs 是一个关键字,加上’'会变成字符串常量,sql语句会出错。
使用${}
在这里插入图片描述

此时是拼接,正确。

其他情况可能也需要 使用${} ,不在叙述,比如表名拼接时,此时是作为关键字而不是字符串常量赋值,或者模糊查询时 比如%奔驰% 如果要传入 奔驰这个关键字 就不能'%#{type}%' ,因为这时候 #{} 是在‘’引号里,不会被认为是占位符,使用${} 可以直接拼接。
我们如果想使用${} 可以 ”%“#{}”% “ 使用双引号的方式。也可以使用concat函数拼接, brand like concat('%',#{brand},'%')

4、别名机制

比如我们每次都returnType 上 都需要写全限定类名,很麻烦,我们可以采用别名机制。
在这里插入图片描述

在mybatis.xml文件中 配置
有三种方式
①对某个类 自己起别名
②对某个类采用默认别名机制
③对包下的类都采用默认别名机制

 <typeAliases><!--  自己起别名      --><typeAlias type="com.cky.pojo.Car" alias="car"></typeAlias><!-- 采用默认别名机制 默认是类名        --><typeAlias type="com.cky.pojo.Car"></typeAlias><!--  对包下所有的类 都采用默认别名机制        --><package name="com.cky.pojo"/></typeAliases>

5 、Mapper配置

SQL映射文件的配置方式包括四种:
● resource:从类路径中加载
● url:从指定的全限定资源路径中加载
● class:使用映射器接口实现类的完全限定类名
● package:将包内的映射器接口实现全部注册为映射器

前两种方式

  <mappers  ><mapper resource="CarMapper.xml"/><mapper url="file:///d:CarMapper.xml"/></mappers>

第三种方式

    <mappers><mapper class="com.cky.Mapper.CarMapper"/></mappers>

有个前提:
如果使用这种方式必须满足以下条件:
● SQL映射文件和mapper接口放在同一个目录下。
● SQL映射文件的名字也必须和mapper接口名一致。
在这里插入图片描述
虽然在不同的地方,其实都是在根路径下,java和resources打包后最后都在同一个目录下。
在这里插入图片描述
第四种方式
将包内的映射器接口实现全部注册为映射器 ,这种方式条件和第三种一样。

    <mappers><package name="com.cky.Mapper"/></mappers>

注意
在resources下只能创建目录 不能创建包
不能使用com.cky.Mapper 的方式 这样其实还是一个一级目录。
应该使用com/cky/Mapper 这是创建多级目录。

6、配置模板文件

比如我们的mybatis配置文件和 xxxMapper.xml,我们可以配置模板文件,方便创建。
举例:
在这里插入图片描述
在这里插入图片描述

7、使用自动生成的主键

不需要我们自己设置主键 而是mybaits帮我们自动生成 并且返回给我们。

    <insert id="insertCargeneratedkey" useGeneratedKeys="true" keyProperty="id">insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})</insert>
    @Testpublic void test(){SqlSession sqlSession = MybatisUtils.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Car car=new Car(null,"1000","1",100.0,"2024-04-09","dianche");int i = mapper.insertCargeneratedkey(car);System.out.println(i);System.out.println(car);sqlSession.commit();sqlSession.close();}

在这里插入图片描述
虽然我们插入的car id为null,但是当我们再次获取输出car时我们可以看到其id是有值的,
useGeneratedKeys=“true” 表示我们需要生成的主键值,keyProperty=“id” 代表将生成的主键值赋给id这个属性。此时当我们插入时,就会将自动生成的主键值赋给id,如果为false,则我们输出时car的id为null,虽然数据库中car的id是有值的,但是由于没有回显,输出就为null。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/802772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybase 8.x 下载安装试用详细教程(Windows)

一、软件介绍 MyBase是一款本地笔记软件&#xff0c;它能够帮助你管理和组织大量的信息。 二、下载安装 下载&#xff1a;点我去下载页面 Mybase 软件目前主要实现了两种版本&#xff1a;Mybase Desktop (桌面版) 和 Mybase Server (网络版)&#xff1a; 桌面版软件运行于 …

零售行业数字化广告评价标准 - 《IAB/MRC零售(广告)测量指南》

IAB/MRC零售&#xff08;广告&#xff09;测量指南 --- 最新标准&#xff0c;2024年1月发布 目录 1出台此标准的目的是什么&#xff1f;2标准宗旨3本标准的主要关键领域4为什么这对品牌和零售商很重要5能给零售媒体中小型玩家带来什么机会&#xff1f;6评价零售媒体效果的最…

金仓数据库Kingbase的数据库开发管理工具KStudio连接乱码

背景&#xff1a; 金仓数据库V8R6&#xff0c;KStudio在Windows10上运行&#xff0c;JDK8 问题&#xff1a; 使用客户端连接数据库时&#xff0c;提示信息乱码&#xff0c;首选项设置字符集不管用&#xff0c;具体如下图所示&#xff1a; Before&#xff1a; After&#xff1…

【CPA考试】2024注册会计师报名照片尺寸要求解读及手机拍照方法

随着2024年注册会计师考试的临近&#xff0c;众多会计专业人士和学生都开始准备报名参加这一行业的重要考试&#xff0c;报名时间为4月8日至4月30日。报名过程中&#xff0c;一张符合要求的证件照是必不可少的。本文将为您详细解读2024年注册会计师考试报名照片的尺寸要求&…

sfml sdl2 windows vscode 调试和coderunner插件运行

链接库写在编译链接命令里&#xff0c;如果没有使用到不会加入到生成的可执行文件里。所以tasks.json可以这样写&#xff0c; {"version": "2.0.0","tasks": [{"type": "cppbuild","label": "C/C: g.exe 生…

GlusterFS分布式文件系统

一、GlusterFS简介 GlusterFS 是一个开源的分布式文件系统。由存储服务器、客户端以及NFS/Samba存储网关(可选&#xff0c;根据需要选择使用)组成。没有元数据服务器组件&#xff0c;这有助于提升整个系统的性能、可靠性和稳定性 二、GlusterFS特点 2.1 扩展性和高性能 Glu…

结合 linux 0.11 源码分析为什么 fork 函数会返回两个值

#&#xff08;1&#xff09;学习资料是这些书 以及赵炯博士的完全剖析。谢谢这些大师与网上优秀的文章。 #&#xff08;2&#xff09;看 linux 0.11 源码是 sourceinlight 4.这里附上一个安装包。 由本图可知&#xff0c; main 函数对 fork 函数的调用。 fork 函数实际是定…

掌握苹果电脑保养秘籍,全方位维护指南!

苹果电脑&#xff08;Mac&#xff09;凭借卓越的性能表现、精致的设计美学以及深入人心的操作系统体验赢得了全球用户的高度评价。不过&#xff0c;无论是哪款顶级配置的Mac产品&#xff0c;都需要经过适时且恰当的保养维护&#xff0c;才能持续展现最优性能。 苹果电脑维护小…

最新AI工具系统ChatGPT网站运营源码SparkAi系统V6.0版本,GPTs应用、AI绘画、AI换脸、垫图混图、Suno-v3-AI音乐生成大模型全支持

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

Django之五种中间件定义类型—process_request、process_view、process_response.......

目录 1. 前言 2. 基础中间件 3. 如何自定义中间件 4. 五种自定义中间件类型 4.1 process_request 4.2 process_view 4.3 process_response 4.4 process_exception 4.5 process_template_response 5. 最后 1. 前言 哈喽&#xff0c;大家好&#xff0c;我是小K,今天咋们…

window安装maven和hadoop3.1.4

前面的文章已讲解如何安装idea和进行基本设置&#xff0c;本文主要带着大家安装配置好maven和hadoop. 大家不用去官网下载&#xff0c;直接使用我发给大家的压缩文件&#xff0c;注意解压后的文件夹不要放在中文目录下&#xff0c;课堂上我们讲解过原因。 这是我电脑上的路径&a…

App Inventor 2 SQLite 拓展

SQLite 拓展 此SQLite 拓展由中文网开发及维护&#xff0c;与 TaifunSQLite 功能类似&#xff0c;但TaifunSQLite是收费的&#xff0c;美刀。 文档及拓展下载地址&#xff1a; App Inventor 2 SQLite 拓展&#xff1a;超流行兼容主流SQL语法的迷你本地数据库引擎 App Invento…

018——红外遥控模块驱动开发(基于HS0038和I.MX6uLL)

目录 一、 模块介绍 1.1 简介 1.2 协议 二、 驱动代码 三、 应用代码 四、 实验 五、 程序优化 一、 模块介绍 1.1 简介 红外遥控被广泛应用于家用电器、工业控制和智能仪器系统中&#xff0c;像我们熟知的有电视机盒子遥控器、空调遥控器。红外遥控器系统分为发送端和…

【SCI绘图】【热力图系列1 R】多特征相关性分析热力图R语言实现

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【热力图系列1 R】多特征相关性分析热力图R语言实现 1.环境准备 library(gplots) library(RColorBrewer) 2.数据示例 ###…

宠物医院管理系统

文章目录 宠物医院管理系统一、系统演示二、项目介绍三、12000字论文参考四、系统部分页面展示五、部分代码展示六、底部获取项目源码和万字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 宠物医院管理系统 一、系统演示 宠物医院管理系统 二、项目介绍 语言&#xf…

基于YOLOv8的GC10-DET缺陷检测系统(Python源码+Pyqt6界面+数据集)

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的GC10-DET缺陷检测系统&#xff0c;并阐述了整个数据制作和训练可视化过程&#xff0c;最后通过Pyside UI界面进行展示。 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff09;YOL…

JAVA并发编程(二)_线程池

JAVA线程池 1.1Java 线程池之 Executor 框架 为了实现线程池和管理线程池&#xff0c;JDK 给我们提供了基于 Executor 接口的一系列接口、抽象类、实现类&#xff0c;我们把它称作线程池的 Executor 框架&#xff0c;Executor 框架本质上是一个线程池&#xff1b; ​ Java 线…

Python的基础知识学习路线1—python简介与环境配置(最全路线,每部分附有代码操作结果)

一、Python简介 &#xff08;1&#xff09;发展史 Python是由创始人贵铎范罗萨姆&#xff08;Guido van Rossum&#xff09;在阿姆斯特丹于1989年圣诞节期间&#xff0c;为了打发圣诞节的无趣&#xff0c;开发的一个新的解释型脚本语言。之所以选中Python&#xff08;大蟒蛇的…

免费SSL证书跟付费SSL证书有什么区别?

免费SSL证书与付费SSL证书的主要区别如下&#xff1a; 1. 类型与验证级别&#xff1a; - 免费SSL证书通常仅提供域名验证&#xff08;DV&#xff09;&#xff0c;这是一种最基本的验证级别&#xff0c;仅验证域名的所有权&#xff0c;确认申请者对所申请域名的有效控制。 - 付费…

怎样买国债逆回购最划算,国债逆回购手续费是多少?1折

国债逆回购是一种以国债作为抵押物的贷款&#xff0c;是一种能为投资者提高闲置资金增值能力的金融品种。国债逆回购的优势有&#xff1a; 安全性高&#xff0c;因为国债是信用等级最高、违约风险最低的金融资产&#xff0c;而且国债逆回购是在证券交易所进行的受监管的交易 …