IDEA项目实践——动态SQL、关系映射、注解开发

系列文章目录

IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介

IDEWA项目实践——mybatis的一些基本原理以及案例

IDEA项目实践——动态SQL、关系映射、注解开发

IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍_intellij 创建scala

文章目录

系列文章目录

前言

一 动态SQL

1.1 动态SQL概述

 1.2 if元素

1.3 where 、set 、trim元素 

1.3.1 where元素

1.3.2 set 元素

1.3.3 trim 元素

 1.元素模拟元素

2. 元素模拟元素

1.4 choose 、when 、 otherwise 元素

1.5 foreach元素

foreach标签

1.6 bind 元素

 二 关系映射

2.1 关联关系概述

2.2 一对一级联查询

2.2.1 准备工作(依赖和工具类)

2.2.2 创建数据库的表与实体类

2.2.3 编写MyBatis配置文件与数据库配置文件

2.2.4 创建Mapper接口与映射文件

2.2.5 创建测试类

2.3 一对多级联查询

2.3.1 准备工作(依赖和工具类)

2.3.2 创建实体类和表

2.3.3 编写MyBatis配置文件与数据库配置文件

2.3.4 创建Mapper接口与映射文件

2.3.5 创建测试类

2.4 多对多级联查询

2.4.1 准备工作(依赖和工具类)

2.4.2 创建实体类和表

2.4.3 编写MyBatis配置文件与数据库配置文件

2.4.4 创建Mapper接口与映射文件

2.4.5 创建测试类

2.5 三种关联映射总结

三 注解开发

3.1 注解开发概述

3.2 案例的实现步骤

3.2.1 导入依赖和工具类

3.2.2 创建MyBatis配置文件和数据库配置文件

3.2.3 创建实体类

3.2.4 创建StudentMapper接口

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 标签
    •  作用:
      1. 替换where关键字
      2. 会动态的去掉第一个条件前的 and
      3. 如果所有的参数没有值则不加where关键字
      4. 注意:需要给每个条件前都加上 and 关键字

<if>元素主要用于条件判断,如果此条件成功,则把此元素中的SQL语句拼接。<if>元素常用于where子句中条件的筛选。

示例:

select * from tb_user where name = #{name} and age = #{age}

如果name属性与age属性有其中一个为空时,查询语句就会报错,为解决此问题,需要判断name与age属性是否为空,如果为空则不附加对应的筛选条件。利用<if>元素可以判断属性是否为空。

<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"字符串。 

<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始终有效。 

<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>元素功能的模拟。

<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>元素功能的模拟

<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>元素中的代码。

<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属性,代表此次循环的角标。

<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>元素后,可以在上下文使用“#{}“引用。

<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 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工具类:

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表的建表语句:

-- ----------------------------
-- 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表的建表语句:

-- ----------------------------
-- 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类:

package com.ambow.pojo;

import lombok.Data;

@Data
public class Card {
    Integer id;
    String cardNumber;
}

Student类:

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 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:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
username=root
password=root

2.2.4 创建Mapper接口与映射文件

StudentMapper接口:

package com.ambow.mapper;

import com.ambow.pojo.Student;

import java.util.List;

public interface StudentMapper {
    /*查询*/
    List<Student> selectStudent();
}

StudentMapper.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 创建测试类

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类:

package com.ambow.pojo;
​
import lombok.Data;
​
import java.util.List;
​
@Data
public class MyClass {
    Integer id;
    String className;
    List<Student> student;
}

Student类:

package com.ambow.pojo;
​
import lombok.Data;
​
@Data
public class Student {
    Integer id;
    String name;
}

myclass表的建表语句:

-- ----------------------------
-- 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表的建表语句:

-- ----------------------------
-- 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:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
username=root
password=root

2.3.4 创建Mapper接口与映射文件

MyClassMapper接口:

package com.ambow.mapper;
​
import com.ambow.pojo.MyClass;
​
import java.util.List;
​
public interface MyClassMapper {
    /*查询*/
    List<MyClass> selectMyClass();
}

MyClassMapper.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 创建测试类

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类:

package com.ambow.pojo;
​
import lombok.Data;
​
import java.util.List;
​
@Data
public class Student {
    Integer id;
    String name;
    List<Teacher> teachers;
}

Teacher类:

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表的建表语句:

-- ----------------------------
-- 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表的建表语句:

-- ----------------------------
-- 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表的建表语句:

-- ----------------------------
-- 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:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
username=root
password=root

2.4.4 创建Mapper接口与映射文件

StudentMapper接口:

