MyBatis框架

2023-05-16

MyBatis学习结构

1. MyBatis框架简介

  • MyBatis是一款优秀的持久层框架

  • 它支持定制化SQL、存储过程以及高级映射。

  • MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。

  • MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的 POJO(Plain Old JavaObjects,普通老式Java对象)为数据库中的记录。

  • MyBatis 本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。

  • 2013年11月迁移到Github。

  • MyBatis是一个开源、轻量级的数据持久化框架,它是JdbcTemplate和Hibernate的替代方案。

1.1 Mybatis配置依赖

MyBatis不是Spring框架提供可以独立于Spring容器,MyBatis也可以结合Spring容器一起使用,导入依赖:

<!-- MyBatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.10</version>
</dependency>
<!-- MyBatis-Spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>

数据持久化: 持久化就是将程序的数据在持久状态和瞬时状态转化的过程 内存:断电即失 数据库(jdbc),io文件持久化

1.2 为什么使用MyBatis?

  • 方便

  • 帮助程序员将数据存入数据库

  • 传统的JDBC代码太过于复杂。mybatis简化,框架,自动化。

  • 不用mybatis也可以。mybatis更容易上手

  • 优点:

    • 简单易学。

    • 灵活

    • sql和代码的分离,提高了可维护性。

    • 提供映射标签,支持对象与数据库的orm字段关系映射。

    • 提供对象关系映射标签,支持对象关系组建维护。

    • 提供xml标签,支持编写动态sql。

最重要的是:使用的人较多

2. 第一独立的MyBatis程序(单个mybatis使用不涉及spring)

以往自己做的MyBatis独立程序:

2.1 新建一个maven项目,并导入依赖

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
</dependency>

2.2下resources目录下编写MyBatis的核心配置文件

<?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默认环境-->
    <environments default="mysql">
        <!--environment单个环境-->
        <environment id="mysql">
            <!--transactionManager配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;useSSL=true&amp;useUnicode=true"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
     </environments>
    <!--每一个Mapper.xml需要在Mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/mybatis/example/dao/StudentMapper.xml"/>
    </mappers>
</configuration>

2.3 编写MyBatis工具类

//sqlSessionFactory--->sqlSession
public class MybatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try{
            //使用mybatis第一步,获取sqlSessionFactroy对象
            String resource="/mybatis-config.xml";
            InputStream inputStream= Resources.getResourceAsStream(resource);
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
    既然有了SqlSessionFactory,顾名思义,我们就可以获取SqlSession的实例了,
    SqlSession完全包含了面向数据库执行SQL命令所需的所有方法。
     */
    public static SqlSession getSqlSession(){
        SqlSession sqlSession=sqlSessionFactory.openSession();
        return  sqlSession;
    }
}

2.4 编写实体类

/**
 * 实体类Student,属性id,name,password,age
 */
