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


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.7.2version>
        <relativePath/> 
    parent>
    <groupId>com.daigroupId>
    <artifactId>springboot-webartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>springboot-webname>
    <description>Demo project for Spring Bootdescription>
    <properties>
        <java.version>1.8java.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.6version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.logging.log4jgroupId>
            <artifactId>log4j-apiartifactId>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-autoconfigureartifactId>
            <version>2.2.2version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.7version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.9version>
        dependency>
    dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>

        <resources>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
            resource>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                    <include>**/*.ymlinclude>
                includes>
                <filtering>truefiltering>
            resource>
        resources>
    build>
project>

2.配置文件mybatis-config.xml

连接数据库


DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    
    <environments default="development">

        <environment id="development">
            
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?userSSL=false&useUnicode=true&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>

方式二


<mppers>
	<mpper class="com.dai.mapper.UserMapper"/>
mppers>

注意

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


<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


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">
    
    <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>log4jgroupId>
    <artifactId>log4jartifactId>
    <version>1.2.17version>
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按照查询嵌套处理


<select id="getStudent" resultMap="StudentTeacher">
    select * from student
select>
<resultMap id="StudentTeacher" type="student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    
    <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"/>

        
        <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


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


<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标签引用即可


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

你可能感兴趣的:(笔记,mybatis,spring,boot,学习)