package com.ambow.mapper;
​
import com.ambow.pojo.Student;
​
import java.util.List;
​
public interface StudentMapper {
    /*查询*/
    List<Student> selectStudent();
}

StudentMapper.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 创建测试类

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来编写。

<association property="card" javaType="card">

对于一对多和多对多他们两者采用的是下面的这一段,使用的是collection和oftype来书写。

<collection property="student" ofType="student">

这是两者的区别。

还有一点在于创建实体类的时候,不同的对应关系创建的实体类是不同的,编写代码时要注意这两点区别与不同。

三 注解开发

3.1 注解开发概述

在MyBatis当中,除了XML映射文件创建SQL语句的方式,还可以通过注解直接编写SQL语句。使用注解开发时,无需创建映射文件,直接在Mapper接口文件的方法上通过注解编写SQL语句即可。MyBatis提供了若干注解来支持注解开发。

注解说明
@Select查询操作注解
@Insert插入操作注解
@Update更新操作注解
@Delete删除操作注解
@Param标注传入参数名称

 在注解开发中,将注解直接放在Mapper接口文件的方法上,代表此方法对应的操作。

使用@Select注解完成查询功能的编写,查询的SQL语句直接写在注解中,其他注解,如修改、增加和删除注解,使用方法与@Select注解相同。 

向SQL语句中传参的方式有三种:

  1. 传入对象:SQL语句通过对象中的属性名取值;

  2. 传入Map集合:SQL语句通过Map集合中的键来取值;

  3. 传入基本数据类型的参数,并通过@Param注解标注参数名:SQL语句通过@Param注解标注的参数名来取值;

    1. 只有一个参数的时候:sql语句在取值的时候,参数名可以任意

    2. 如果有两个参数,则参数的默认命名规则,如下:

      • 默认参数名:arg0,arg1,...

      • 默认参数名:param1,param2,...

在此需要注意的是,MyBatis注解开发除了简单的增删改查外,还有一对多,多对多等级联查询的映射方法,因为一对多,多对多等问题需要复杂的配置,一般使用XML映射文件编写,在实际开发中,SQL语句比较复杂时,一般将注解方式与XML方式混合使用,复杂SQL使用XML映射文件编写,简单SQL使用注解开发。

总结:

  • 简单SQL使用注解开发

  • 复杂SQL使用XML映射文件编写

3.2 案例的实现步骤

3.2.1 导入依赖和工具类

pom.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>

工具类:

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 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

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test3
username=root
password=root

3.2.3 创建实体类

package com.ambow.pojo;
​
import lombok.Data;
​
@Data
public class Student {
    Integer id;
    String name;
​
}

3.2.4 创建StudentMapper接口

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 编写测试类

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();
    }
}
​

总结

以上就是今天的内容~

欢迎大家点赞👍,收藏⭐,转发🚀,
如有问题、建议,请您在评论区留言💬哦。

最后:转载请注明出处!!!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 IntelliJ IDEA 中创建一个包含 SQL 数据库的网站,可以按照以下步骤进行操作: 1. 创建一个新的 Maven 项目:在 IntelliJ IDEA 中选择 File -> New -> Project,选择 Maven 项目类型,然后按照向导式操作来创建项目。 2. 配置项目依赖:在 pom.xml 文件中添加所需的依赖,例如 JDBC 驱动、Web 框架、模板引擎等。 3. 配置数据库连接:在 IntelliJ IDEA 中选择 View -> Tool Windows -> Database,然后在窗口中添加一个新的数据库连接。在连接设置中,需要填写数据库类型、主机名、端口号、用户名、密码等信息。 4. 创建数据库表:在数据库连接中,可以通过 SQL 编辑器来创建表、插入数据等。例如可以创建一个名为 users 的表,包含 id、name、email 等字段。 5. 创建网站页面:在项目中创建一个 Web 页面,例如 index.jsp,然后在页面中使用 JSTL 或者其他模板引擎来查询数据库数据并展示在页面中。例如可以查询 users 表中的数据,并将数据展示在页面中。 6. 实现数据操作功能:在项目中创建一个 Servlet,例如 UserServlet,然后在 Servlet 中实现数据操作的功能,例如查询、添加、修改、删除等。在 Servlet 中可以使用 JDBC 来连接数据库,并执行 SQL 语句来实现数据操作。 7. 部署项目:在 IntelliJ IDEA 中选择 Run -> Edit Configurations,然后创建一个新的 Tomcat 配置,将项目部署到 Tomcat 中运行。 总之,通过以上步骤,可以在 IntelliJ IDEA 中创建一个包含 SQL 数据库的网站,并实现数据操作的功能。当然,具体的实现方式还需要根据具体的需求来进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小鱼༒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值