public class Student {
    private long id;
    private String name;
    private String password;
    private String age;
​
    public long getId() {
        return id;
    }
​
    public void setId(long id) {
        this.id = id;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    public String getAge() {
        return age;
    }
​
    public void setAge(String age) {
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

2.5 编写Mapper接口和配置Mapper.xml

/dao接口在mybatis中是mapper接口
public interface StudentDao{
    //查询全部用户
    List<Student> getStudentList();
}
<?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" >
​
<!--namespace绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.mybatis.example.dao.StudentDao">
    <!--select查询语句-->
    <select id="getStudentList" resultType="com.mybatis.example.pojo.Student">
       select * from student
   </select>
</mapper>

2.6 使用原生或者工具类来做测试

//没有使用工具类
public class StudentDaoTest {
    @Test
    public void getStu() throws IOException {
        //1.读取配置文件
        InputStream in = Resources.class.getResourceAsStream("/mybatis.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        SqlSession session = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        StudentDao studentDao = session.getMapper(StudentDao.class);
        //5.使用代理对象执行方法
        List<Student> users = studentDao.getStudentList();
        for (Student user:users) {
            System.out.println(user);
        }
        //6.释放资源
        session.close();
        in.close();
    }
}
//使用该工具类
public class Test {
    @org.junit.Test
    public void test(){
        //第一步,获得SqlSession对象
        SqlSession sqlSession= MybatisUtil.getSqlSession();
        //第二步,执行sql语句
        StudentDao  studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> users = studentDao.getStudentList();
        for (Student user:users) {
            System.out.println(user);
        }
        //释放资源
        sqlSession.close();
    }
}

SqlSession ==> SqlSessionFactory.openSession() ==> SqlSessionFactoryBuilder.build(InputStream)

如果我们的配置文件Mapper.xml放在了编写java程序文件下,那么我们需要注意我们的配置文件的一个资源加载问题,(maven约定大于配置,因此我们可能遇到写的配置文件无法被导入或者生效问题,解决方案如下):

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

问题总结:

  • 配置文件没有注册

  • 绑定接口错误

  • 方法名不对

  • 返回类型不对

  • Maven导出资源问题

格外CRUD操作

1.namespace

namespace中的包名要和接口中的包名一致!

基本步骤:

1、编写接口


public interface StudentMapper{
Student getStudentById(int id);
}  

2、编写对应mapper中的sql


<select id="getStudentById" parameterType="int" resultType="com.mybatis.example.pojo.Student">
   select * from student where id=#{id}
</select>  

3、测试


@org.junit.Test
public void test1(){
   SqlSession sqlSession=null;
   try{
       sqlSession=MybatisUtil.getSqlSession();
       StudentMapper studentDao=sqlSession.getMapper(StudentMapper.class);
       Student student=studentDao.getStudentById(1);
       System.out.println(student);

   }catch (Exception e){
       e.printStackTrace();
   }finally {
       sqlSession.close();
   }
}  

2.select

选择,查询语句;

  • id:方法名字

  • resultType:sql语句执行后,返回值类型

  • parameterType:传递的参数类型

3.insert


//编写接口
public interface StudentMapper{
   int addStudent(Student student);
}
//编写对应mapper中的sql
<insert id="addStudent" parameterType="com.mybatis.example.pojo.Student">
       insert into student(name,password,age) value(#{name},#{password},#{age})
   </insert>
//测试
 @org.junit.Test
   public void add(){
       Student student=new Student();
       student.setName("胡进");
       student.setPassword("787878");
       student.setAge("18");
       SqlSession sqlSession=null;
       try{
           sqlSession=MybatisUtil.getSqlSession();
           StudentMapper studentDao=sqlSession.getMapper(StudentMapper.class);
           int i=studentDao.addStudent(student);
           System.out.println(i);
           //提交事务
           sqlSession.commit();
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           sqlSession.close();
       }
   }  

4.update


//编写接口
public interface StudentMapper{
    int updateStudent(Student student);
}
//编写接口对应mapper的sql
<update id="updateStudent" parameterType="com.mybatis.example.pojo.Student">
       update student set name=#{name},password=#{password},age=#{age} where id=#{id}
   </update>
//测试
@org.junit.Test
   public void update(){
       Student student1=new Student();
       student1.setId(1);
       student1.setName("小李");
       student1.setAge("12");
       student1.setPassword("123982");
       SqlSession sqlSession=null;
       try{
           sqlSession=MybatisUtil.getSqlSession();
           StudentMapper studentDao=sqlSession.getMapper(StudentMapper.class);
           int i=studentDao.updateStudent(student1);
           //提交事务
           sqlSession.commit();
           System.out.println(i);
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           sqlSession.close();
       }
   }   

5.delete


//编写接口
public interface StudentMapper{
   int deleteStudent(int id);
}
//编写接口mapper对应的sql
<delete id="deleteStudent" parameterType="int">
       delete from student where id=#{id}
   </delete>
//测试
@org.junit.Test
   public void del(){
       SqlSession sqlSession=null;
       try{
           sqlSession=MybatisUtil.getSqlSession();
           StudentMapper studentDao=sqlSession.getMapper(StudentMapper.class);
           int i=studentDao.deleteStudent(1);
           System.out.println(i);
           sqlSession.commit();
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           sqlSession.close();
       }
   }  

注意点:

  • 增删改需要提交事务!

  • 标签不要弄错

  • resource绑定mapper需要使用路径

  • 程序配置文件必须符合规范

  • NullPointerException 空指针异常

  • 代码中禁止出现乱码

  • maven资源没有导出

6.万能的Map

假设我们实体类,数据库中的表,字段或者参数过多,我们应当考虑使用Map!

  • map传递参数,直接在sql中取出key即可!【parameterType="map"】

  • 对象传递参数,直接在sql中取出对象的属性即可!【parameterType="Object"】

  • 只有一个基本参数可以直接在sql中取到

  • 多个参数用map或者注解


//map的使用
//第一步,编写接口
public interface StudentMapper{
   int adstu();
}
//第二步,编写mapper对应的sql
<insert id="adStu" parameterType="map">
       insert into student(name,password,age) values (#{stName},#{stPassword},#{stAge})
   </insert>
//测试
@org.junit.Test
   public void adds(){
       SqlSession sqlSession=null;
       try{
           sqlSession=MybatisUtil.getSqlSession();
           StudentMapper studentDao=sqlSession.getMapper(StudentMapper.class);
           Map<String,Object> map=new HashMap<String, Object>();
           map.put("stName","朝朝");
           map.put("stPassword","7787878");
           map.put("stAge","18");
           int i=studentDao.adStu(map);
           System.out.println(i);
           sqlSession.commit();
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           sqlSession.close();
       }  

7.模糊查询

1、java执行的时候传递%


List<Student> students=studentDao.getLikeStudent("%胡%");  

2、%在sql拼接中使用


//编写接口
public interface StudentMapper{
   List<Student> getLikeStudent(String value);
}
//编写接口mapper对应接口
<select id="getLikeStudent" resultType="com.mybatis.example.pojo.Student" parameterType="String">
       select * from student where name like "%"#{value}"%"
   </select>
//测试
@org.junit.Test
   public void like(){
       SqlSession sqlSession=null;
       try{
           sqlSession=MybatisUtil.getSqlSession();
           StudentDaoImpl studentDao=sqlSession.getMapper(StudentDaoImpl.class);
           List<Student> students=studentDao.getLikeStudent("胡");
           for (Student student:students) {
               System.out.println(student);
           }
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           sqlSession.close();
       }
   }  

2.7 MyBatis核心配置文件标签

2.7.1 核心配置文件

  • 官方建议命名mybatis-config.xml

  • mybatis的配置文件包含了mybatis的设置和属性信息


configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)  

2.7.2 环境配置environments

  • mybatis可以配置多个环境,但每个SqlSessionFactory只能选择一个环境。

  • mybatis默认的管理其实JDBC,连接池:POOLED

    学习要求:学会使用多套环境配置

2.7.3 属性(properties)

  • 我们可以通过peoperties实现引用配置文件。

  • 这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【如:db.properties】

#编写一个配置文件 db.peoperties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;useSSL=true&amp;useUnicode=true
username=root
password=123456
  • 将db.properties引入核心配置文件

<?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>
    <properties resource="db.properties">
    </properties>
    <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>
        <mapper resource="com/mybatis/cn/dao/Mapper.xml"/>
    </mappers>
</configuration>

将部分引入:


#编写一个配置文件 db.peoperties
url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;useSSL=true&amp;useUnicode=true
username=root
password=123456
    
<?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>
    <properties resource="db.properties">
    	<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    </properties>
    <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>
        <mapper resource="com/mybatis/cn/dao/Mapper.xml"/>
    </mappers>
</configuration>  

知识点:

com.mysql.jdbc.Driver与com.mysql.cj.jdbc.Driver的区别

  • JDBC连接Mysql5 com.mysql.jdbc.Driver

  • JDBC连接Mysql6 com.mysql.cj.jdbc.Driver,需要指定时区serverTimezone

如果外部和内部引用出现相同的字段,则优先选择外部引用。

2.7.4 类型别名(typeAliases)

  • 类型别名是为java类型设置一个短的名字

  • 存在的意思仅在于用来减少类完全限定名的冗余

1、类别名

//mybatis-config.xml
<typeAliases>
        <typeAlias type="com.mybatis.cn.pojo.Student" alias="student"></typeAlias>
    </typeAliases>
//mapper.xml
<select id="getStudentList" resultType="student"> //student不用写完全限定名
        select * from student
    </select>

2、包别名(mybatis会自动扫描java bean)

//mybatis-config.xml
<typeAliases>
        <package name="com.mybatis.cn.pojo"/>
    </typeAliases>
//mapper.xml
<select id="getStudentList" resultType="Student"> //会在包下自动扫面实体类
        select * from student
    </select>

使用分析:在实体类较少时,使用第一种;实体类较多时,使用第二种。第一种可以自定义别名,第二种不行。

第二种如果非要改,则可以在实体类上增加注解


@Alias("hello")
public class Student {
    //实体类
}
//mapper.xml
 <select id="getStudentList" resultType="hello"> //hello就是注解取的别名
        select * from student
 </select>  

2.7.5 设置(setting)

  • 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

2.7.6 其他配置


typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
     1.mybatis-generator-coreo 
     2.mybatis-plus
     3.通用mapper
  

2.7.7 映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件;

方式一:


<mappers>
    <mapper resource="com/mybatis/cn/dao/Mapper.xml"/>
</mappers>  

方式二:使用class绑定文件


<mappers>
    <mapper class="com.mybatis.cn.dao.StudentMapper"/>
</mappers>  

注意点:

  • 接口和他的mapper配置文件必须同名(接口UserMapper .xml命名为UserMapper.xml)

  • 接口和它的配置文件必须在同一个包下

方式三:使用扫描包进行绑定注入(注意点与方式二一致)


<mappers>
    <package name="com.mybatis.cn.dao"/>
</mappers>  

2.7.8 生命周期和作用域

 

这里面每一个mappper都代表一个业务!

  • 不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

  • SqlSessionFactory一旦创建,就没用了,局部变量

  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。

  • SqlSession用完要关闭

2.8 日志文件

2.8.1 日志工厂

日志是数据库排错最好的帮手!

曾经:sout debug

现在:日志工厂

Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:

  • SLF4J

  • Apache Commons Logging

  • Log4j 2

  • Log4j (deprecated since 3.5.9)

  • JDK logging

在mybatis中具体是用哪个日志,在设置(setting 核心配置文件)中实现!


<!--默认的标准日志工厂-->
 <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
 </settings>  

2.8.2 log4j

<!--外部引入pom.xml-->
<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
<!--mybatis.config.xml-->
 <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;

  • 我们也可以控制每一条日志的输出格式;

  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

  • 最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

建立配置文件:log4j.properties


#将等级为DEBUG的日志信息输出到console和file这两个目的地, console 和file的定义在下面的代码
log4j.rootLogger=DEBUG, console,file
#控制台输出的相关设置
1og4j.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
文件每出的相关没置
1og4j.appender.file = org.apache.1og4j.RollingFileAppender
1og4j.appender.file.File=./iog/kuang. log
log4j.appender.file.MaxFilesize=1Bmb
1og4j.appender.file.Threshold=DEBUG
1og4j.appender.file.layout=org.apache.log4j.PatternLayout
1og4j.appender.file.1ayout.conversionPattern=[%p][%d{yy-M-dd}][%c ]Xm%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
1og4j.logger.java.sq1=DEBUG
1og4j.logger.java.sq1.statement=DEBUG
log4j.logger.java.sq1.ResultSet=DEBUG
1og4j.logger.java.sq1.PreparedStatement=DEBUG
  

log4j的简单使用:

  • 在要使用Log4j的类中,导入包 import org.apache.log4j.Logger;

  • 日志对象,参数为当前类的class

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

log4j如同输出一般,简单理解,但还有更多功能:


logger.info("")//普通的输出
logger.debeg("")//debeg的输出
logger.error("")//错误的输出  

public void test(){
    logger.info("info:输出");
}  

3. MyBatis融于Spring容器开发测试

3.1 配置MyBatis

<!-- mybatis配置文件 -->
<?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>
    <settings>
        <!-- 启用驼峰命名法和智能转换 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>
<!-- mybatis-spring配置文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--    配置数据源-->
    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!-- 数据库驱动 -->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <!-- 数据库地址 -->
        <property name="url" value="jdbc:mysql://localhost:3306/sql_study?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT%2B8"/>
        <!-- 连接数据的账号 -->
        <property name="username" value="root"/>
        <!-- 连接数据库的密码 -->
        <property name="password" value="123456"/>
    </bean>

    <!-- 配置MyBatis的Sql会话工厂 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" autowire="byName">
        <!-- 核心配置路径 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- mapper文件路径 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!--    mybatis扫描-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--        mapper接口包路径,包与类的路劲引用.与/-->
        <property name="basePackage" value="com.ssm.mga.mapper"/>
    </bean>
</beans>

3.2 测试案例


创建一个interface,并添加@Mapper 注解,如:
@Mapper
public interface UserMapper {
    这里就是抽象方法
}  

pom.xml文件注解说明(自己理解):

<!--  依赖导入库-->
  <dependencies>
    <!-- 单元测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
      <!-- 下面涉及web容器及webapplicationcontext -->
      <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.23</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.23</version>
    </dependency>
    <!--  spring依赖  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.3.23</version>
    </dependency>
      <!-- spring上下文bean的注入加载 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.23</version>
    </dependency>
      <!-- 数据源配置需要用到 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.23</version>
    </dependency>
      <!-- 测试需要用到 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.3.23</version>
    </dependency>
    <!-- MyBatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.10</version>
    </dependency>
     <!-- mybatis相关配置注入spring容器加载 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.7</version>
    </dependency>
    <!-- MySQL -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.18</version>
    </dependency>
    <!--  json-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.83</version>
    </dependency>
    <!-- 日志文件输入 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.36</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.36</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.11</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
    </dependency>
    <!-- 可以解决json格式的乱码 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.8</version>
    </dependency>
    <!-- 简化实体类的sertter和getter及构造方法 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>
    <!-- 下面两个都会用于jsr303验证等 -->
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>8.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.1.0.Final</version>
    </dependency>
  </dependencies>

构建实体类:


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
 private int id;
 private String studentName;
 private String password;
 private LocalDate birthday;
 private int classId;
}  

创建mapper接口:


@Mapper
public interface IStudentMapper {
 List<Student> students();
}  

编写sql语句在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.ssm.mga.mapper.IStudentMapper">

 <resultMap id="student" type="com.ssm.mga.entity.Student">
     <result property="id" column="id"/>
     <result property="studentName" column="studentName"/>
     <result property="birthday" column="birthday"/>
     <result property="password" column="password"/>
     <result property="birthday" column="birthday"/>
 </resultMap>
 <select id="students" resultMap="student">
     select * from student
 </select>
</mapper>  

单元测试:


@WebAppConfiguration
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {
 @Resource
 IStudentMapper studentMapper;
 @Test
 public void test_01(){
     List<Student> students = studentMapper.students();
     for (Student student : students) {
         System.out.println((student.toString()));
     }
 }
}  

4. MyBatis的XML文件使用(动态SQL嵌入)

4.1 Mapper.xml文件结构

我们可以在resources/mapper目录下创建xml文件,该文件里就包含了我们所需要的SQL语句。格式如下:


<?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="">

</mapper>  

4.2 Mapper.xml的CRUD操作

select标签


查询语句,最常用、最复杂的元素之一,可以自定义参数,返回结果集。
标签属性:
    id                  它对应的是@Mapper接口里的方法名,是唯一不重复
    resultMap           它是映射体的引用,对应的是在本配置文件里的创建的<resultMap>标签的id
    resultType          如果返回的数据类型不是ORM映射集(比如一个整数、一个字符串),就需要设置resultType="返回类型的完整类型",
                        如:resultType="java.lang.Integer"
格式:select * from 表名 left join 表名 on 表.字段=表.字段 where 条件 group by ... having ... orderBy ... limit index,size;  

insert标签


插入语句
标签属性:
    id                  它对应的是@Mapper接口里的方法名,是唯一不重复
    keyProperty         该属性的作用是将插入操作的主键值赋给JavaBean的某个属性,通常为主键对应的属性。
    useGeneratedKeys    该属性用于设置是否使用JDBC提供的getGenereatedKeys()方法,
                        获取数据库内部产生的主键并赋值到keyProperty属性设置的请求对象的属性中,例如:数据库自动增长的ID字段,其默认为false
返回值:影响行数
格式:insert into 表 values(字段1,字段2,字段3,...)  

update标签


修改语句
标签属性:
    id                  它对应的是@Mapper接口里的方法名,是唯一不重复
返回值:影响行数
update 表 set 字段=值,... where 条件  

delete标签


删除语句
标签属性:
    id                  它对应的是@Mapper接口里的方法名,是唯一不重复
返回值:影响行数
delete from 表 where 条件  

4.3 解决字段与实体类映射问题


1.可以利用给字段定义别名如:select student_name as name from student where ...
2.使用ResultMap标签:
    配置@Mapper接口与数据库表的ORM映射,用于描述JavaBean的属性与数据库字段的关系
    标签属性
        id                  唯一的标识
        type                对应的JavaBean的全名称
    result 子标签
        通过该标签,可以手动指定JavaBean的属性与数字库字段的映射关系
        <result property="JavaBean的属性" column="数据表的字段"/>  

4.4 解决参问题

一个参数时:


通过 #{任何字符串}  来获取参数
注意:如果参数为一个JavaBean对象时,我们应该通过 #{属性} 来获取参数  

多个参数时:


通过 #{字符串} 来获取参数,其中”字符串“需要跟@Mapper接口的方法的参数的@Param()注解配置的值一一对应  

4.5 动态构建SQL语句

if标签


单条件分支判断语句
<if test="判断条件">
    拼接的SQL语句
</if>  

choose-when-otherwise标签


判断语句,相当于Java中的if else if else,多条件分支判断
<choose>
    <when test="判断条件1">
        拼接的SQL语句1
    </when>
    <when test="判断条件2">
        拼接的SQL语句
    </when>
    <otherwise>
        拼接的SQL语句
    </otherwise>
</choose>
当判断条件1成立的时候,则执行“拼接的SQL语句1”,后面不再进行判断。  

foreach标签


循环语句,用于in 这个条件语句
and id in 
<foreach collection="ids" item="id" open="(" close=")" separator=",">
    #{id}
</foreach>
其中ids就是一个传递进来的数组或者集合  

where标签


辅助元素,用于处理SQL条件字段拼接时的问题,如:去掉多余的小逗号,用于select语句  

set标签


作用和where类似,区别就是用于update语句中更新字段的拼接问题  

bind标签


辅助元素,自定义绑定参数
  

练习测试CRDU及SQL动态

1.实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private Integer id;
    private String studentName;
    private String password;
    private LocalDate birthday;
    private int classId;
}

2.mapper接口

@Mapper
public interface IStudentMapper {

    /**
     * 根据名字和密码获取用户信息
     * @param studentName
     * @param password
     * @return
     */
    Student getStudent(@Param("studentName") String studentName, @Param("password") String password);

    /**
     * student列表查询
     * @return
     */
    List<Student> students();

    /**
     * 添加学生
     * @param student
     * @return
     */
    int insert(Student student);

    /**
     * 修改学生信息
     * @param student
     * @return
     */
    int update(Student student);

    /**
     * 删除学生
     * @param id
     * @return
     */
    int delete(int id);

    /**
     * 使用万能Map接受值
     * 根据学生姓名或者班级名字查询
     * @param studentName
     * @param clazzName
     * @return
     */
    List<Map<String,Object>> ByStuNameAndClazzName(
            @Param("studentName") String studentName,@Param("clazzName") String clazzName);

    /**
     * 传递对象时,都可以加上@Param注解,以免找不到
     * 根据id序列批量查询
     * @param ids
     * @return
     */
    List<Student> ByListId(@Param("ids") List<Integer> ids);
}

3.mapper.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.ssm.mga.mapper.IStudentMapper">
    <resultMap id="student" type="com.ssm.mga.entity.Student">
        <result property="id" column="id"/>
        <result property="studentName" column="studentName"/>
        <result property="birthday" column="birthday"/>
        <result property="password" column="password"/>
        <result property="birthday" column="birthday"/>
    </resultMap>

    <insert id="insert">
        insert into student(id,studentName,password,birthday,classID)
        values(default ,#{studentName},#{password},#{birthday},#{classId})
    </insert>

    <update id="update">
        update student
        <set>
            studentName=#{studentName},
            password=#{password},
            birthday=#{birthday},
            classID=#{classId}
        </set>
         where id=#{id}
    </update>

    <delete id="delete">
        delete from student where id=#{id}
    </delete>

    <select id="students" resultMap="student">
        select * from student
    </select>

    <!--  如果实体类与数据库表字全部相对应就不需要使用resultMap  -->
    <select id="getStudent" resultType="com.ssm.mga.entity.Student">
        select * from student where studentName=#{studentName} and password=#{password}
    </select>

    <select id="ByStuNameAndClazzName" resultType="java.util.Map">
        select student.id as studentId,studentName,className from student
        left join class on student.classID=class.id
        <where>
            <if test="clazzName != ''">
                and className=#{clazzName}
            </if>
            <bind name="stuName" value="'%'+studentName+'%'"/>
            <if test="studentName != ''">
                and studentName like #{stuName}
            </if>
        </where>
    </select>

    <select id="ByListId" resultType="com.ssm.mga.entity.Student">
        select * from student
        <where>
            <if test="ids.size()>0">
                and id in
                <foreach collection="ids" item="Id" open="(" close=")" separator=",">
                   #{Id}
                </foreach>
            </if>
        </where>
    </select>
</mapper>

4.测试

@WebAppConfiguration
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {
    @Resource
    IStudentMapper studentMapper;
    @Test
    public void test_01(){
        List<Student> students = studentMapper.students();
        for (Student student : students) {
            System.out.println((student.toString()));
        }
    }

    @Test
    public void test_02(){
        Student student = studentMapper.getStudent("李四", "123456");
        System.out.println(student.toString());
    }

    @Test
    public void test_03(){
        Student student=new Student(null, "jack", "123456", LocalDate.now(), 2);
        int count = studentMapper.insert(student);
        System.out.println(count);
    }

    @Test
    public void test_04(){
        Student student=new Student(13, "jack", "123456", LocalDate.now(), 2);
        int count = studentMapper.update(student);
        System.out.println(count);
    }

    @Test
    public void test_05(){
        List<Map<String, Object>> maps = studentMapper.ByStuNameAndClazzName("张", "");
        for (Map<String, Object> map : maps) {
            System.out.println(map.toString());
        }
    }

    @Test
    public void test_06(){
        List<Integer> integers=new ArrayList<>();
        integers.add(1);
        integers.add(2);
        List<Student> students = studentMapper.ByListId(integers);
        for (Student student : students) {
            System.out.println(student.toString());
        }
    }
}

以上没有对 choose-when-otherwise标签做练习,基本使用就是if-elseif-else

5. MyBatis注解使用(动态SQL嵌入-->不支持)

MyBatis为了简化XML的配置,也提供了注解功能,通过注解也能完成对@Mapper接口方法的实现

@Select("select * from 表 left join 表 on 条件 where "):用于查询

@Insert("insert into 表 (表字段...) value(#{参数}) "):用于插入

@Update("update 表 set 字段名=#{值}... where 条件"):用于修改

@Delete("delete from 表 where 条件"):用于删除

@Options:用于配置一些选项(如插入后获取id,是否开启缓存等) 语法: @Options( 选项1 = 选项值, 选项2 = 选项值 )

@Results 用于配置JavaBean与数据表字段的ORM映射, 注意:如果一个Mapper接口内有多个@Results注解,则这些注解的ID属性不能重复,必须是唯一值。

@ResultMap 用于引入@Result,只需要输入本Mapper类中已经定义的@Results中的id值即可。 写法: @ResultMap("anResult")

@ResultType 如果返回的数据类型不是ORM映射集(比如一个整数、一个字符串),就可能设置resultType="类型.class" 写法: @ResultType(Integer.class)

因为MyBatis的XML与注解实现有冲突,所以我们在映入mapper.xml文件的xml文件时注解了。不然会报错。 具体实现根据上面的XML实现来,具体修改了mapper层,其他不变。

@Mapper
public interface IStudentMapper {

    /**
     * 根据名字和密码获取用户信息
     * @param studentName
     * @param password
     * @return
     */
    @Select("select * from student where studentName=#{studentName} and password=#{password}")
    Student getStudent(@Param("studentName") String studentName, @Param("password") String password);

    /**
     * student列表查询
     * @return
     */
    @Results(
            id = "student",
            value = {
                    @Result(property = "studentName",column = "studentName"),
                    @Result(property = "password",column = "password")
            }
    )
    @Select("select * from student")
    List<Student> students();

    /**
     * 添加学生
     * @param student
     * @return
     */
    @Insert("insert into student(id,studentName,password,birthday,classID)" +
            "values(default ,#{studentName},#{password},#{birthday},#{classId})")
    int insert(Student student);

    /**
     * 修改学生信息
     * @param student
     * @return
     */
    @Update("update student set studentName=#{studentName}," +
            "password=#{password},birthday=#{birthday},classID=#{classId} where id=#{id}")
    int update(Student student);

    /**
     * 删除学生
     * @param id
     * @return
     */
    @Delete("delete from student where id=#{id}")
    int delete(int id);

    /**
     * 使用万能Map接受值
     * 根据学生姓名或者班级名字查询
     * @param studentName
     * @param clazzName
     * @return
     */
    @ResultType(Map.class)
    @Select("<script>" +
            "select student.id as studentId,studentName,className from student\n" +
            "        left join class on student.classID=class.id\n" +
            "        <where>\n" +
            "            <if test=\"clazzName != ''\">\n" +
            "                and className=#{clazzName}\n" +
            "            </if>\n" +
            "            <bind name=\"stuName\" value=\"'%'+studentName+'%'\"/>\n" +
            "            <if test=\"studentName != ''\">\n" +
            "                and studentName like #{stuName}\n" +
            "            </if>\n" +
            "        </where>" +
            "</script>")
    List<Map<String,Object>> ByStuNameAndClazzName(
            @Param("studentName") String studentName,@Param("clazzName") String clazzName);

    /**
     * 传递对象时,都可以加上@Param注解,以免找不到
     * 根据id序列批量查询
     * @param ids
     * @return
     */
    @ResultMap("student")
    @Select("<script>" +
            "select * from student\n" +
            "        <where>\n" +
            "            <if test=\"ids.size()>0\">\n" +
            "                and id in\n" +
            "                <foreach collection=\"ids\" item=\"Id\" open=\"(\" close=\")\" separator=\",\">\n" +
            "                   #{Id}\n" +
            "                </foreach>\n" +
            "            </if>\n" +
            "        </where>" +
            "</script>")
    List<Student> ByListId(@Param("ids") List<Integer> ids);
}

6. MyBatis缓存(这里浅提,具体Redis缓存)

6.1 MyBatis缓存


我们通过MyBatis去查询数据,有可能会重复性的查询相同的数据。如果每次查询都去数据库里面执行,则会增加数据库压力。
我们就可以使用缓存技术来实现对查询数据的临时存储,当我们第一次查询若干数据的时候,会从数据库里获取。
当后面查询相同数据的时候,则不需要再从数据库里获取,而是直接从缓存里获取即可。即————缓存技术
缓存技术分为一级缓存和二级缓存。  

6.2 一级缓存


是基于HashMap的本地缓存,作用范围为一个request,当一个请求结束后,该request中所有缓存就会被清空。
在参数和SQL语句完全一样的情况下,我们使用同一个sqlSession对象调用同一个mapper的方法,往往只需要执行一次SQL。
因为SQLSerssion第一次查询后,MyBatis会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,
SQLSession会取出当前缓存的数据,而不是再次发SQL到数据库,这个不用我们来开启,MyBatis自带支持一级缓存。
前提:是请求的方法需要事务的支持  

开启事务支持,可以在一个request实现一级缓存。

6.2 二级缓存


原理和一级缓存类似,是全局性缓存,作用范围比一级缓存高,是真正的Session级别的缓存。
默认是关闭,如果需要开启二级缓存,需要进行相应配置。  

实现二级缓存:

1.mybatis-config.xml配置文件


在mybatis-config.xml配置
<setting name="cacheEnabled" value="true"/>  

2.基于XML文件实现


是在mapperXML里面配置
<cache/>
属性说明:
 eviction         代表的是缓存回收策略,可选:
                                 LRU【默认】     使用较少,移除最长时间不用的对象;
                                 FIFO           先进先出,按对象进入缓存的顺序来移除它们;
 flushInterval       刷新间隔时间,单位为毫秒。如果省略该配置,那么只有当 SQL 被执行的时候才会刷新缓存。
 size                引用数目,正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。
 readOnly            只读,默认值为 false,意味着缓存数据只能读取而不能修改,这样设置的好处是可以快速读取缓存,缺点是没有办法修改缓存。
​
配置之后,所在mapper文件里的所有<select>SQL语句会自动应用二级缓存。
如果某一个<select>不需要二级缓存,可以设置属性useCache="false"  

3.基于注解实现


添加注解
@CacheNamespace(
     eviction = LruCache.class,
     flushInterval = 100,
     size = 100,
     readWrite = false       //读写,如果需要设置为只读,则设置为false
)
如果某一个@Select注解不需要二级缓存,可以在其@Options注解中设置useCache=false  

总结


对于 MyBatis 内置二级缓存仅作了解即可,因为面对一定规模的数据量,内置的 Cache 方式就派不上用场了,
并且对查询结果集做缓存并不是 MyBatis 所擅长的,它专心做的应该是 ORM 映射。
而专门做二级缓存我可以使用Redis等专业的缓存服务器来做更合理。
注意:缓存不适用于需要精密计算的数据查询  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis框架 的相关文章

  • swagger被拦截器拦截

    配置swagger文档 xff0c 被拦截器拦截不能使用 拦截器中添加以下配置 xff0c 适当修改即可使用 重写addInterceptors registry addInterceptor new UserInterceptor add
  • JAVA之JDBC连接数据库

    前景说明 xff1a 在我们刚开始使用数据库的时候 xff0c 发现只能在mysql编辑器里面使用sql语句来完成对数据库的操作 xff0c 那我们怎么来通过Java来操控数据库呢 xff1f 这个时候就有了JDBC的出现 1 什么是JDB

随机推荐

  • Css margin 和 float浮动

    1 浮动 定义 浮动是css里面布局最多的一个属性 xff0c 也是很重要的一个属性 float xff1a 表示浮动的意思 它有四个值 none 表示不浮动 xff0c 默认right xff1a 表示右浮动left 表示左浮动 floa
  • Java Servlet组件

    1 什么是Servlet xff1f 从广义上来讲 xff0c Servlet规范是Sun公司制定的一套技术标准 xff0c 包含与Web应用相关的一系列接口 xff0c 是Web应用实现方式的宏观解决方案 而具体的Servlet容器负责提
  • JAVA 之 Ajax

    1 什么是Ajax xff1f AJAX xff08 Asynchronous Javascript And XML xff09 翻译成中文就是 异步Javascript和XML 即是用Javascript语言与服务器进行异步交互 xff0
  • Servlet 的Request和Response

    1 Request和Response概述 1 Request 获取请求数据 浏览器会发送HTTP请求到后台服务器 Tomcat HTTP的请求中会包含很多请求数据 请求行 43 请求头 43 请求体 后台服务器 Tomcat 会对HTTP请
  • 链接标签的使用

    什么是链接 xff1f 链接相当于是一个传送门 xff0c 点击链接就可以从该页面 xff0c 跳转到其他页面 xff0c 或者从该页面跳转到该页面的其他地方 链接的表现形式有哪些 xff1f 链接可以 表现为文字 xff0c 图片 xff
  • 报错 java: 程序包org.apache.ibatis.annotations不存在

    今天在使用mybatis运行项目时 xff0c 项目忽然报错了 xff0c 检查了自己的pom xml文件也没有问题 xff0c 报错情况如图 xff1a 在网上找了一大堆方法 xff0c 都没有解决问题 xff0c 这里附上一个网上的常用
  • spring框架

    文章内容 介绍spring框架 为什么要使用spring框架 如何使用spring IOC控制反转 1 介绍spring框架 1 spring是一个轻量级开源的JAVAEE框架 2 Spring提高了IOC和AOP IOC 控制反转 把创建
  • Ubuntu忘记密码怎么办 如何重置Ubuntu登入密码

    1 首先重新启动Ubuntu系统 xff0c 然后快速按下shift键 xff0c 以调出grub启动菜单 2 在这里我们选择第二个 xff08 Ubuntu高级选项 xff09 xff0c 选中后按下Enter键 3 选择第二个recov
  • 快速掌握e语言,以js语言对比,快速了解掌握。

    易语言 xff0c 怎么调试输出 xff0c 查看内容 在js语言里 xff0c 弹窗是 alert 在易语言里 xff0c 弹窗是 信息框 弹出显示内容 0 标题 在js语言里 xff0c 调试输出是 console log 在易语言里
  • java 实现Comparable接口排序,升序、降序、倒叙

    本人由于项目开发中需要对查询结果list进行排序 xff0c 这里根据的是每一个对象中的创建时间降序排序 本人讲解不深 xff0c 只实现目的 xff0c 如需理解原理还需查阅更深的资料 1 实现的效果 2 创建排序的对象 package
  • gitbash不能粘贴

    点击鼠标滚轮或者shift 43 ins
  • Hive安装与配置常见问题解决

    欢 43 迎使用Markdown编辑器 提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 目录 前言一 Hive是什么 xff1f 二 安装步骤1 引入jar包2 配置步骤1 hive s
  • 【Linux】生产者消费者模型

    文章目录 1 生产者消费者模型1 1生产者消费者模型的特点1 2生产者消费者模型的原则1 3生产者消费者模型的优点 2 基于阻塞队列的生产者消费者模型2 1如何理解生产者消费者模型的并发 xff1f 3 信号量3 1信号量接口3 2基于环形
  • Ubuntu设置允许root用户登录

    Ubuntu激活root用户 sudo passwd root 设置root密码 设置允许root通过ssh默认登录 vim etc ssh sshd config root权限编辑 PermitRootLogin yes 在第一行添加内容
  • python编写程序统计一元人民币换成一分、两分和五分的所有兑换方案个数(用while循环)

    a 61 int input 34 输入钱数 xff08 单位 xff1a 元 xff09 34 e 61 a 100 count 61 0 i 61 1 while i lt e 5 43 1 i 43 61 1 b 61 e 5 i 2
  • springboot简易整合mybatis

    SpringBoot整合Mybatis篇 实现单表mybatis整合 准备sql 创建数据库 create database if not exists 96 mybatis 96 修改数据库默认字节编码 alter database 96
  • Springboot+PageHelper实现分页(前后端简单展示)

    Springboot 43 PageHelper实现分页 前后端简单展示 创建表及赋值 创建表 DROP TABLE IF EXISTS 96 page learn 96 CREATE TABLE 96 page learn 96 96 i
  • SpringBoot缓存注解使用(无数据库操作)

    SpringBoot缓存注解使用 无数据库操作 缓存注解介绍 64 EnableCaching注解 xff1a 开启注解缓存的支持 64 Cacheable注解 xff1a 对方法的查询结果进行缓存 64 CachePut注解 xff1a
  • JavaScript(基于Java开发的学习)

    JavaScript 基于Java基础学习 JavaScript结构图 1 JS简介 JavaScript xff08 行为 xff09 xff1a 是一种弱类型脚本语言 xff0c 其源码不需经过编译 xff0c 而是由浏览器解释运行 x
  • MyBatis框架

    MyBatis学习结构 1 MyBatis框架简介 MyBatis是一款优秀的持久层框架 它支持定制化SQL 存储过程以及高级映射 MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集 MyBatis可以使用简单的XML或