MyBatis
MyBatis
1.MyBatis介绍
1.1 MyBatis基本介绍
结合MyBatis官网一起阅读,效果更加哟~~~
1.2 JDBC缺点
1.3 MyBatis 简化JDBC
2.MyBatis快速入门
要求:
2.1 创建数据库表
创建一个自己的表,属性自己去确定,也可以用我的:
输入以下数据库信息:
语句:
create database mybatis;
use mybatis;
drop table if exists tb_user;
create table tb_user(
id int primary key auto_increment,
username varchar(20),
password varchar(20),
gender char(1),
addr varchar(30)
);
INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');
2.2 创建maven,导入坐标
1、创建一个maven项目,然后导入坐标依赖
在pom.xml 的 dependencies> /dependencies> 这对标签里面写,当然要记得用dependency> /dependency>去包起来
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- 添加slf4j日志api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!-- 添加logback-classic依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 添加logback-core依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
注:需要什么依赖的时候,就导入即可,不知道的可以直接去官网cv即可,上面的是些比较普遍的依赖
2.3 编写MyBatis的核心文件
MyBatis的核心文件的主要作用就是去,替换jdbc中的连接信息,来解决硬代码的问题
这些都可以在MyBatis的官网里面找到哦
一般都是用mybatis-config.xml去命名的,注意要写在resource下面
<?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:/// " " ?useSSL=false"/>//双引号" "里面填自己的表名
<property name="username" value=" "/>//注意这里是自己的数据库名
<property name="password" value=" "/>//注意这里是自己的数据库密码
</dataSource>
</environment>
</environments>
<mappers>
<!--指定sql映射文件路径-->
<!--resource:是相对于类的类路径,也就是后面要写的Mapper.xml的路径-->
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
注意:上面代码中这短里面的注释哦~~~
<property name="url" value="jdbc:mysql:/// " " ?useSSL=false"/>//双引号" "里面填自己的表名
<property name="username" value=" "/>//注意这里是自己的数据库名
<property name="password" value=" "/>//注意这里是自己的数据库密码
2.4 编写SQL映射文件
这个映射文件的目的就是,统一管理sql语句,也是为了去解决硬代码问题
这个映射文件主要是用要定义的类+Mapper.xml去命名,比如你要操作的是User,那就是UserMapper.xml,如果是Brand,那就是BrandMapper.xml,Mappar就是映射的意思嘛~~
注意要写在resource下面
<?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:名称空间
id:sql语句的唯一标识
resultType:数据的返回类型
-->
<mapper namespace="xiaowang">
<select id="selectAll" resultType="com.xiaowang.pojo.User">
select * from tb_user;
</select>
</mapper>
注意:
namespace:名称空间
id:sql语句的唯一标识
resultType:数据的返回类型
2.5 编码
2.5.1 定义POJO类
POJO类主要就是存放Java类的,
这就是写一个你数据库表里面有的属性的属性类,然后封装起getter、setter方法、以及toString方法
package com.xiaowang.pojo;
/**
* @Author 小王
* @DATE: 2022/5/18
*/
//ALT+鼠标左键--->整列编辑
//CTRL+ ALT + L---> 格式化
public class User {
private Integer id;
private String username;
private String password;
private String gender;
private String addr;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Uesr{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", addr='" + addr + '\'' +
'}';
}
}
2.5.2 加载核心配置文件
加载这个文件主要是为了去获取SqlSessionFactory对象,这些在MyBatis的官网里都有,直接cv就行,MyBatis官网
2.5.3 获取sqlSession对象
这个对象的目的就是相当于替换了jdbc中执行sql语句的方法,在jbdc中,
2.5.4 执行sqlSession对象
也就是和jdbc中的SQL语句执行一样的意思,但是MyBatis的话就会更简单,在JDBC中如果要执行的参数很多的时候,就会写很多条语句去执行,执行后还需要写语句去封装,然而在MyBatis中的话,一句话就可以搞定了,就很方便啦~~
2.5.5 释放资源
这就和jdbc中一样了,都是使用 资源.close,但是使用MyBatis的话,好处就是只需要去释放一个执行对象的资源,即sqlSession.close
编码部分的总代码:
package com.xiaowang;
import com.xiaowang.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;
/**
* @Author 小王
* @DATE: 2022/5/18
*/
//MyBatis快速入门
public class MyBatisDemo {
public static void main(String[] args) throws IOException {
//1.加载MyBatis的核心配置为文件,获取SqlSessionFactory对象
/*
resource:mybatis的配置文件路径
inputStream:通过MyBatis的资源加载类对象(Resources)去调用getResourceAsStream(resource)返回字节输入流
sqlSessionFactory:通过SqlSessionFactoryBuilder()对象去调用build()方法去传入一个输入流对象返回
* */
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
// selectList():查询所有的方法,里面传入的是sql语句的唯一标识,要带上名称空间哦~~,为了区分不同的Mapper
// selectOne():查询一个的方法
//用集合自动封装了~~
List<User> users = sqlSession.selectList("xiaowang.selectAll");
System.out.println(users);
//4.释放资源
sqlSession.close();
}
}
3.Mapper代理开发
3.1 Mapper开发的目的
MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
3.2 Mapper代理
1、特别注意,接口名和Mapper映射名要一直,并且要在同一个目录下
然后将其映射文件拖进去,编译一下就可以发现在同一个目录下了
2、设置SQL映射文件的namespace属性为Mapper接口的全限定名(也就是将namespace改成当前第一步设置的Mapperxml的路径)
3、在Mapper接口中要去定义一个SQL映射文件中的id,并且参数类型和返回值要一直
4、编码
4.1 通过 sqlSession.getMapper( )方法
4.2 得到mapper对象后,直接通过mapper对象就去调用对应要使用的方法即可
注意:
注意哦,使用Mapper去扫描包后,要记得把SQL的映射给注销咯
4.MyBatis 核心配置文件
4.1 XML 映射配置文件
配置:
MyBatis 的配置文件包含了影响 MyBatis 行为的设置(settings)和属性(properties)信息。
在官网里面有很多,可以自行查看学习
4.1 配置环境(environments)
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。
通俗理解:可以在mybatis的配置环境中去,配置多个environment去连接多个
数据库,通过对应的default属性去切换对应的environment数据库即可。
4.2类型别名(typeAliases)
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
对比:
5. 配置文件增删改查
要求:
5.1 环境准备
1、先准备好需要的环境:
一个数据库表,一个实体类,和装一个插件
一个插件
5.2 查询
5.2.1 查询所有信息
步骤:
查询所有功能及注意事项:
<?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:名称空间(可以自己设置的哈)
id:sql语句的唯一标识
resultType:数据的返回类型
-->
<mapper namespace="com.xiaowang.mapper.BrandMapper">
<!--
数据库表的字段名称 和 实体类的属性名称 不一样,就不能自动封装数据
1.使用别名:对不一样的列名起别一个和实体类的一样即可
缺点:(每次查询都要定义别名,不方便)
解决:通过定义SQL片段
缺点:不灵活
<select id="selectAll" resultType="Brand">
select id,brand_name as brandName,company_name as companyName,ordered,description,status from tb_brand;
</select>
解决:
定义SQL片段
<sql id="brand_column">/*将所有的属性封装到一起就可以直接通过引用搞定*/
id,brand_name as brandName,company_name as companyName,ordered,description,status
</sql>
<select id="selectAll" resultType="Brand">
select
<include refid="brand_column"/>/*通过include去引用*/
from tb_brand;
</select>
2.resultMap,映射
步骤:①定义<resultMap>标签
②在<select>标签中,使用resultMap 替换 resultType
typy是确定的映射类型
result标签是普通属性
id标签是主键属性
column:列名
property:实体类属性名
-->
<resultMap id="brandResultMap" type="brand">
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
<!--<id></id>-->
<!--把不一样的属性,全部映射在这里,下面直接调用resultMap映射就行-->
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
select *
from tb_brand;
</select>
<!--<select id="selectAll" resultType="Brand">
select *
from tb_brand;
</select>-->
</mapper>
注意:
5.2.3查看详情
步骤:
查看详情功能及注意事项:
<?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:名称空间(可以自己设置的哈)
id:sql语句的唯一标识
resultType:数据的返回类型
-->
<mapper namespace="com.xiaowang.mapper.BrandMapper">
<!--查看详情-->
<!--
*参数占位符:
1.#{ } 会将其替换为 ? ,为了防止SQL注入
2.${ } 拼SQL 会存在SQL注入问题
3.使用时机:
参数传递的时候,都用 #{}
表名或列名,不固定情况下 用 ${}
*参数类型: parameterType="" 可以省略 因为接口里面有定义类型
是给#{}里面的参数做类型
*特殊字符处理:
1.转移字符: <(小于<符号的转移字符)
2.<![CDATA[
<
]]>
这个是在哪里输入 CD 就会自动补全.
<select id="selectById" resultMap="brandResultMap">
select *
from tb_Brand where id
<!–<(小于<符号的转移字符)–>
<![CDATA[
]]>
#{id};
</select>
-->
<select id="selectById" resultMap="brandResultMap">
select *
from tb_Brand where id= #{id};
</select>
</mapper>
注意:
5.2.4 条件查询
5.2.4.1 多条件查询
需求:
步骤:
方法一:
注解:
方法二:
实体类对象:
方法三:
Map键值对对象
Mapper.xml 映射 SQL语句:
<!--条件查询-->
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
Mapper接口:
package com.xiaowang.mapper;
import com.xiaowang.pojo.Brand;
import com.xiaowang.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @Author 小王
* @DATE: 2022/5/19
*/
public interface BrandMapper {
//1.查询所有
List<Brand> selectAll();
//2.查看详情
Brand selectById(int id);
//3.多表查询
/* 3.1通过注解查询,多个参数要用@Param
List<Brand> selectByCondition(@Param("status")int status,@Param("companyName")String companyName,@Param("brandName")String brandName);
*/
/*3.2通过brand对象,对象属性名称要和占位符的一致
List<Brand> selectByCondition(Brand brand);
*/
//3.3通过Map去查询
List<Brand> selectByCondition(Map map);
}
测试类:
/*@Test
//注解方式
public void testSelectByCondition() throws IOException {
//先定一个死的id,后面用的时候,是前端传入的
int status =1;
String companyName = "小";
String brandName = "小";
//处理参数
//因为映射那边的占位符是like,模糊类型,所以要通过“%”去处理一下参数
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.执行对应sql方法
List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
System.out.println(brands);
//5.释放资源
sqlSession.close();
}*/
/* @Test
//brand对象方式
public void testSelectByCondition() throws IOException {
//先定一个死的id,后面用的时候,是前端传入的
int status =1;
String companyName = "小";
String brandName = "小";
//处理参数
//因为映射那边的占位符是like,模糊类型,所以要通过“%”去处理一下参数
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.执行对应sql方法
List<Brand> brands = brandMapper.selectByCondition(brand);
System.out.println(brands);
//5.释放资源
sqlSession.close();
}*/
@Test
//Map对象
public void testSelectByCondition() throws IOException {
//先定一个死的id,后面用的时候,是前端传入的
int status =1;
String companyName = "小";
String brandName = "小";
//处理参数
//因为映射那边的占位符是like,模糊类型,所以要通过“%”去处理一下参数
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.执行对应sql方法
List<Brand> brands = brandMapper.selectByCondition(map);
System.out.println(brands);
//5.释放资源
sqlSession.close();
}
注意:
遇见的注意事项:
①数据库连接的时候,记得将字符集写上去characterEncoding=UTF-8
②对于like的模糊数据库语句,要用 “%” 去修饰