系列文章目录
IDEA项目实践------创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介
IDEWA项目实践------mybatis的一些基本原理以及案例
IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍_intellij 创建scala
文章目录
[一 动态SQL](#一 动态SQL)
[1.1 动态SQL概述](#1.1 动态SQL概述)
[1.2 if元素](#1.2 if元素)
[1.3 where 、set 、trim元素](#1.3 where 、set 、trim元素)
[1.3.1 where元素](#1.3.1 where元素)
[1.3.2 set 元素](#1.3.2 set 元素)
[1.3.3 trim 元素](#1.3.3 trim 元素)
[2. 元素模拟元素](#2. 元素模拟元素)
[1.4 choose 、when 、 otherwise 元素](#1.4 choose 、when 、 otherwise 元素)
[1.5 foreach元素](#1.5 foreach元素)
[1.6 bind 元素](#1.6 bind 元素)
[二 关系映射](#二 关系映射)
[2.1 关联关系概述](#2.1 关联关系概述)
[2.2 一对一级联查询](#2.2 一对一级联查询)
[2.2.1 准备工作(依赖和工具类)](#2.2.1 准备工作(依赖和工具类))
[2.2.2 创建数据库的表与实体类](#2.2.2 创建数据库的表与实体类)
[2.2.3 编写MyBatis配置文件与数据库配置文件](#2.2.3 编写MyBatis配置文件与数据库配置文件)
[2.2.4 创建Mapper接口与映射文件](#2.2.4 创建Mapper接口与映射文件)
[2.2.5 创建测试类](#2.2.5 创建测试类)
[2.3 一对多级联查询](#2.3 一对多级联查询)
[2.3.1 准备工作(依赖和工具类)](#2.3.1 准备工作(依赖和工具类))
[2.3.2 创建实体类和表](#2.3.2 创建实体类和表)
[2.3.3 编写MyBatis配置文件与数据库配置文件](#2.3.3 编写MyBatis配置文件与数据库配置文件)
[2.3.4 创建Mapper接口与映射文件](#2.3.4 创建Mapper接口与映射文件)
[2.3.5 创建测试类](#2.3.5 创建测试类)
[2.4 多对多级联查询](#2.4 多对多级联查询)
[2.4.1 准备工作(依赖和工具类)](#2.4.1 准备工作(依赖和工具类))
[2.4.2 创建实体类和表](#2.4.2 创建实体类和表)
[2.4.3 编写MyBatis配置文件与数据库配置文件](#2.4.3 编写MyBatis配置文件与数据库配置文件)
[2.4.4 创建Mapper接口与映射文件](#2.4.4 创建Mapper接口与映射文件)
[2.4.5 创建测试类](#2.4.5 创建测试类)
[2.5 三种关联映射总结](#2.5 三种关联映射总结)
[三 注解开发](#三 注解开发)
[3.1 注解开发概述](#3.1 注解开发概述)
[3.2 案例的实现步骤](#3.2 案例的实现步骤)
[3.2.1 导入依赖和工具类](#3.2.1 导入依赖和工具类)
[3.2.2 创建MyBatis配置文件和数据库配置文件](#3.2.2 创建MyBatis配置文件和数据库配置文件)
[3.2.3 创建实体类](#3.2.3 创建实体类)
[3.2.4 创建StudentMapper接口](#3.2.4 创建StudentMapper接口)
[3.2.5 编写测试类](#3.2.5 编写测试类)
前言
本文主要介绍MyBatis当中的动态SQL、关系映射、注解开发,以及相关的案例讲解。
一 动态SQL
动态SQL,即通过MyBatis 提供的各种标签对条件作出判断已实现动态拼接SQL语句。条件判断使用的表达式为OGNL表达式。
在项目开发中,动态SQL可以解决很多不确定因素导致的SQL语句不同的问题。动态SQL可以简单高效的进行编码。
注意事项
在mapper的动态SQL中如出现大于号,小于号,大于等于号,小于等于号,最好将其转换为实体符号,否则,XML可能会出现解析出错问题,特别是小于号 (<),在XML中绝对不能出现 ,否则一定出错
官方文档:mybatis -- MyBatis 3 | 动态 SQL
1.1 动态SQL概述
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
动态SQL是MyBatis提供的拼接SQL语句的强大机制。
元素 | 说明 |
---|---|
<if> | 判断某个条件是否符合,符合则拼接此SQL语句 |
<choose>、<when>、<otherwise> | 判断多个条件是否符合,符合则拼接此SQL语句 |
<where>、<set>、<trim> | 限定语句,用于限制SQL语句的格式 |
<foreach> | 循环语句,用于循环拼接SQL语句 |
<bind> | 命名元素,用于创建一个变量,以便后续重复使用 |
1.2 if元素
不确定多条件查询------ if、where 标签
- if 标签:条件判断
- test 属性:逻辑表达式
- where 标签
- 作用:
- 替换where关键字
- 会动态的去掉第一个条件前的 and
- 如果所有的参数没有值则不加where关键字
- 注意:需要给每个条件前都加上 and 关键字
<if>元素主要用于条件判断,如果此条件成功,则把此元素中的SQL语句拼接。<if>元素常用于where子句中条件的筛选。
示例:
sql
select * from tb_user where name = #{name} and age = #{age}
如果name属性与age属性有其中一个为空时,查询语句就会报错,为解决此问题,需要判断name与age属性是否为空,如果为空则不附加对应的筛选条件。利用<if>元素可以判断属性是否为空。
XML
<select id="selectUser" resultType="user">
select * from tb_user where
<if test="null != name and '' != name">
name = #{name}
</if>
<if test="null != age and '' != age">
and age = #{age}
</if>
</select>
使用Junit单元测试,同时通过日志,测试各种情况。
以下为小的模块讲解
此处的if里面的判断条件,可以多写个and,需要在where条件里面补充1=1恒等式解决只输入性别SQL语句错误的情况。
1.3 where 、set 、trim元素
1.3.1 where元素
<where>:当<where>元素中存在内容时,自动拼接"where"字符串,并且将<where>元素中的第一个"and"字符串删除;当<where>元素中没有内容时,将删除<where>元素自身,即不拼接"where"字符串。
XML
<select id="selectUser" resultType="user">
select * from tb_user
<where>
<if test="null != name and '' != name">
and name = #{name}
</if>
<if test="null != age and '' != age">
and age = #{age}
</if>
</where>
</select>
对1.2 里面的if元素那块代码的一种优化方法
1.3.2 set 元素
<set>用于更新操作的SQL语句的拼接。
<set>元素用于更新操作的SQL拼接,当<set>元素中存在内容时,自动拼接"set"字符串,并且将<set>元素中最后的","字符串删除。当<set>元素中没有内容时,<set>元素将会删除自身,即不拼接"set""字符串。此处需要注意的是,当"set"字符串被删除时,SQL语句会报错,此时可以在<set>元素中添加id=#{id}"来保持SQL始终有效。
XML
<update id="updateuser" >
update tb_user
<set>
<if test="null != name and '' != name">
name = #{name},
</if>
<if test="null != age and '' != age">
age = #{age},
</if>
</set>
where id = #{id}
</update>
两个字段之间使用逗号隔开,判断条件并不是书写的最后一个,通过set动态的删除最后设置的那个逗号。
1.3.3 trim 元素
<trim>元素的使用方法较复杂,拼装SQL语句的灵活性极强,可以模拟<where>、<set>的功能。
1.<trim>元素模拟<set>元素
通过<trim>元素的prefix属性,给需要拼接的SQL添加"set"字符串前缀,通过<trim>元素的suffixOverrides属性,将SQL语句最后的","字符串删除,完成<set>元素功能的模拟。
XML
<update id="updateuser" >
update tb_user
<trim prefix="set" suffixOverrides=",">
<if test="null != name and '' != name">
name = #{name},
</if>
<if test="null != age and '' != age">
age = #{age},
</if>
</trim>
where id = #{id}
</update>
2. <trim>元素模拟<where>元素
通过<trim>元素的prefix属性,为需要拼接的SQL添加"where"字符串前缀,通过<trim>元素的prefixOverrides属性,将SQL前面的"and"字符串删除,完成<where>元素功能的模拟
XML
<select id="selectUserTrim" resultType="user">
select * from tb_user
<trim prefixOverrides="and" prefix="where">
<if test="null != name and '' != name">
and name = #{name}
</if>
<if test="null != age and '' != age">
and age = #{age}
</if>
</trim>
</select>
1.4 choose 、when 、 otherwise 元素
不确定单个条件查询------choose (when, otherwise) 标签
<choose>元素表示选择拼接其中一段代码,其中需要使用<when>元素判断是否拼接此段代码,从上至下,只要有一个<when>元素符合条件,便拼接此段代码,退出<choose>元素;当所有<when>元素都不符合条件时,拼接<otherwise>元素中的代码。
XML
<select id="selectUserChoose" resultType="user">
select * from tb_user
<where>
<choose>
<when test="null != name">
and name = #{name}
</when>
<when test="null != age and '' != age">
and age = #{age}
</when>
<otherwise>
and id = #{id}
</otherwise>
</choose>
</where>
</select>
1.5 foreach元素
<foreach>元素中的collection属性负责引入需要循环的集合,open属性负责设置拼接SQL的前缀,close属性负责设置拼接SQL的后缀,separator属性负责设置每个循环中元素的分割符,item代表循环中的每一个元素,除此之外,还有index属性,代表此次循环的角标。
XML
<select id="selectUserForEach" resultType="user">
select * from tb_user where id in
<foreach collection="idList" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</select>
查询到的数据作为集合返回
循环里面传进去的参数为集合
映射文件传参的时候,单个是任意的字符可能会找不到,通过添加注解**@param("list")**获取
如果为string类型,也需要加入注解**@param("keyword")**
oreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值
foreach标签
foreach 标签:用来迭代任何可迭代的对象(如数组,集合)。
1.6 bind 元素
<bind>元素为命名元素,它可以创建一个变量井将其绑定到上下文中,方便后续重复使用,在以上代码中,使用<bind>元素设置了一个变量,值为'%'+name+'%',注意此时的name为从user类中获取的参数,并非name字符串。设置<bind>元素后,可以在上下文使用"#{}"引用。
XML
<select id="selectUserBind" resultType="user">
<bind name="bindName" value="'%'+name+'%'"/>
SELECT * FROM tb_user
<if test="age!=null">
/*相当于where name like '%'+#{name}+'%'*/
where name like #{bindeName}
</if>
</select>
二 关系映射
2.1 关联关系概述
表与表之间的关系可以分为三种,分别为"一对一","一对多"和"多对多"。
在"一对一"的关系中:A表中的一条数据只能与B表中的一条数据关联,反过来同样成立,比如学生卡与学生。
在"一对多""的关系中,A表中的一条数据可以与B表中多条数据关联,但是B表中的每个数据都只能有A表中的一条记录对应。比如班级和学生,每个班级对应多个学生,但是每个学生只能对应一个班级。
在"多对多"的关系中,A表中的一条数据可以与B表中的多条数据关联,B表中的每个数据可以与A表中的多条记录对应。比如老师和学生,一个学生可以对应多个老师,一个老师也可以对应多个学生。
【关联映射:本质上是告诉你多表查询的字段,如何映射到实体类的属性上。】
2.2 一对一级联查询
案例实现步骤
2.2.1 准备工作(依赖和工具类)
pom.xml:
XML
<?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.ambow</groupId>
<artifactId>mybatis07</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- mybatis的依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- mysql-connector-java 的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- lombok 的依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<!-- <scope>provided</scope>-->
</dependency>
<!-- junit的依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
定义一个MyBatisUtil工具类:
java
package com.ambow.util;
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;
public class MyBatisUtil {
private static SqlSessionFactoryBuilder builder;
private static SqlSessionFactory sqlSessionFactory;
//静态代码块 - 类加载的时候,只执行一次
static {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//获取SqlSessionFactory - 工厂对象
builder = new SqlSessionFactoryBuilder();
System.out.println(builder);
sqlSessionFactory = builder.build(inputStream);
System.out.println(sqlSessionFactory);
}
//获取SqlSession
public static SqlSession getSqlSession(){
//获取SqlSession - 连接对象
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
//关闭SqlSession
public static void closeSqlSession(SqlSession session){
if (session != null) {
session.close();
}
}
}
2.2.2 创建数据库的表与实体类
创建表和实体类
card表的建表语句:
sql
-- ----------------------------
-- Table structure for card
-- ----------------------------
DROP TABLE IF EXISTS `card`;
CREATE TABLE `card` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`card_number` int(11) DEFAULT NULL,
`sid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of card
-- ----------------------------
INSERT INTO `card` VALUES ('1', '178283992', '3');
INSERT INTO `card` VALUES ('2', '123624573', '2');
INSERT INTO `card` VALUES ('3', '234122212', '1');
student表的建表语句:
sql
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '张三', '3');
INSERT INTO `student` VALUES ('2', '李四', '2');
INSERT INTO `student` VALUES ('3', '王五', '1');
Card类:
java
package com.ambow.pojo;
import lombok.Data;
@Data
public class Card {
Integer id;
String cardNumber;
}
Student类:
java
package com.ambow.pojo;
import lombok.Data;
@Data
public class Student {
Integer id;
String name;
Card card; //每个学生都有一个学生卡 card
//Integer cid;
}
2.2.3 编写MyBatis配置文件与数据库配置文件
mybatis-config.xml:
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">
<!--MyBatis的核心配置文件-->
<configuration>
<properties resource="jdbc.properties" />
<!--设置-->
<settings>
<!--开启数据库日志检测-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名法-->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!--类型别名-->
<typeAliases>
<package name="com.ambow.pojo" />
</typeAliases>
<!--配置环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--配置映射器-->
<mappers>
<!-- 4.将包内的映射器接口实现全部注册为映射器【推荐】 -->
<package name="com.ambow.mapper" />
</mappers>
</configuration>
jdbc.properties:
XML
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
username=root
password=root
2.2.4 创建Mapper接口与映射文件
StudentMapper接口:
java
package com.ambow.mapper;
import com.ambow.pojo.Student;
import java.util.List;
public interface StudentMapper {
/*查询*/
List<Student> selectStudent();
}
StudentMapper.xml:
XML
<?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">
<mapper namespace="com.ambow.mapper.StudentMapper">
<resultMap id="studentMap" type="student">
<id column="id" property="id" />
<result column="name" property="name" />
<association property="card" javaType="card">
<id column="cid" property="id" />
<result column="card_number" property="cardNumber" />
</association>
</resultMap>
<select id="selectStudent" resultMap="studentMap">
SELECT s.id,name,cid,card_number
FROM student s JOIN card c
ON s.cid = c.id
</select>
</mapper>
2.2.5 创建测试类
java
package com.ambow.test;
import com.ambow.mapper.StudentMapper;
import com.ambow.pojo.Student;
import com.ambow.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class AssociateTest {
@Test
public void test01(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectStudent();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
}
2.3 一对多级联查询
案例实现步骤
2.3.1 准备工作(依赖和工具类)
pom.xml:
同上一案例
MyBatisUtil:
同上一案例
2.3.2 创建实体类和表
MyClass类:
java
package com.ambow.pojo;
import lombok.Data;
import java.util.List;
@Data
public class MyClass {
Integer id;
String className;
List<Student> student;
}
Student类:
java
package com.ambow.pojo;
import lombok.Data;
@Data
public class Student {
Integer id;
String name;
}
myclass表的建表语句:
sql
-- ----------------------------
-- Table structure for myclass
-- ----------------------------
DROP TABLE IF EXISTS `myclass`;
CREATE TABLE `myclass` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`class_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of myclass
-- ----------------------------
INSERT INTO `myclass` VALUES ('1', '一班');
INSERT INTO `myclass` VALUES ('2', '二班');
INSERT INTO `myclass` VALUES ('3', '三班');
student表的建表语句:
sql
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '张三', '1');
INSERT INTO `student` VALUES ('2', '李四', '2');
INSERT INTO `student` VALUES ('3', '王五', '1');
INSERT INTO `student` VALUES ('4', '赵六', '3');
INSERT INTO `student` VALUES ('5', '蜀七', '1');
INSERT INTO `student` VALUES ('6', '魏八', '3');
2.3.3 编写MyBatis配置文件与数据库配置文件
mybatis-config.xml:
同上一案例
jdbc.properties:
sql
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
username=root
password=root
2.3.4 创建Mapper接口与映射文件
MyClassMapper接口:
java
package com.ambow.mapper;
import com.ambow.pojo.MyClass;
import java.util.List;
public interface MyClassMapper {
/*查询*/
List<MyClass> selectMyClass();
}
MyClassMapper.xml:
XML
<?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">
<mapper namespace="com.ambow.mapper.MyClassMapper">
<resultMap id="myClassMap" type="myClass">
<id column="cid" property="id" />
<result column="class_name" property="className" />
<collection property="student" ofType="student">
<id column="sid" property="id" />
<result column="name" property="name" />
</collection>
</resultMap>
<select id="selectMyClass" resultMap="myClassMap">
SELECT c.id cid,class_name,s.id sid,`name`
FROM myclass c JOIN student s
ON c.id = s.cid
</select>
</mapper>
2.3.5 创建测试类
java
package com.ambow.test;
import com.ambow.mapper.MyClassMapper;
import com.ambow.pojo.MyClass;
import com.ambow.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class CollectionTest {
@Test
public void test01(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
MyClassMapper mapper = sqlSession.getMapper(MyClassMapper.class);
List<MyClass> myClasses = mapper.selectMyClass();
for (MyClass myClass : myClasses) {
System.out.println(myClass);
}
sqlSession.close();
}
}
2.4 多对多级联查询
案例实现步骤
2.4.1 准备工作(依赖和工具类)
pom.xml:
同上一案例
MyBatisUtil:
同上一案例
2.4.2 创建实体类和表
Student类:
java
package com.ambow.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Student {
Integer id;
String name;
List<Teacher> teachers;
}
Teacher类:
java
package com.ambow.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
Integer id;
String courseName;
String name;
List<Student> students;
}
student表的建表语句:
sql
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '张三');
INSERT INTO `student` VALUES ('2', '李四');
INSERT INTO `student` VALUES ('3', '王五');
teacher表的建表语句:
sql
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`course_name` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('1', '语文', '刘伟');
INSERT INTO `teacher` VALUES ('2', '语文', '张帅');
INSERT INTO `teacher` VALUES ('3', '数学', '赵凯');
INSERT INTO `teacher` VALUES ('4', '英语', '刘波');
INSERT INTO `teacher` VALUES ('5', '英语', '英丽');
student_teacher表的建表语句:
sql
-- ----------------------------
-- Table structure for student_teacher
-- ----------------------------
DROP TABLE IF EXISTS `student_teacher`;
CREATE TABLE `student_teacher` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`t_id` int(11) DEFAULT NULL,
`s_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student_teacher
-- ----------------------------
INSERT INTO `student_teacher` VALUES ('1', '1', '1');
INSERT INTO `student_teacher` VALUES ('2', '3', '1');
INSERT INTO `student_teacher` VALUES ('3', '5', '1');
INSERT INTO `student_teacher` VALUES ('4', '2', '2');
INSERT INTO `student_teacher` VALUES ('5', '3', '2');
INSERT INTO `student_teacher` VALUES ('6', '4', '2');
INSERT INTO `student_teacher` VALUES ('7', '1', '3');
INSERT INTO `student_teacher` VALUES ('8', '3', '3');
INSERT INTO `student_teacher` VALUES ('9', '4', '3');
2.4.3 编写MyBatis配置文件与数据库配置文件
mybatis-config.xml:
同上一案例
jdbc.properties:
sql
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
username=root
password=root
2.4.4 创建Mapper接口与映射文件
StudentMapper接口:
java
package com.ambow.mapper;
import com.ambow.pojo.Student;
import java.util.List;
public interface StudentMapper {
/*查询*/
List<Student> selectStudent();
}
StudentMapper.xml:
XML
<?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">
<mapper namespace="com.ambow.mapper.StudentMapper">
<resultMap id="studentMap" type="student">
<id column="sid" property="id" />
<result column="sname" property="name" />
<collection property="teachers" ofType="teacher">
<id column="tid" property="id" />
<result column="course_name" property="courseName" />
<result column="tname" property="name" />
</collection>
</resultMap>
<select id="selectStudent" resultMap="studentMap">
SELECT s.id sid,s.name sname,t.id tid,t.course_name,t.name tname
FROM student s join student_teacher st on st.s_id = s.id
join teacher t on t.id = st.t_id
ORDER BY s.id
</select>
</mapper>
2.4.5 创建测试类
java
package com.ambow.test;
import com.ambow.mapper.StudentMapper;
import com.ambow.pojo.Student;
import com.ambow.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class CollectionTest {
@Test
public void test01(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.selectStudent();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
}
2.5 三种关联映射总结
三种关联映射的实体类创建是不同,对应的查询条件是不一样的。
对于一对一关系,使用的是下面这一段,需要用到association和javatype来编写。
XML
<association property="card" javaType="card">
对于一对多和多对多他们两者采用的是下面的这一段,使用的是collection和oftype来书写。
XML
<collection property="student" ofType="student">
这是两者的区别。
还有一点在于创建实体类的时候,不同的对应关系创建的实体类是不同的,编写代码时要注意这两点区别与不同。
三 注解开发
3.1 注解开发概述
在MyBatis当中,除了XML映射文件创建SQL语句的方式,还可以通过注解直接编写SQL语句。使用注解开发时,无需创建映射文件,直接在Mapper接口文件的方法上通过注解编写SQL语句即可。MyBatis提供了若干注解来支持注解开发。
注解 | 说明 |
---|---|
@Select | 查询操作注解 |
@Insert | 插入操作注解 |
@Update | 更新操作注解 |
@Delete | 删除操作注解 |
@Param | 标注传入参数名称 |
在注解开发中,将注解直接放在Mapper接口文件的方法上,代表此方法对应的操作。
使用@Select注解完成查询功能的编写,查询的SQL语句直接写在注解中,其他注解,如修改、增加和删除注解,使用方法与@Select注解相同。
向SQL语句中传参的方式有三种:
传入对象:SQL语句通过对象中的属性名取值;
传入Map集合:SQL语句通过Map集合中的键来取值;
传入基本数据类型的参数,并通过@Param注解标注参数名:SQL语句通过@Param注解标注的参数名来取值;
只有一个参数的时候:sql语句在取值的时候,参数名可以任意
如果有两个参数,则参数的默认命名规则,如下:
默认参数名:arg0,arg1,...
默认参数名:param1,param2,...
在此需要注意的是,MyBatis注解开发 除了简单的增删改查外,还有一对多,多对多等级联查询的映射方法,因为一对多,多对多等问题需要复杂的配置,一般使用XML映射文件编写,在实际开发中,SQL语句比较复杂时,一般将注解方式与XML方式混合使用,复杂SQL使用XML映射文件编写,简单SQL使用注解开发。
总结:
-
简单SQL使用注解开发
-
复杂SQL使用XML映射文件编写
3.2 案例的实现步骤
3.2.1 导入依赖和工具类
pom.xml:
XML
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- mybatis的依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- mysql-connector-java 的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- lombok 的依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<!-- <scope>provided</scope>-->
</dependency>
<!-- junit的依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
工具类:
java
package com.ambow.util;
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;
public class MyBatisUtil {
private static SqlSessionFactoryBuilder builder;
private static SqlSessionFactory sqlSessionFactory;
//静态代码块 - 类加载的时候,只执行一次
static {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//获取SqlSessionFactory - 工厂对象
builder = new SqlSessionFactoryBuilder();
System.out.println(builder);
sqlSessionFactory = builder.build(inputStream);
System.out.println(sqlSessionFactory);
}
//获取SqlSession
public static SqlSession getSqlSession(){
//获取SqlSession - 连接对象
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
//关闭SqlSession
public static void closeSqlSession(SqlSession session){
if (session != null) {
session.close();
}
}
}
3.2.2 创建MyBatis配置文件和数据库配置文件
mybatis-config.xml
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">
<!--MyBatis的核心配置文件-->
<configuration>
<properties resource="jdbc.properties" />
<!--设置-->
<settings>
<!--开启数据库日志检测-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启驼峰命名法-->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!--类型别名-->
<typeAliases>
<package name="com.ambow.pojo" />
</typeAliases>
<!--配置环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--配置映射器-->
<mappers>
<!-- 4.将包内的映射器接口实现全部注册为映射器【推荐】 -->
<package name="com.ambow.dao" />
</mappers>
</configuration>
jdbc.properties
XML
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test3
username=root
password=root
3.2.3 创建实体类
java
package com.ambow.pojo;
import lombok.Data;
@Data
public class Student {
Integer id;
String name;
}
3.2.4 创建StudentMapper接口
java
package com.ambow.dao;
import com.ambow.pojo.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
public interface StudentMapper {
/*查询*/
@Select("select * from student")
List<Student> getAllStudent();
/*查询单个记录*/
/*
只有一个参数的时候:sql语句在取值的时候,参数名可以任意
*/
@Select("select * from student where id = #{testId}")
Student getStudentById(int testId);
//@Select("select * from student where id = #{id}")
//Student getStudentById(@Param("id") int testId);
/*新增*/
@Insert("insert into student (name) values(#{name})")
int addStudent(Student student);
/*修改*/
/*
如果有两个参数,则参数的默认命名规则,如下:
默认参数名:arg0,arg1,...
默认参数名:param1,param2,...
*/
//@Update("update student set name = #{arg1} where id = #{arg0}")
//@Update("update student set name = #{param2} where id = #{param1}")
//int updateStudent(int id,String name);
@Update("update student set name = #{name} where id = #{id}")
//int updateStudent(@Param("id") int id,@Param("name") String name);
int updateStudent(Map map);
/*删除*/
@Delete("delete from student where id = #{id}")
int deleteStudent(@Param("id") int id);
}
3.2.5 编写测试类
java
package com.ambow.test;
import com.ambow.dao.StudentMapper;
import com.ambow.pojo.Student;
import com.ambow.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
public class AnnotationTest {
@Test
public void test01(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.getAllStudent();
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
}
@Test
public void test02(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.getStudentById(1);
System.out.println(student);
sqlSession.close();
}
@Test
public void test03(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = new Student();
student.setName("Tom");
mapper.addStudent(student);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test04(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//mapper.updateStudent(5,"Tom");
HashMap map = new HashMap();
map.put("id",3);
map.put("name","Cat");
mapper.updateStudent(map);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test05(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
mapper.deleteStudent(5);
sqlSession.commit();
sqlSession.close();
}
}
总结
以上就是今天的内容~
欢迎大家点赞👍,收藏⭐,转发🚀,
如有问题、建议,请您在评论区留言💬哦。
最后:转载请注明出处!!!