IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【springboot-Mybatis学习01】 -> 正文阅读

[Java知识库]【springboot-Mybatis学习01】

1.创建项目

groupid和artifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找。
groupId和artifactId是maven管理项目包时用作区分的字段,就像是地图上的坐标。
artifactId:artifactId一般是项目名或者模块名。
groupId:groupId分为几个字段,例如cn.com.fullstack,前面的com叫【域】,后面的是你自己起的域名。
groupId一般分为多个段,这里我只说两段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。举个apache公司的tomcat项目例子:这个项目的groupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,artigactId是tomcat。

<?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.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dai</groupId>
    <artifactId>springboot-web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-web</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-autoconfigure</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
<!--添加资源访问配置-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.yml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

2.配置文件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核心配置文件-->
<configuration>
    <!--    -->
    <environments default="development">

        <environment id="development">
            <!--            事物管理 默认使用JDBC-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--驱动-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?userSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/dai/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

将UserMapper.xml配置到mybatis-config.xml文件中

    <mappers>
        <mapper resource="com/dai/mapper/UserMapper.xml"/>
    </mappers>

2.1映射器mappers

方式一

<!-- 使用相对于类路径的资源引用 -->
<mappers>
	<mapper resource="com/dai/mapper/UserMapper.xml"/>
</mappers>

方式二

<!--每个Mapper.XML都需要在Mybatis核心配置文件中注册-->
<mppers>
	<mpper class="com.dai.mapper.UserMapper"/>
</mppers>

注意

接口和他的Mapper配置文件必须同名!!
接口和他的Mapper配置文件必须要在同一个包下!!
方式三

<!--每个Mapper.XML都需要在Mybatis核心配置文件中注册-->
<mppers>
	<package  name="com.dai.mapper"/>
</mppers>

接口和他的Mapper配置文件必须同名!!
接口和他的Mapper配置文件必须要在同一个包下!!

3.MybatisUtils工具类

从mybatis-config.xml文件中获取数据源,创建sqlSessionFactory中获取sqlSession实例。

