Mybatis概述
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使 开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建 connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、 preparedStatemnt)配置起来,并通过java对象和statement中的sql进行映射生成 终执行的sql语句,后由mybatis框架执行sql并将结果映射成java对象并返回。
总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决 JDBC将结果集封装为Java对象的麻烦.
下图是MyBatis架构图:
(1)mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成 SqlSessionFactory,也就是SqlSession工厂
(2)基于SqlSessionFactory可以生成SqlSession对象
(3)SqlSession是一个既可以发送SQL去执行,并返回结果,类似于JDBC中的 Connection对象,也是Mybatis中至关重要的一个对象。
(4)Executor是SqlSession底层的对象,用于执行SQL语句
(5)MapperStatement对象也是SqlSession底层的对象,用于接收输入映射(SQL 语句中的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)
Mybatis实现
逆向工程
通过逆向工程生成sql语句。
第一步:导入generator原始文件,并修改generatorConfig.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<!-- JavaBean 实现 序列化 接口 -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin">
</plugin>
<!-- genenat entity时,生成toString -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<!-- 共用5处要修改 -->
<!--修改1: 数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mall" userId="root"
password="root">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL
和 NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--修改2: targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.tedu.jtmall.pojo"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--修改3: targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.tedu.jtmall.mapper"
targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 修改4: targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.tedu.jtmall.mapper" targetProject=".\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!--修改5: 指定数据库表 -->
<table tableName="category" />
<table tableName="item" />
<table tableName="user" />
<table tableName="jt_order" />
<table tableName="admin" />
</context>
</generatorConfiguration>
第二步:执行GeneratorApp生成xml和实体类
执行GeneratorApp后,选中项目右键refresh,查看生成的xml和类如下图:
实现CRUD操作
第一步:复制逆向工程生成的Mapper接口和xml文件以及pojo实体类
第二步:主程序上添加包扫描@MapperScan("...")
package com.tedu.mybatis02_multiTable;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//框架为com.tedu.jtmall.mapper包下的接口自动创建代理对象
@MapperScan("com.tedu.mybatis02_multiTable.mapper")
public class Mybatis02MultiTableApplication {
public static void main(String[] args) {
SpringApplication.run(Mybatis02MultiTableApplication.class, args);
}
}
第三步:配置yml文件
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
username: root
password: root
mybatis:
mapperLocations: classpath:com.tedu.jtmall.mapper/*.xml
logging:
path: ./logs
level:
com.tedu.jtmall.mapper: debug
第四步:创建控制层CategoryController类,完成查询操作
1.创建CategoryController类
package com.tedu.mybatis02_multiTable.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tedu.mybatis02_multiTable.mapper.CategoryMapper;
import com.tedu.mybatis02_multiTable.pojo.Category;
@RestController
public class CategoryController {
@Autowired
CategoryMapper categoryMapper;
@RequestMapping("/cat")
public Category cat() {
return categoryMapper.selectCategory(1);
}
}
2.编辑查看xml文件
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace的值是接口所在的包名+接口名 -->
<mapper
namespace="com.tedu.mybatis02_multiTable.mapper.CategoryMapper">
<!-- 1,映射:结果集和类的映射 type:商品分类类名 id:自命名 -->
<resultMap type="com.tedu.mybatis02_multiTable.pojo.Category"
id="categoryMap">
<result column="category_id" property="categoryId" />
<result column="category_name" property="categoryName" />
<!-- 一个分类下有多个商品 ofType:商品的类名 -->
<collection property="itemList"
ofType="com.tedu.mybatis02_multiTable.pojo.Item">
<result column="item_name" property="itemName"/>
</collection>
</resultMap>
<!-- 2,sql语句
id必须和方法名一致-->
<select id="selectCategory" resultMap="categoryMap" parameterType="Integer">
SELECT category.category_id,category_name,item_name
FROM category,item
WHERE category.category_id=#{categoryId}
AND item.category_id=category.category_id
</select>
</ma
MybatisPlus+Lombok
利用MP可,可有spring自动生成xml文件,切接口中底层已自定义基本的CRUD方法,可省略。
Lombok可在pojo类上添加注解,自动生成get、set、构造函数等方法。
第一步:添加Lombok、MP核心库、springboot整合mp的依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tedu</groupId>
<artifactId>mybatis04_plus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis04_plus</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- mybatisplus与springboot整合 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<!-- MP 核心库 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
第二步:pojo类上添加@Data注解,自动生成get、set方法
package com.tedu.mybatis04_plus.pojo;
import lombok.Data;
@Data//lombok会为User生成set,get
//从网上下载代码,如果发现实体类没有set(),get(),加了@data,
//说明项目用了lombok
public class User {
Integer userId;
}
第三步:pojo类上添加注解实现MP
package com.tedu.mybatis04_plus.pojo;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;
//对应catepory表
//实现映射,以前是在CategoryMapper.xml中实现
@Data
@TableName("category")
public class Category {
//映射到category_id列
//以前是在xml中写rsult column=category_id property=categoryId
@TableField("category_id")
Integer categoryId;
@TableField("category_name")
String categoryName;
}
第四步:创建接口CategoryMapper继承BaseMapper<pojo>
package com.tedu.mybatis04_plus.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.tedu.mybatis04_plus.pojo.Category;
//以前为们要写insert(),delete(),update(),select()
//BaseMapper中有insert(),delete(),update(),select()
public interface CategoryMapper extends BaseMapper<Category>{
}
第五步:创建CategoryController类
package com.tedu.mybatis04_plus.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.tedu.mybatis04_plus.mapper.CategoryMapper;
import com.tedu.mybatis04_plus.pojo.Category;
@RestController
public class CategoryController {
@Autowired
CategoryMapper categoryMapper;
@RequestMapping("/select")
public List<Category> select(){
//设置排序
EntityWrapper<Category> wrapper=new EntityWrapper();
wrapper.orderBy("category_id desc");
//调用baseMapper中的selectList()
return categoryMapper.selectList(wrapper);
}
}
第六步:创建启动类Mybatis04PlusApplication
package com.tedu.mybatis04_plus;
import java.lang.reflect.Method;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.tedu.mybatis04_plus.pojo.User;
@MapperScan("com.tedu.mybatis04_plus.mapper")
@SpringBootApplication
public class Mybatis04PlusApplication {
public static void main(String[] args) {
SpringApplication.run(Mybatis04PlusApplication.class, args);
//测试User类有没有set(),get()
User user=new User();
user.setUserId(6688);
System.out.println(user.getUserId());
Class clazz=User.class;
Method[] methods=clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
}
}
动态sql
<if> 标签:是根据 test属性 中的布尔表达式的值,从而决定是否执行包 含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果 结果为false,则不执行其中的SQL片段
<where> 标签:用于对包含在其中的SQL片段进行检索,在需要时可以生 成where关键字,并且在需要时会剔除多余的连接词(比如and或者or)
foreach 标签:可以对传过来的参数数组或集合进行遍历,以下是foreach标签 上的各个属性介绍
第一步:创建springboot项目mybatis03_dynamicSql
第二步:创建Item实体类
package com.tedu.mybatis03_dynamicsql.pojo;
//对应item表
@Data
public class Item {
Integer itemId;
String itemName;
第三步:创建Mapper接口
package com.tedu.mybatis03_dynamicsql.mapper;
//操作Item表的
import java.util.List;
import com.tedu.mybatis03_dynamicsql.pojo.Item;
public interface ItemMapper {
//如果返回的是多个数据,加个list
public List<Item> select(Item item);
//查询多个商品
public List<Item> list(List<Integer> idList);
}
第四步:启动类上添加包扫描@MapperScan("...")
@SpringBootApplication
@MapperScan("com.tedu.dynamicSql.mapper")
public class DynamicSqlApplication {
public static void main(String[] args) {
SpringApplication.run(DynamicSqlApplication.class, args);
}
}
第五步:创建控制层ItemController
package com.tedu.mybatis03_dynamicsql.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tedu.mybatis03_dynamicsql.mapper.ItemMapper;
import com.tedu.mybatis03_dynamicsql.pojo.Item;
@RestController
public class ItemController {
//从spring ioc的容器中获取代理对象
@Autowired
ItemMapper itemMapper;
@RequestMapping("/item")
public List<Item> select(Item item){
return itemMapper.select(item);
}
@RequestMapping("/list")
public List<Item> list(){
ArrayList<Integer> idList=new ArrayList<Integer>();
idList.add(2);
idList.add(3);
return itemMapper.list(idList);
}
}
第六步:创建xml文件
<!-- copy9.4.6 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的全名称 -->
<mapper
namespace="com.tedu.mybatis03_dynamicsql.mapper.ItemMapper">
<!-- id必须和接口中的方法名一致 -->
<!-- mybatis矿建判断结果集如果是多行,自动创建list -->
<select id="select"
parameterType="com.tedu.mybatis03_dynamicsql.pojo.Item"
resultType="com.tedu.mybatis03_dynamicsql.pojo.Item">
SELECT item_id AS itemId,
item_name AS itemName
FROM item
<!-- 用户可以根据分类的id,商品id,商品名称,商品价格 Item中包含的是查询条件 判断item中有没有商品id,如果有加上item_id=1
判断item中有没有商品名称,如果有加上and item_name like '%itemName%' -->
<where>
<if test="itemId !=null">
item_id=#{itemId}
</if>
<!-- concat是mysql函数,实现字符串相加,每个字符串中间用,分隔空开 -->
<if test="itemName !=null">
and item_name like concat('%',#{itemName},'%')
</if>
</where>
</select>
<!-- id必须和方法名一样 -->
<select id="list"
parameterType="Integer"
resultType="com.tedu.mybatis03_dynamicsql.pojo.Item">
SELECT item_id AS itemId,
item_name AS itemName
FROM item
<where>
<!-- 遍历idList集合,取出来的数据叫id (2,3) -->
item_id in
<foreach collection="idList" item="id" open="(" separator=","
close=")">
#{id}
</foreach>
</where>
</select>
</mapper>
占位符#{}和${}的区别
1.#{}相当于JDBC中的问号(?)占位符,是为SQL语句中的参数值进行占位,大部分情况下都是使用#{}占位符;并且当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号);
2.${}是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在占位符所在的位置,不会进行任何的转义处理.(由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题)
在mapper文件中: select * from emp where name=#{name}
在程序执行时: select * from emp where name=?
参数:王海涛,将参数传入,替换占位符
select * from emp where name=王海涛; -- 错误
select * from emp where name=‘王海涛’; -- 正确
需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。