Maven
概述
- Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
-
提供了一套标准化的项目结构
- Maven提供了一套标准化的项目结构,所有IDE使用Maven构建的项目结构完全一样,所有IDE创建的Maven项目可以通用
- Maven提供了一套标准化的项目结构,所有IDE使用Maven构建的项目结构完全一样,所有IDE创建的Maven项目可以通用
-
提供了一套标准化的构建流程(编译,测试,打包,发布....)
- 标准化的构建流程
Maven提供了一套简单的命令来完成项目构建
- 标准化的构建流程
-
提供了一套依赖管理机制
- 依赖管理
-
依赖管理其实就是管理你项目所依赖的第三方资源(jar包、插件...)
- 下载jar包
- 复制jar包到项目
- 将jar包加入工作环境
- 当jar包需要很多时,下载需要很多时间,而且下载的版本不同又会有影响,然后手动导jar包也十分的繁琐,但是Maven提供了一个管理jar包的机制
- Maven只需要一个简单的配置就可以完成jar包的导入了
- Maven使用标准的坐标配置来管理各种依赖
- 只需要简单的配置就可以完成依赖管理(pom.xml)
<!-- 导入mysql驱动jar包--> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> </dependencies>
-
- 依赖管理
-
Maven简介
- Apache Maven是一个项目管理和构建工具,它基于项目对象模型(pom)的概念,通过一小段描述信息来管理项目的构建、报告和文档
- 官网:maven.apache.org/
- Maven作用
- 标准化的项目结构
- 标准化的构建流程
- 方便的依赖管理
- Maven作用
- Maven模型
- 项目对象模型(Project Object Model)
- 依赖管理模型(Dependency)
- 插件(Plugin)
- 仓库分类
- 本地仓库:自己计算机上的一个目录
- 中央仓库:由Maven团队维护的全国唯一的仓库
- 远程仓库(私服):一般由公司团队搭建的私有仓库
- 当项目中使用坐标引入对应的依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
- 如果有,则在项目直接引用
- 如果没有,则去中央仓库下载对应的jar包到本地仓库
- 当项目有远程仓库(私服),首先会查找本地仓库中是否有对应的jar包,没有则在远程仓库里下载,若还是没有,则在中央仓库中寻找
- 当项目中使用坐标引入对应的依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
Maven安装配置
- 解压apache-maven-3.6.1.rar既安装完成(官网上下载)
- 配置环境变量MAVEN_HOME为安装路径的bin目录
- 第一步:新建MAVEN_HOME(maven的安装目录)
- 第二步:双击Path
- 第三步:新建(%MAVEN_HOME%\bin)
- 第四步:全部确定
- 第五步:验证(打开cmd -->输入
mvn -version), 若出现以下,则配置成功
- 第一步:新建MAVEN_HOME(maven的安装目录)
- 配置本地仓库:修改conf/setting.xml中的
<localRepository>为一个指定目录- 第一步:找到conf --> setting.xml -->双击打开
- 第二步:往下拉找到
localReposition
- 第三步:将上一步找出来的注释的最后一行粘贴出来(
<localRepository>/path/to/local/repo</localRepository>) - 第四步:修改本地仓库位置,其实要是不修改的话,我们是有默认的本地仓库位置的,不过在C盘,所以我们要修改。(在Maven安装目录下新建一个文件夹mvn_resp -->复制文件夹位置 -->粘贴到
localRepository中)
- 配置阿里云私服:修改conf/setting.xml中的
<mirrors>标签,为其添加如下子标签:- 配置阿里云私服是为了提高jar包下载速度
<mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>https://maven.aliyun.com/nexus/content/groups/public/</url> <blocked>true</blocked> </mirror> </mirrors>
Maven基本使用
- Maven常用命令
- compile:编译
- clean:清理
- test:测试
- package:打包
- install:安装
- 首先新建一个项目
- mvn compile:在项目根目录下,右键(在终端打开)-->输入
mvn compile-->回车
出现了BUILD SUCCESS即成功
成功之后,会多出一个target目录
要是把target目录给删了,可以重新运行(mvn compile),这次会很快运行完,因为已经不用再重新下载了。
- mvn clean:删除target目录
- mvn package:将生成的字节码文件打包成jar包(因为这是一个Java项目,所以会打包成一个jar包,如果是一个web项目,则会打包成一个var包)
- mvn test:会自动执行test目录下的Java文件
- mvn install:将当前这个项目安装到本地仓库上去
- Maven生命周期
- Maven构建项目生命周期描述的是一次构建过程经历了多少个事件
- Maven对项目构建的生命周期划分为3套
- clean:清理工作
- default:核心工作,例如编译,测试,打包,安装等
- site:产生报告,发布站点等
- 同一生命周期内,执行后边的命令,前边的所有命令会自动执行
IDEA配置Maven
-
IDEA配置Maven环境
- 创建空项目-->选择IDEA File -->Settings(设置)
- 搜索maven
- 设置IDEA使用本地安装的Maven,并修改配置文件路径
-
Maven坐标详解
- 什么是坐标?
- Maven 中的坐标是资源的唯一标识
- 使用坐标来定义项目或引入项目中需要的依赖
- Maven 坐标主要组成
- groupld:定义当前Maven项目隶属组织名称 (通常是域名反写,例如:com.alibaba)
- artifactld: 定义当前Maven项目名称 (通常是模块名称,例如 order-service、goods-service)
- version:定义当前项目版本号
- IDEA创建Maven项目
-
创建模块,选择Maven,点击Next
-
填写模块名称,坐标信息,点击finish,创建完成
-
编写HelloWorld,并运行
package com; public class HelloWorld { public static void main(String[] args) { System.out.println("hello Maven"); } } -
- IDEA导入Maven项目
- 点击最右边的Maven
- 点击“+”号
- 选择pom文件
- 点击最右边的Maven
- 配置Maven-Helper插件(如果搜不到,则在官网下下载)
- 选择IDEA中File-->Settings
- 选择Plugins
- 搜索Maven,选择第一个Maven Helper,点击install安装,弹出面板中点击Accept
- 重启IDEA
依赖管理
使用坐标导入jar包
- 在pom.xml中编写
<dependencies>标签 - 在
<dependencies>标签其中使用<dependency>引入坐标 - 定义坐标的
groupld,artifactld,version - 点击刷新按钮,使坐标生效
<!-- 导入mysql驱动jar包-->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.24</version>
</dependency>
</dependencies>
- 有时候会忘记点刷新按钮让它生效,可以设置让它自己自动生效
- setting(设置)
- Build,Execution,Deployment(构建,执行,部署)--> Build Tools(构建工具)
- anychanges(任何变更)
- 也可以手动导入jar包
- Fn+Alt+insert
- 依赖项(Dependency)
- 搜索mysql-->选中所需要的版本
依赖范围
- 通过设置坐标的依赖范围(scope),可以设置对应的jar包的作用范围:编译环境、测试环境、运行环境
| 依赖范围 | 编译classpath | 测试classpath | 运行classpath | 例子 |
|---|---|---|---|---|
| compile | Y | Y | Y | logback |
| test | - | Y | - | Junit |
| provided | Y | Y | - | servlet-api |
| runtime | - | Y | Y | jdbc驱动 |
| system | Y | Y | - | 存储在本地的jar包 |
| import | 引入DependencyManagement | ~ | ~ | ~ |
<scope>默认值:compile(就是在哪个环境都有效,通常只要默认就行)
MyBatis
概述
什么是MyBatis
- MyBatis是一款优秀的持久层框架,用于简化JDBC开发
- MyBatis本是Apache的一个开源项目iBatis,2020年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github
- 官网:mybatis.org/mybatis-3/z…
持久层
- 负责将数据保持到数据库的那一层代码
- JavaEE三层架构:表现层、业务层、持久层
框架
- 框架就是一个半成品软件,是一套可重用、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展
JDBC缺点
- 硬编码 --》配置文件
- 注册驱动,获取连接
- SQL语句
- 操作繁琐--》自动完成
- 手动设置参数
- 手动封装结果集
MyBatis简化
配置文件
<!--连接池信息-->
<dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///db1?useSSL=false"/><property name="username"
value="root"/><property name="password" value="1234"/></dataSource>
<!--SQL语句-->
<select id="selectByGender" parameterType="string"resultType="com.itheima
.pojo.User";select * from tb_user where gender = #{gender};
</select>
<!--设置参数-->
List<User> users=sqlSession.selectList("test.selectByGender","男");
MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作
Mybatis快速入门(mybatis.net.cn/getting-sta…)
-
创建tb_user表,添加数据
-
创建模块,导入坐标
- logback所需的jar包和xml文件(maven导入)
- logback-classic-1.2.3.jar
- logback-core-1.2.3.jar
- slf4j-api-1.7.26.jar
- logback.xml
查看mysql版本号:mysql中输入
SELECT VERSION();。
- xml文件(这个文件复制到src-->main-->resources下)
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- CONSOLE :表示当前的日志信息是可以输出到控制台的 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--输出流对象 默认 System.out 改为 System.err 其中err:控制台输出日志为红色,而out为黑色--> <target>System.out</target> <encoder> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n</pattern> </encoder> </appender> <!-- File:表示当前的日志信息是可以输出到文件的 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>utf-8</charset> </encoder> <!--日志输出路径(logback_message.log是文档名,下方还有一处文件名(不用写.log))--> <file>D:\codeLogback\xie-data.log</file> <!--指定日志文件拆分和压缩规则(防止文件过大)--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--通过指定压缩文件名称,来确定分割文件方式--> <fileNamePattern>D:\codeLogback\xie-data-%d{yyyy-MM-dd}.log%i.gz</fileNamePattern> <maxFileSize>1MB</maxFileSize> <!--文件拆分大小--> </rollingPolicy> </appender> <!-- level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF (关掉), 默认debug(可忽略大小写) <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。 --> <root level="INFO"> <!--打印规则:只打印不低于当前级别的日志--> <appender-ref ref="CONSOLE"/> <!--如果这个地方不配置关联打印的位置,改位置将不会记录日志--> <appender-ref ref="FILE" /> </root> </configuration>
- logback所需的jar包和xml文件(maven导入)
-
编写MyBatis核心配置文件-->替换连接信息解决硬编码的问题
- 在recources在创建一个mybatis_config.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!--数据库连接信息--> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <!--加载SQL映射文件--> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
- 在recources在创建一个mybatis_config.xml文件
-
编写SQL映射文件-->统一管理SQL语句,解决硬编码问题
- 在recources创建一个UserMapper.xml文件(映射文件起名有规则,如果是User表,则起UserMapper,但如果是open表,则起名为OpenMapper)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace:名称空间,名字可以随便取,这里取得名字是test--> <mapper namespace="test"> <select id="selectBlog" resultType="Blog"> select * from tb_user where id = #{id} </select> <!-- <select></select>:定义查询语句 id:SQL语句的唯一标识,需要改值 resultType:对应返回的结果类型,将来我们的数据打算包装成什么类型,我们就写什么类型,所以接下来就是要把user类给创建出来( --> </mapper> - 创建User类(Java目录下)
- 将
改成<mapper namespace="test"> <select id="selectBlog" resultType="Blog"> select * from tb_user where id = #{id} </select><mapper namespace="test"> <select id="selectAll" resultType="com.xie.pojo.User"> select * from tb_user; //可以随意写SQL语句 </select>
com.xie.pojo.User:是创建的User表的目录
- 将mybatis_config.xml的加载SQL映射文件部分修改
改成<!--加载SQL映射文件--> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers>因为UserMapper.xml文件和mybatis_config.xml文件都是在rescources目录下,所以是同一级目录,所以直接写"UserMapper.xml"<!-- 加载SQL映射文件--> <mapper resource="UserMapper.xml"/> </mappers>
- 在recources创建一个UserMapper.xml文件(映射文件起名有规则,如果是User表,则起UserMapper,但如果是open表,则起名为OpenMapper)
-
编码
- 定义POJO类(User表)
ackage com.xie.pojo; public class User { private Integer id; private String username; private String password; private String gender; private String addr; public Integer getId() { return id; } }
右键生成setting,getting,toString方法
package com.xie.pojo; public class User { private Integer id; private String username; private String password; private String gender; private String addr; public Integer getId() { return id; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + ''' + ", password='" + password + ''' + ", gender='" + gender + ''' + ", addr='" + addr + ''' + '}'; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getUsername() { return username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public void setUsername(String username) { this.username = username; } public void setId(Integer id) { this.id = id; } }- 加载核心配置文件,获取sqlSessionFactory对象
- 获取sqlSession对象,执行SQL语句
- 释放资源
package com.xie; import com.xie.pojo.User; 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; import java.io.InputStream; import java.util.List; //MyBatis快速入门代码 public class MyBatis { public static void main(String[] args) throws IOException { // 1.加载mybatis的核心配置文件,获取sqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2. 获取sqlSession对象,用它来执行SQL SqlSession sqlSession=sqlSessionFactory.openSession(); // 3. 执行SQL List<User> users=sqlSession.selectList("test.selectAll"); System.out.println(users); // 4.释放资源 sqlSession.close(); } }
List<User> users=sqlSession.selectList("test.selectAll");中的test.selectAll是UserMapper.xml文件中的名称空间.id标识 - 定义POJO类(User表)
-
解决SQL映射文件的警告提示
- 产生问题:idea和数据库没有建立连接,不识别表信息
- 解决方式:在idea中配置MySQL数据库连接
Mapper代理开发
-
目的
-
解决原生方式中的硬编码
-
简化后期执行SQL
//3.执行SQL List<User> users=sqlSession.selectList("test.selectAll"); System.out.printf(users);//3.获取接口代理对象 UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //4.执行方法,其实就是执行SQL语句 List<User> users=users=userMapper.selectAll();
第二种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点;其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择到映射好的 SQL 语句。
-
-
Mapper代理需要遵循的要求
- 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
在resources目录下要是想要建包,则不能直接新建“com.xie.mapper”,要不然idea会认为一个目录就叫做com.xie.mapper,所以要改成“com/xie/mapper”
- 设置SQL映射文件的namespace属性为Mapper接口全限定名
- 在Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
- 在映射文件中有一个SQL id叫做selectAll,那就意味着将来在Usermapper(类)里面要有一个方法,叫做selectAll,而且参数和返回类型要一致。
- 在UserMapper.xml这个映射文件中有一个返回类型,叫做User
package com.xie.mapper; import com.xie.pojo.User; import java.util.List; public interface UserMapper { List<User> selectAll(); //因为在UserMapper.xml中返回的是一个User集合,所以这返回的是List<User>,如果返回的对象是User,则只能查询出一个对象 }
- 编码
- 通过 SqlSession 的 getMapper方法获取 Mapper接口的代理对象
- 新建一个类(MyBatisDemo2),然后运行,能得到相同的结果
结果package com.xie; import com.xie.mapper.UserMapper; import com.xie.pojo.User; 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; import java.io.InputStream; import java.util.List; //MyBatis代理开发 public class MyBatisDemo2 { public static void main(String[] args) throws IOException { // 1.加载mybatis的核心配置文件,获取sqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2. 获取sqlSession对象,用它来执行SQL SqlSession sqlSession=sqlSessionFactory.openSession(); // 3. 执行SQL // List<User> users=sqlSession.selectList("test.selectAll"); //3.1获取serMapper接口的代理对象 UserMapper userMapper=sqlSession.getMapper(UserMapper.class); List<User> users=userMapper.selectAll(); System.out.println(users); // 4.释放资源 sqlSession.close(); } }
- 调用对应方法完成sql的执行
- 通过 SqlSession 的 getMapper方法获取 Mapper接口的代理对象
- 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
-
整个运行流程
- myBatisDemo2类中第2步获取了sqlSession对象
- 在第3.1步中通过sqlSeession来获取对应的Mapper接口(UserMapper.class)代理对象(UserMapper)
- 通过第3.1步这行代码可以找到UserMapper这个接口
- 又因为在当前这个目录(UserMapper)下面有一个同名的映射文件,所以又可以找到映射文件(UserMapper.xml)下对应的SQL语句
- 找到之后,通过UserMapper.selectAll()(回到MyBatisDemo2类中的第3.1步)调用UserMapper这个接口里的selectAll()方法
- selectAll()(接口UserMapper中的)对应的是SQL语句的id,找到UserMapper.xml中的对应的id,找到id之后,就可以获取SQL语句了
- 有了SQL语句后,因为我们的返回值是List,所以其实它的底层执行的还是sqlSession.selectList,它帮我们写
List<User> users=sqlSession.selectList("test.selectAll");这行代码(在之前学过的MyBatisDemo类中有)
-
细节:如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
- 意思是在mybatis-config.xml中加载SQL映射文件时,现在的映射文件有包的名称,写起来不是很方便,而且将来会有很多很多这样的映射文件,就要写一排,不方便。如果用了Mapper代理开发方式,有另外简化的方式来加载映射文件。可以
<package name="com.xie.mapper"/>这一行代码全部搞定
- 意思是在mybatis-config.xml中加载SQL映射文件时,现在的映射文件有包的名称,写起来不是很方便,而且将来会有很多很多这样的映射文件,就要写一排,不方便。如果用了Mapper代理开发方式,有另外简化的方式来加载映射文件。可以
MyBatis核心配置文件(即mybatis-config.xml)
- enviroment(mybatis.org/mybatis-3/z…
- 可以写多个environment,即可以导入多个库
第一个库是开发库,第二个测试库
- 可以写多个environment,即可以导入多个库
- typeAliases(类型别名)
mybatis.org/mybatis-3/z…- 配置完之后相当于我们给所有pojo目录下的所有实体类起了个别名,别名默认为是类名,不需要带包名称了。
- 意味着我们将来写UserMapper.xml中的返回类型(resultType)时,可以直接写
resultType="类名"(不区分大小写)
- 细节:配置各个标签时,需要遵循前后顺序
顺序:
配置文件完成增删改查
案例:完成品牌数据的增删改查操作
- 要完成的功能列表清单
准备环境
-
数据库表tb_brand
-
实体类Brand
-
测试用例
-
安装MyBatisX插件
- MybtisX插件
- MybatisX是一款基于idea的快速开发插件,为效率而生
- 主要功能
- XML和接口方法相互跳转
- 根据接口方法生成statement(例如UserMapper.xml中的SQL语句)
- 安装:
- MybtisX插件
查询
查询所有数据
-
编写接口方法:Mapper接口
- 参数:无
- 结果:List
-
编写SQL语句:SQL映射文件
-
执行方法,测试
MyBatis完成操作需要几步
三步:编写接口方法-》编写SQL-》执行方法
注意
查看详情
- 编写接口方法:Mapper接口
- 参数:id
- 结果:Brand
- 编写SQL语句:SQL映射文件
- 执行方法,测试
- 总结
- 参数占位符
- #{}: 执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
- S{}: 拼sQL。会存在sQL注入问题
- 使用时机:
- 参数传递,都使用#{}
- 如果要对表名、列名进行动态设置,只能使用${}进行sql拼接
- parameterType 用于设置参数类型,该参数可以省略
- SQL 语句中特殊字符处理
- 转义字符
<![CDATA[ 内容]]>
- 转义字符
- 参数占位符
条件查询
- 多条件查询
- 编写接口方法(BrandMapper.java)
- 参数:所有查询条件
- 结果:
List<Brand>
/** 条件查询 * 参数接受 * 1.散装参数(如果方法中有多个参数,需要使用@Param("SQL参数占位符名称")) * 2.对象参数:只需要保证SQL中的参数名和实体类属性名对应上,即可设置成功 * 3. map集合参数:只需要保证SQL中参数名和map集合的键的名称对应上,即可设置成功 **/ Brand selectById(int id); List<Brand> selectByCondition(@Param("status")int status,@Param("companyName")String companyName,@Param("brandName") String brandName); List<Brand> selectByCondition(Brand brand); List<Brand> selectByCondition(Map map); } - 编写SQL语句,SQL映射文件(BrandMapper.xml)
<!-- 条件查询--> <select id="selectByCondition"resultMap="brandResultMap"> select * from tb_brand where status=#{status} and company_name like #{companyName} and brand_name like #{brandName} </select> - 执行方法,测试
- 散装参数
// 散装参数 @Test public void testSelectByCondition() throws IOException { // 接受参数 int status=1; String companyName="华为"; String brandName="华为"; // 处理参数 companyName ="%"+companyName+"%"; brandName="%"+brandName+"%"; // 1.获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.获取SqlSession对象 SqlSession sqlSession=sqlSessionFactory.openSession(); // 3.获取Mapper接口的代理对象 BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class); // 4.执行方法 List<Brand> brands=brandMapper.selectByCondition(status,companyName,brandName); System.out.println(brands); // 5.释放资源 sqlSession.close(); }- 对象参数
// 对象参数 @Test public void testSelectByCondition() throws IOException { // 接受参数 int status=1; String companyName="华为"; String brandName="华为"; // 处理参数 companyName ="%"+companyName+"%"; brandName="%"+brandName+"%"; // 封装参数 Brand brand=new Brand(); brand.setStatus(status); brand.setCompanyName(companyName); brand.setBrandName(brandName); // 1.获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.获取SqlSession对象 SqlSession sqlSession=sqlSessionFactory.openSession(); // 3.获取Mapper接口的代理对象 BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class); // 4.执行方法 // List<Brand> brands=brandMapper.selectByCondition(status,companyName,brandName); List<Brand> brands=brandMapper.selectByCondition(brand); System.out.println(brands); // 5.释放资源 sqlSession.close(); }- map集合参数
// map集合参数 @Test public void testSelectByCondition() throws IOException { // 接受参数 int status=1; String companyName="华为"; String brandName="华为"; // 处理参数 companyName ="%"+companyName+"%"; brandName="%"+brandName+"%"; // 封装参数 // Brand brand=new Brand(); // brand.setStatus(status); // brand.setCompanyName(companyName); // brand.setBrandName(brandName); Map map=new HashMap(); map.put("status",status); map.put("companyName",companyName); map.put("brandName",brandName); // 1.获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.获取SqlSession对象 SqlSession sqlSession=sqlSessionFactory.openSession(); // 3.获取Mapper接口的代理对象 BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class); // 4.执行方法 // List<Brand> brands=brandMapper.selectByCondition(status,companyName,brandName); // List<Brand> brands=brandMapper.selectByCondition(brand); List<Brand> brands=brandMapper.selectByCondition(map); System.out.println(brands); // 5.释放资源 sqlSession.close(); }
- 编写接口方法(BrandMapper.java)
- 多条件-动态条件查询 mybatis.org/mybatis-3/z…
SQL语句会随着用户的输入或外部条件的变化而变化,我们称为动态SQL
- MyBatis对动态SQL有很大的支撑:
- if:用于判断参数是否有值,使用test属性进行条件判断
- 存在的问题:第一个条件不需要逻辑运算符
- 解决方案:
- 使用恒等式让所有条件格式都一样
<where>标签替换where关键字
- choose(when,otherwise)
- trim(where,set)
- foreach
- if:用于判断参数是否有值,使用test属性进行条件判断
- MyBatis对动态SQL有很大的支撑:
查询(BrandMapper.xml)
<!-- 动态条件查询
* if:条件查询
* test:逻辑表达式
* 问题
* 恒等式
* <where> 替换where关键字
-->
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
# where 1=1
<where>
<if test="status !=null">
and status=#{status}
</if>
<if test="companyName !=null and companyName !=''">
and company_name like #{companyName}
</if>
<if test="brandName !=null and brandName !=''">
and brand_name like #{brandName}
</if>
</where>
</select>
- 单条件动态查询
从多个条件中选择一个- choose(when,otherwise):选择,类似于Java中的Switch语句
- BrandMapper.java
/**单条件动态查询**/ List<Brand> selectByConditionSingle(Brand brand);- BrandMapper.xml
<select id="selectByConditionSingle" resultType="Brand"> select * from tb_brand <where> <choose><!--相当于Switch--> <when test="status !=null"><!--相当于case--> status=#{status} </when> <when test="companyName !=null and companyName !=''"><!--相当于case--> company_name like #{companyName} </when> <when test="brandName !=null and brandName !=''"><!--相当于case--> brand_name like #{brandName} </when> </choose> </where> </select>- MyBatisTest.java
@Test public void testSelectByConditionSingle() throws IOException { // 接受参数 int status=1; String companyName="华为"; String brandName="华为"; // 处理参数 companyName ="%"+companyName+"%"; brandName="%"+brandName+"%"; // 封装参数 Brand brand=new Brand(); // brand.setStatus(status); // brand.setCompanyName(companyName); // brand.setBrandName(brandName); // 1.获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.获取SqlSession对象 SqlSession sqlSession=sqlSessionFactory.openSession(); // 3.获取Mapper接口的代理对象 BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class); // 4.执行方法 List<Brand> brands=brandMapper.selectByConditionSingle(brand); System.out.println(brands); // 5.释放资源 sqlSession.close(); }
添加
基础添加
- 编写接口方法
- 参数:除了id之外的所有数据
- 结果:void
- 编写SQL语句:SQL映射文件
- 执行方法,测试
- MyBatis事务
- oppenSession():默认开启事务,进行增删改查操作后需要使用sqlSession.commit();手动提交事务
- oppSession(true):可以设置为自动提交事务(关闭事务)
- MyBatis事务
- BrndMapper.java
/*
* 添加
* */
void add(Brand brand);
- BrandMapper.xml
<insert id="add">
insert into tb_brand(brand_name, company_name, ordered, description, status)
values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
- MyBatisTest.java
@Test
public void testAdd() throws IOException {
// 接受参数
int status=1;
String companyName="波导手机";
String brandName="波导";
String description="手机中的战斗机";
int ordered=100;
// 封装参数
Brand brand=new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
// SqlSession sqlSession=sqlSessionFactory.openSession();
SqlSession sqlSession=sqlSessionFactory.openSession(true);
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
brandMapper.add(brand);
// 提交事务
// sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
添加-主键返回
在数据添加成功后,需要获取插入数据库数据的主键值
- 比如:添加订单和订单项
- 添加订单
- 添加订单项,订单项中需要设置所属订单的id
返回添加数据的主键
<insert useGeneratedKeys="true" keyProperty="id">
如果没有这行代码的话,添加完数据后,并不能查询到对应的id。
- BrandMapper.xml
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into tb_brand(brand_name, company_name, ordered, description, status)
values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
- MyBatisType.java
@Test
public void testAdd2() throws IOException {
// 接受参数
int status=1;
String companyName="波导手机";
String brandName="波导";
String description="手机中的战斗机";
int ordered=100;
// 封装参数
Brand brand=new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
// SqlSession sqlSession=sqlSessionFactory.openSession();
SqlSession sqlSession=sqlSessionFactory.openSession(true);
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
brandMapper.add(brand);
Integer id=brand.getId();
System.out.println(id);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
修改
修改全部字段
- 编写接口方法:Mapper接口
- 参数:所有数据
- 结果:void
int update(Brand brand); - 编写SQL语句:SQL映射文件
<update id="update"> update tb_brand set brand_name=#{brandName}, company_name=#{companyName}, ordered=#{ordered}, description=#{description}, status=#{status} where id=#{id}; </update> - 执行方法,测试
@Test public void testUpdate() throws IOException { // 接受参数 int status=1; String companyName="波导手机"; String brandName="波导波导"; String description="波导手机,手机中的战斗机"; int ordered=100; int id=5; // 封装参数 Brand brand=new Brand(); brand.setStatus(status); brand.setCompanyName(companyName); brand.setBrandName(brandName); brand.setDescription(description); brand.setOrdered(ordered); brand.setId(id); // 1.获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.获取SqlSession对象 // SqlSession sqlSession=sqlSessionFactory.openSession(); SqlSession sqlSession=sqlSessionFactory.openSession(true); // 3.获取Mapper接口的代理对象 BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class); // 4.执行方法 int count=brandMapper.update(brand); System.out.println(count); // 提交事务 sqlSession.commit(); // 5.释放资源 sqlSession.close(); }
修改动态字段
比如用户修改密码时,只会修改密码,而不会改变其他的值
<update id="update">
update tb_brand
<set>
<if test="brandName !=null and brandName !=''">
set brand_name=#{brandName},
</if>
<if test="companyName !=null and companyName !=''">
company_name=#{companyName},
</if>
<if test="ordered !=null">
ordered=#{ordered},
</if>
<if test="description !=null and description !=''">
description=#{description},
</if>
<if test="status !=null">
status=#{status}
</if>
</set>
where id=#{id};
</update>
删除
删除一个
- 编写接口方法:Mapper接口
- 参数:id
- 结果:void
void deleteById(int id); - 编写SQL语句:SQL映射文件
<delete id="deleteById">
delete from tb_brand where id=#{id};
</delete>
3.执行方法,测试
@Test
public void testDeleteById() throws IOException {
// 接受参数
int id=5;
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
// SqlSession sqlSession=sqlSessionFactory.openSession();
SqlSession sqlSession=sqlSessionFactory.openSession(true);
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
brandMapper.deleteById(id);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
批量删除
- 编写接口方法:Mapper接口
- 参数:id数组
- 结果:void
void deleteByIds(@Param("ids")int[] ids);
- 编写SQL语句:SQL映射文件
<!--
mybatis 会将数组参数,封装为一个map集合,
* 默认:array=数组
* 使用@Param注解来改变map集合的默认key的名称
-->
<delete id="deleteByIds">
delete
from tb_brand
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}
</foreach>
;
</delete>
- 执行方法,测试
@Test
public void testDeleteByIds() throws IOException {
// 接受参数
int[] ids={7,6,8};
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
// SqlSession sqlSession=sqlSessionFactory.openSession();
SqlSession sqlSession=sqlSessionFactory.openSession(true);
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
brandMapper.deleteByIds(ids);
// 提交事务
sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
MyBatis参数传递
MyBatis接口方法中可以接收各种各样的参数,MyBatis底层对于这些参数进行不同的封装处理方式
- 单个参数:
- POJO类型
- Map集合
- Collection:
- List
- Array:
- 其他类型
- 多个参数
MyBatis提供了ParamNameResolver类来进行参数封装...
省略
注解完成增删查改
使用注解开发会比配置文件开发更加方便
@Select("select * from tb_user where id=#{id}")
public User selectById(int id);
- 查询:@Select
- 添加:@Insert
- 修改:@Update
- 删除:@Delete
提示:
- 注解完成简单功能
- 配置文件完成复杂功能
使用注解来射简单语句会使码得更加首洁,但对于微复杂一点的语句a 解不力不以心,还会让你本就复杂的 SOL 语向更加混乱不。因此,如果你需要做一些很复杂的作,最好
用XML 来映射语句。
选择何种方式来配置映射,以及认为是否应该要统一谢语向定义的式,完全决和你的团队换句适说,永远不要于-种方式,你可以很经的在基于解和 M, 的语句映射方式间
由移植和切换。