package com.dai.utils;

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 MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static{
        try {
            //使用Mybatis第一步获取:sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //既然有了SqlSessionFactory,顾名思义,我们就可以从中获取SqlSession的实例
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

3.1、作用域(Scope)和生命周期

生命周期,和作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBuilder
一旦创建了SqlSessionFactory,就不需要他了
局部变量
SqlSessionFactory
说白了就是可以想象为:数据库连接池
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
因此 SqlSessionFactory 的最佳作用域是应用作用域
最简单的就是使用单例模式或者静态单例模式。
SqlSession
连接到连接池的一个请求
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
用完之后要赶紧关闭,否则资源被占用

4.entity类

package com.dai.entity;
public class User {
    Integer id;
    String name;
    String pwd;

    public User() {

    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

5.UserMapper接口

package com.dai.mapper;

import com.dai.entity.User;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserMapper {
    /**
     * 根据id查询用户信息
     * @param id
     * @return
     */
    User getUserInfo(int id);
    /**
     * 新增用户
     * @param user
     * @return
     */
    int save (User user);

    /**
     * 更新用户信息
     * @param user
     * @return
     */
    int update (User user);

    /**
     * 根据id删除
     * @param id
     * @return
     */
    int deleteById (int id);

    /**
     * 查询所有用户信息
     * @return
     */
    List<User> selectAll ();
    /**
     * 查询所有用户信息
     * @return
     */
    List<User> getUserList();
}

6.UserMapper.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.dai.mapper.UserMapper">
<-----接口方法------返回数据类型>
    <select id="getUserList" resultType="com.dai.entity.User">
        select * from mybatis.user
    </select>
    <select id="getUserById" parameterType="int" resultType="com.dai.entity.User" >
    select * from mybatis.user where id = #{id};
</select>
    <select id="getUserById" parameterType="int" resultType="com.dai.entity.User" >
        select * from mybatis.user where id = #{id};
    </select>
    <update id="updateUSer" parameterType="com.dai.entity.User">
        update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
    </update>
    <delete id="delUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

7. MyTest测试类

package com.dai;

import com.dai.entity.User;
import com.dai.mapper.UserMapper;
import com.dai.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class MyTest {
    @Test
    public void test(){
        //第一步: 获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userDao = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userDao.getUserList();
        for(User user : userList){
            System.out.println(user);
        }
        //关闭SqlSession
        sqlSession.close();
    }

}

8.易错点

配置文件没有注册
绑定接口错误
方法名不对
返回类型不对 resultType
Maven导出资源问题

标签不匹配的错误
resource绑定mapper,需要使用路径
程序配置文件必须符合规范!
NullPointerException,没有注册资源 例作用域问题
输出的xml文件中存在中文乱码问题
maven资源没有导出问题!

9.resultMap 结果集映射

<!--结果集映射-->
<resultMap id="UserMap" type="user">
    <!--column数据库的字段,property实体类的属性-->
    <result column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="pwd" property="password"/>
</resultMap>

<select id="getUserById" parameterType="int" resultMap="UserMap" >
   select * from mybatis.user where id = #{id};
</select>

resultMap元素是MyBatis中最重要最强大的元素
ResultMap的设计思想是,对于简单的语句根本不需要配置显示的结果映射,而对于复杂一点的语句只需要描述他们的关系就行了
ResultMap 最优秀的地方在于,虽然你已经对他相当了解了,但你根本就不需要显示的用到他们
如果世界总是这么简单就好了

10.日志工厂

SLEF4
LOG4J 【掌握】
LOG4J2
JDK_LOGGING
COMMONS_LOGGING
STDOUT_LOGGING【掌握】
NO_LOGGING

    <!--日志文件-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

导包

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

日志格式配置log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger = DEBUG,console ,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern =  [%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = ./log/kun.log
log4j.appender.file.MaxFileSize = 10mb
log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = [%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
    <!--日志文件-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

使用log4j日志
1.在要使用Log4j的类中,导入包import org.apache.log4j.Logger;
2.日志对象,参数为当前类的class

static Logger logger = Logger.getLogger(UserMapper.class);

3.日志级别

logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");

11.多对一结果映射

多个学生,对应老师
对于这边而言,关联。。 多个学生,关联一个老师【多对一】
对于老师而言,集合。。 一个老师,有很多学生 【一对多】

11.1按照查询嵌套处理

<!--
     思路:
        1. 查询所有的学生信息
        2. 根据查询出来的学生的tid寻找特定的老师 (子查询)
-->
<select id="getStudent" resultMap="StudentTeacher">
    select * from student
</select>
<resultMap id="StudentTeacher" type="student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!--复杂的属性,我们需要单独出来 对象:association 集合:collection-->
    <collection property="teacher" column="tid" javaType="teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="teacher">
    select * from teacher where id = #{id}
</select>

11.2按照结果嵌套 处理

<!--按照结果进行查询-->
<select id="getStudent2" resultMap="StudentTeacher2">
    select s.id sid , s.name sname, t.name tname
    from student s,teacher t
    where s.tid=t.id
</select>
<!--结果封装,将查询出来的列封装到对象属性中-->
<resultMap id="StudentTeacher2" type="student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="teacher">
        <result property="name" column="tname"></result>
    </association>
</resultMap>

12.一对多处理

12.1按照查询嵌套处理

<!--(子查询)-->
    <select id="getTeacher2" resultMap="TeacherStudent2">
        select * from mybatis.teacher where id=#{tid};
    </select>

    <resultMap id="TeacherStudent2" type="Teacher">
        <collection property="students" javaType="ArrayList" ofType="Student" select="getStudent" column="id"/>
    </resultMap>
    <select id="getStudent" resultType="Student">
        select * from mybatis.student where tid=#{tid};
    </select>

12.2按照结果嵌套查询

    <!--按照结果嵌套处理-->
    <select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid, s.name sname, t.name tname, t.id tid
        from student s, teacher t
        where s.tid = t.id and t.id=#{tid}
    </select>

    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>

        <!--复杂的属性,我们需要单独出来 对象:association 集合:collection

        指定的属性类型使用 javaType=""
        集合中的泛型信息使用 ofTYpe=" " 获取
        -->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

总结

小结:
关联 - association 【多对一】
集合 - collection 【对多】
JavaType & ofType
JavaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型
注意点:
尽量保证SQL的可读性,尽量保证通俗易懂
注意一对多、多对一中,属性名和字段问题!!
如果问题不好排除,可以使用日志~ 建议Log4j 【其实默认的也够用了】

13.动态SQL

13.1if

<!--parameterType 输入类型
        resultType    返回结果集
    -->
<select id="queryBlogIF" parameterType="map" resultType="blog">
    select * from mybatis.blog where 1=1
    <if test="title != null">
        and title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</select>

13.2choose (when,otherwise)

<select id="queryBlogChoose" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <choose>
            <when test="title != null">
                title = #{title}
            </when>
            <when test="author != null">
                and author = #{author}
            </when>
            <otherwise>
                and views=#{views}
            </otherwise>
        </choose>
    </where>
</select>

13.3trim (where, set)

<!-- where标签  会去除多余的 “AND” 或 “OR”,或 "where" -->
<select id="queryBlogIF" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </where>
</select>

所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码

13.4sql片段

1.使用SQL标签抽取公共部分

<sql id="sql-if-title-author">
    <if test="title != null">
        title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</sql>

2.在需要使用的地方使用Include标签引用即可

<!--parameterType 输入类型
        resultType    返回结果集
    -->
<select id="queryBlogIF" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <include refid="sql-if-title-author"/>
    </where>
</select>

注意:
最好基于单表定义SQL片段!!
sql标签不要存在where标签 因为他是动态的

13.5Foreach

select * from user where 1=1 and 
<foreach item="id" collection="ids" open="(" separator="or" close=")">
	#{id}
</foreach>
(id=1 or id=2 or id=3)

<!--
        集合 select * from user where 1=1 and (id=1 or id=2 or id=3)

        我们现在传递一个万能的map,这map可以存在一个集合!
        collection:集合      item:集合里的数据
    -->
<select id="queryBlogForeach" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <foreach item="id" collection="ids" open="and (" separator="or" close=")">
            id=#{id}
        </foreach>
    </where>
</select>

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:38:26  更:2022-09-30 00:40:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/25 5:39:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码