Java之MyBatis入门详解

 更新时间:2022年12月21日 11:49:45   作者:MinggeQingchun  
这篇文章主要介绍了Java之MyBatis入门详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

一、三层架构

Java中的三层架构指

1、界面层(User Interface layer;表示层,视图层):接受用户的数据,显示请求的处理结果。使用 web 页面或者手机 app和 用户交互

2、业务逻辑层(Business Logic Layer):接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据

3、数据访问层(Data access layer):与数据库打交道;主要实现对数据的增、删、改、查。将存储在数据库中的数据提交 给业务层,同时将业务层处理的数据保存到数据库

(1)三层对应的包

界面层: controller包 (servlet)

业务逻辑层: service 包(XXService类)

数据访问层: dao包(XXDao类)

(2)三层中类的交互

用户使用界面层----> 业务逻辑层----->数据访问层(持久层)---->数据库(MySQL,Oracle等)

(3)三层对应的处理框架

界面层---servlet---springmvc(框架)

业务逻辑层---service类--spring(框架)

数据访问层---dao类--mybatis(框架)

(4)使用三层架构有点

【1】结构清晰、耦合度低, 各层分工明确

【2】可维护性高,可扩展性高

【3】有利于标准化

【4】开发人员可以只关注整个结构中的其中某一层的功能实现

【5】有利于各层逻辑的复用

(5)缺点

【1】降低了系统的性能。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,三层架构必须通过中间层来完成

【2】导致级联的修改。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码

  • 框架( Framework )是构成一类特定软件可复用设计的一组相互协作的类。框架规定了你的应用的体系结构。
  • 它定义了整体结构,类和对象的分割,各部分的主要责任,类和对象怎么协作,以及控制流程。
  • 框架预定义了这些设计参数,以便于应用设计者或实现者能集中精力于应用本身的特定细节

二、MyBatis

1、官方简介

MyBatis官网中文

MyBatis在GitHub地址

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录

java bean,pojo,vo,entity,domain可参考

2、百度基本信息

  • MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁 移到了 google code,并且改名为 MyBatis 。
  • 2013 年 11 月迁移到 Github。 iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。
  • iBATIS 提供的 持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)

3、JDBC

JDBC代码如下

  • (1)注册驱动
  • (2)获取连接
  • (3)获取数据库操作对象
  • (4)执行SQL语句
  • (5)处理查询结果集
  • (6)释放资源

这些导致

  • (1)代码比较多,开发效率低
  • (2)需要关注 Connection ,Statement, ResultSet 对象创建和销毁
  • (3)对 ResultSet 查询的结果,需要自己封装为 List
  • (4)重复的代码比较多些
  • (5)业务代码和数据库的操作混在一起
        String driver = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://127.0.0.1:3306/mydb";
        String user = "root";
        String pwd = "123456";
 
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
 
        try {
            //1、注册驱动(连接的数据库)
            Class.forName(driver);
 
            //2、获取连接
            conn = DriverManager.getConnection(url,user,pwd);
 
            //3、获取数据库操作对象(专门执行sql语句的对象)
            stmt = conn.createStatement();
 
            //4、执行SQL语句(DQL DML....)
            String sql = "select empno,empname as name,sal from emp2 where empno=7369";
            rs = stmt.executeQuery(sql);
 
            //5、处理查询结果集(只有当第四步执行的是select语句的时候,才有处理查询结果集)
            while (rs.next()){
                /*
                (1)下标取值;下标从 1 开始
                */
                String empno = rs.getString(1);
                String empname = rs.getString(2);
                String sal = rs.getString(3);
                System.out.println(empno + " " + empname + " " + sal);
 
                /*
                (2)数据类型取值
                */
                int empno1 = rs.getInt(1);
                String empname1 = rs.getString(2);
                Double sal1 = rs.getDouble(3);
                System.out.println(empno1 + " " + empname1 + " " + sal1);
 
                /*
                (3)字段名取值
                */
                String empno2 = rs.getString("empno");
                //如果执行的SQL语句中有别名,需要使用别名字段取值
                String empname2 = rs.getString("name");
                String sal2 = rs.getString("sal");
                System.out.println(empno2 + " " + empname2 + " " + sal2);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            //6、释放资源;从小到大关闭
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }

MyBatis 是一个基于 java 的持久层ORM( Object Relational Mapping,对象关系映射)框架,内部封装了 jdbc,开发者只需要关注 sql 语句 本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。

MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的 动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回

mybatis是 MyBatis SQL Mapper Framework for Java (sql映射框架)

(1)sql mapper:sql映射

把数据库表中的一行数据  映射为 一个java对象

一行数据可以看做是一个java对象;操作这个对象,就相当于操作表中的数据

(2)Data Access Objects(DAOs):数据访问 , 对数据库执行增删改查

MyBatis框架

【1】提供了创建和销毁、关闭Connection ,Statement, ResultSet等对象能力

【2】提供了执行sql语句的能力

【3】提供了循环sql, 把sql的结果转为java对象, List集合的能力

三、MyBatis入门SqlSession

首先以SqlSession的方式使用mybatis框架

首先我们先设置一下maven的本地仓库

1、新建一个数据库,以及一张表user

CREATE TABLE `user` (
  `user_id` int(10) NOT NULL COMMENT '用户名ID',
  `user_name` varchar(100) DEFAULT NULL COMMENT '用户名',
  `email` varchar(80) DEFAULT NULL COMMENT '用户邮箱',
  `age` int(5) DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、创建maven的普通Java工程,加入maven的mybatis坐标,mysql驱动坐标

其中,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.mycompany</groupId>
  <artifactId>mybatis-1</artifactId>
  <version>1.0.0</version>
 
  <properties>
    <!-- 项目构建使用的编码,避免中文乱码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 源码编译 jdk 版本 -->
    <maven.compiler.source>1.8</maven.compiler.source>
    <!-- 运行代码的 jdk 版本 -->
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
 
  <dependencies>
    <!-- 单元测试依赖 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
 
    <!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
 
    <!--mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>
 
  </dependencies>
 
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <!-- filtering 选项 false 不启用过滤器, *.property 已经起到过滤的作用了 -->
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
 
</project>

3、创建Java实体类User--保存表中的一行数据

package com.mycompany.domain;
 
public class User {
    private int userId;
    private String userName;
    private String email;
    private int age;
 
    public int getUserId() {
        return userId;
    }
 
    public void setUserId(int userId) {
        this.userId = userId;
    }
 
    public String getUserName() {
        return userName;
    }
 
    public void setUserName(String userName) {
        this.userName = userName;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
}

4、创建持久层的dao接口,定义操作数据库的方法

package com.mycompany.dao;
 
import com.mycompany.domain.User;
 
import java.util.List;
 
public interface UserDao {
    /**
     * 查询user列表
     * @param user 单个user用户
     * @return user的list
     */
    List<User> selectUserList(User user);
 
    /**
     * 插入user
     * @param user
     * @return
     */
    int insertUser(User user);
}

5、创建一个mybatis使用的配置文件 SQL映射文件

编写SQL语句,一般一个表对应一个SQL映射文件,这个文件就是xml文件

sql映射文件(sql mapper):编写SQL语句,mybatis负责执行这些SQL语句

1.指定约束文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  • mybatis-3-mapper.dtd:约束文件名称

2.约束文件作用:限制,检查当前文件中出现的标签,属性必须符合mybatis的要求

3.<mapper>:当前文件根标签(必须的)

  • namesace:命名空间(唯一值,自定义字符串;要求使用dao接口的全限定名称)
  • 全限定类名:就是类名全称,带包路径的用点隔开,如: java.lang.String
  • 即全限定名 = 包名 + 类型
  • 非限定类名也叫短名,就是我们平时说的类名,不带包的,如:String

4.数据库增删改查特定标签

  • <select>:查询,select语句
  • <update>:更新,update语句
  • <insert>:插入,insert语句
  • <delete>:删除,delete语句
<?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">
 
<!--
    sql映射文件(sql mapper):编写SQL语句,mybatis负责执行这些SQL语句
    1、指定约束文件
    <!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     mybatis-3-mapper.dtd:约束文件名称
    2、约束文件作用:限制,检查当前文件中出现的标签,属性必须符合mybatis的要求
    3、<mapper>:当前文件根标签(必须的)
       namespace:命名空间(唯一值,自定义字符串;要求使用dao接口的全限定名称)
       全限定类名:就是类名全称,带包路径的用点隔开,如: java.lang.String
          即全限定名 = 包名 + 类型
       非限定类名也叫短名,就是我们平时说的类名,不带包的,如:String
    4、数据库增删改查特定标签
       <select>:查询,select语句
       <update>:更新,update语句
       <insert>:插入,insert语句
       <delete>:删除,delete语句
-->
 
<mapper namespace="com.mycompany.dao.UserDao">
 
    <!--
        <select>标签:查询操作
        id:执行SQL语法的唯一标识,mybatis会根据这个id的值来找到要执行的SQL语句
            可以自定义,一般要求使用接口中的方法名称
        resultType:表示结果类型,SQL语句执行后得到ResultSet结果集,遍历这个结果集得到的Java对象类型
            值写Java对象的全限定名称
    -->
    <select id="selectUserList" resultType="com.mycompany.domain.User">
        select user_Id,user_Name,email,age
        from user
        order by user_Id asc
    </select>
 
    <!--插入操作,字段名和Java实体类中字段保持一致-->
    <insert id="insertUser">
        insert into user values(#{userId},#{userName},#{email},#{age})
    </insert>
 
</mapper>

6、创建mybatis的主配置文件 一个项目一个主配置文件

主配置文件提供了数据库的连接信息和SQL映射文件的位置信息

<?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的主配置文件:主要定义了数据库的配置信息,SQL映射文件的位置
    1、约束文件
        <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
        mybatis-3-config.dtd:约束文件名称
    2、configuration:根标签
-->
<configuration>
 
    <!-- settings:mybatis全局行为 -->
    <settings>
        <!-- 设置mybatis输出日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
 
    <!--
        环境配置:数据库的连接信息
            default:必须和某个environment的id值一样
            告诉mybatis使用哪个数据库的连接信息(访问哪个数据库)
    -->
    <environments default="development">
 
        <!--
            environment:一个数据库的配置,环境
            id:一个唯一值(可自定义,表示环境的名称)
         -->
        <environment id="development">
            <!--
                transactionManaer:mybatis的事务类型
                    type:JDBC(表示使用JDBC中的Connection对象的commit,rollback做事务处理)
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource:表示数据源,连接数据库的
                    type:表述数据源的类型,POOLED表示使用连接池
            -->
            <dataSource type="POOLED">
                <!--
                   driver, user, username, password 是固定的,不能自定义。
                -->
                <!-- 数据库驱动类名 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!-- 连接数据库的URL字符串 -->
                <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                <!-- 访问数据库的用户名 -->
                <property name="username" value="root"/>
                <!-- 访问数据库的密码 -->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
 
        <!--表示线上的数据库,是项目真实使用的库-->
        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
 
    </environments>
 
    <!-- sql mapper(SQL映射文件)的位置 -->
    <mappers>
        <!--
            一个mapper标签指定一个文件的位置
                从类路径开始的路径信息(target/classes)类路径
        -->
        <mapper resource="com/mycompany/dao/UserDao.xml"/>
    </mappers>
</configuration>

7、创建使用mybatis测试类(通过mybatis访问数据库)

public class TestMyBatis {
    /**
     * 查询user列表
     */
    @Test
    public void testSelectUserList(){
        try {
            //访问mybatis读取user数据
            //1、定义mybatis主配置文件名称,从类路径的根开始(target/clasess)
            String config = "mybatis-config.xml";
            //2、读取config表示的文件
            InputStream in = Resources.getResourceAsStream(config);
            //3、创建SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            //4、创建SqlSessionFactory对象
            SqlSessionFactory factory = builder.build(in);
            //5、获取SqlSession对象,从SqlSessionFactory中获取SqlSession(非自动提交事务,如果增删改需要手动提交事务)
            SqlSession sqlSession = factory.openSession();
            //6、指定要执行的SQL语句标识;sql映射文件中的 namespace + "." + 标签的id值
            String sqlId = "com.mycompany.dao.UserDao.selectUserList";
            //7、执行sql语句,通过sqlId找到语句
            List<User> userList = sqlSession.selectList(sqlId);
            //8、输出结果
            for (User user:userList){
                System.out.println("查询用户="+user);
            }
            //9、关闭SQLSession对象
            sqlSession.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 查询user列表
     */
    @Test
    public void testMyBatisUtil(){
        try {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            String sqlId = "com.mycompany.dao.UserDao.selectUserList";
            //7、执行sql语句,通过sqlId找到语句
            List<User> userList = sqlSession.selectList(sqlId);
            //8、输出结果
            for (User user:userList){
                System.out.println("查询用户="+user);
            }
            //9、关闭SQLSession对象
            sqlSession.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 插入
     */
    @Test
    public void testInsertUser(){
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.getSqlSession();
            String sqlId = "com.mycompany.dao.UserDao.insertUser";
            //7、执行sql语句,通过sqlId找到语句
            User user = new User();
            user.setUserId(5);
            user.setUserName("zhangfei");
            user.setEmail("zangfei@163.com");
            user.setAge(16);
            int nums = sqlSession.insert(sqlId,user);
 
            //mybatis默认不是自动提交事务的, 所以在insert ,update ,delete后要手工提交事务
            sqlSession.commit();
 
            System.out.println("更新用户条数="+nums);
 
            //9、关闭SQLSession对象
            sqlSession.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 我们将SqlSession提取为工具类MyBatisUtil

public class MyBatisUtil {
    public MyBatisUtil() {
    }
 
    public static SqlSession getSqlSession() throws IOException {
        String config = "mybatis-config.xml";
        InputStream ins = Resources.getResourceAsStream(config);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(ins);
        SqlSession sqlSession = factory.openSession();
        return sqlSession;
    }
}

(1)Resources

mybatis中的一个类, 负责读取主配置文件

//1、定义mybatis主配置文件名称,从类路径的根开始(target/clasess)
String config = "mybatis-config.xml";
 
//2、读取config表示的文件
InputStream in = Resources.getResourceAsStream(config);

(2)SqlSessionFactoryBuilder :

创建SqlSessionFactory对象 

//3、创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
 
//4、创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);

(3)SqlSessionFactory

重量级对象, 程序创建一个对象耗时比较长,使用资源比较多;在整个项目中,有一个就够用

  • SqlSessionFactory:接口 ,接口实现类: DefaultSqlSessionFactory
  • SqlSessionFactory作用:获取SqlSession对象
SqlSession sqlSession = factory.openSession();

openSession()方法

【1】openSession() :无参数的, 获取是非自动提交事务的SqlSession对象

【2】openSession(boolean):

  • openSession(true)  获取自动提交事务的SqlSession
  • openSession(false)  非自动提交事务的SqlSession对象

(4)SqlSession

SqlSession接口 :定义了操作数据的方法

例如 selectOne() ,selectList() ,insert(),update(),delete(),commit(),rollback()

SqlSession接口的实现类DefaultSqlSession。

使用要求: SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。

在执行完sql语句后,需要关闭它,执行SqlSession.close();这样能保证他的使用是线程安全的

9、整个mybatis框架的maven模块目录如下

10、常见报错问题

(1)找不到mybatis-config.xml文件或者对应的dao以及SQL映射文件

有如下三种解决方案

【1】clean一下,然后compile一下,会重新生成target目录

【2】Rebuild Project,再重新运行,就会在target目录下出现mybatis-config.xml文件

【3】以上两种方式不行,直接手动将src/resources/mybatis-config.xml文件拷贝至target/classes目录下

 (2)dao接口的 方法 和 dao.xml映射文件中的 id 要保持一致

 (3)数据库表中的列名,要和Java实体类中的字段,dao.xml映射文件的属性字段保持一致

11、 junit : 单元测试

  • junit:单元测试, 一个工具类库,做测试方法使用的。
  • 单元:指定的是方法, 一个类中有很多方法,一个方法称为单元

使用单元测试

(1)需要加入junit依赖

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

(2)创建测试类

src/test/java目录中创建类

(3)创建测试方法

【1】public 方法

【2】没有返回值 void 

【3】方法名称自定义,建议名称是test + 测试方法名称

【4】方法没有参数

【5】方法的上面加入 @Test ,方法可以单独执行;不用使用main方法

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 在Spring Boot中如何使用数据缓存

    在Spring Boot中如何使用数据缓存

    本篇文章主要介绍了在Spring Boot中如何使用数据缓存,具有一定的参考价值,有兴趣的可以了解一下。
    2017-04-04
  • Spring源码解析之推断构造方法

    Spring源码解析之推断构造方法

    今天给大家带来的是关于Java的相关知识,文章围绕着Spring推断构造方法展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Jar打包用法详解

    Jar打包用法详解

    这篇文章主要介绍了Jar打包用法,详解分析了jar打包命令的各种常见用法及参数含义,非常具有实用价值,需要的朋友可以参考下
    2014-12-12
  • SpringBoot多模块打包部署Docker的项目实战

    SpringBoot多模块打包部署Docker的项目实战

    本文通过介绍最常见的Maven管理的Spring Boot项目多模块打包部署Docker来介绍一下项目部署过程中操作流程和几个需要注意的点,具有一定的参加价值,感兴趣的可以了解一下
    2023-08-08
  • Maven继承与聚合详解及作用介绍

    Maven继承与聚合详解及作用介绍

    继承关系中,分为父模块与子模块,父模块也被称为 parent 模块,子模块会继承父模块的依赖,父模块中也可以设置依赖管理器,供子模块选择是否需要某些依赖
    2022-08-08
  • java序列化对象根据不同配置动态改变属性名的方法

    java序列化对象根据不同配置动态改变属性名的方法

    本文主要介绍了java序列化对象根据不同配置动态改变属性名的方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java版给爱人表白的玫瑰花程序代码

    Java版给爱人表白的玫瑰花程序代码

    这篇文章主要讲解了Java版给爱人表白的玫瑰花程序代码,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧
    2018-05-05
  • Spring Boot实现WebSocket实时通信

    Spring Boot实现WebSocket实时通信

    本文主要介绍了Spring Boot实现WebSocket实时通信,包含实现实时消息传递和群发消息等功能,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • 基于Java生成图片验证码的方法解析

    基于Java生成图片验证码的方法解析

    这篇文章主要来为大家详细介绍一下基于Java生成图片验证码的具体方法,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2023-02-02
  • 使用多种方式实现遍历HashMap的方法

    使用多种方式实现遍历HashMap的方法

    下面小编就为大家带来一篇使用多种方式实现遍历HashMap的方法。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05

最新评论