草庐IT

day01-Mybatis介绍与入门

liyuelian 2023-03-28 原文

Mybatis介绍与入门

1.官方文档

Mybatis中文手册:mybatis – MyBatis 3 或者 MyBatis中文网

Maven仓库:Maven Repository: org.mybatis » mybatis » 3.5.7 (mvnrepository.com)

2.概述

2.1传统Java程序操作DB

传统方式操作数据库的问题:

  1. 需要自己去连接数据库,这段代码由程序员编写(不一定标准)

  2. 程序不是OOP的方式来操作DB(我们希望在代码层面上是以对象的形式来操作,如insert(Object))

  3. SQL语句写在程序中,属于硬编码,没有解耦

2.2Mybatis基本介绍

  1. Mybatis 是一个持久层框架
  2. 前身是 ibatis,在ibatis3.x 时,更名为Mybatis
  3. Mybatis 在 Java 和 sql 之间提供更加灵活的映射方案
  4. mybatis 可以对数据库表的操作(sql,方法)等等直接剥离,写到 xml 配置文件,实现和 java 代码的解耦
  5. mybatis 通过 SQL 操作 DB,建库建表的操作仍需要程序员完成

2.3Mybatis工作原理

相对于传统方式,Mybatis的优势:

  1. 数据库的连接/连接池,只需要配置即可,标准可以统一
  2. 程序以OOP的方式来操作数据库
  3. sql语句可以写在xml文件中,实现了解耦
  4. Mybatis可以对DB操作进行优化,提高效率,比如配置缓存

3.Mybatis快速入门

3.1需求说明

要求:开发一个Mybatis项目,通过Mybatis的方式可以对monster表进行crud操作。

3.2环境搭建

(1)创建maven父项目,方便项目的jar包管理

<?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.li</groupId>
    <artifactId>mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <!--加入依赖-->
    <dependencies>
        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!--junit依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!--指定该jar的作用范围在test目录下-->
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

(2)创建maven父项目的Module,视为子项目

此时父项目的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>

    <!--说明:
        1.将 mybatis作为父项目管理多个子模块/子项目
        2.父项目的完整的坐标 groupId[组织名]+artifactId[项目名]
        3.后面该父项目会管理多个子模块/子项目,将来父项目中的引入的依赖可以直接给子项目用,
            这样开发简单,提高复用性,也便于管理
        4.<packaging>pom</packaging> 表示父项目以多个子模块/子项目管理工程
        5. 在 modules指定管理哪些子模块
     -->
    <groupId>com.li</groupId>
    <artifactId>mybatis</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>mybatis_quickstart</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    
    <!--加入依赖,略,详见上面-->
    <dependencies>
        <!--mysql依赖-->
        <!--mybatis依赖-->
        <!--junit依赖-->
    </dependencies>
</project>

子模块的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">

    <!--说明
        1.parent指定了该模块的父项目的坐标 artifactId+groupId
        2.这样配置后,子模块就可以使用到父项目的依赖
        -->
    <parent>
        <artifactId>mybatis</artifactId>
        <groupId>com.li</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <!--子模块的名称,当前子模块的groupId默认和父项目的groupId相同,即com.li-->
    <artifactId>mybatis_quickstart</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

3.2代码实现

(1)创建数据库和表

-- 创建数据库
CREATE DATABASE `mybatis`;
USE `mybatis`;
-- 创建monster表
CREATE TABLE `monster`(
`id` INT NOT NULL AUTO_INCREMENT,
`age` INT NOT NULL,
`birthday` DATE DEFAULT NULL,
`email` VARCHAR(255) NOT NULL,
`gender` TINYINT NOT NULL,-- 1 male, 0 female
`name` VARCHAR(255) NOT NULL,
`salary` DOUBLE NOT NULL,
PRIMARY KEY(`id`)
)CHARSET=utf8

(2)在子模块 mybatis_quickstart 的 resources 目录创建配置文件 mybatis-config.xml(名称随意)

mybatis配置文件模板

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://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.jdbc.Driver"/>
                <!--配置连接mysql的url
                    1.jdbc:mysql 协议
                    2.127.0.0.1:3306 连接数据库的 ip+port
                    3.mybatis 连接的数据库名称
                    4.useSSL=true 表示使用安全连接
                    5.&amp; 表示 & 符号,这里这样写是为了转义,防止解析错误
                    6.useUnicode=true 使用Unicode,防止编码错误
                    7.characterEncoding=UTF-8 使用utf-8,防止中文乱码
                    -->
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?
                    useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <!--用户名-->
                <property name="username" value="root"/>
                <!--密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--这里配置需要管理的mapper.xml文件-->
    <mappers>
        <mapper resource="com/li/mapper/MonsterMapper.xml"/>
    </mappers>
</configuration>

(3)创建实体类 Monster.java

package com.li.entity;

import java.util.Date;

/**
 * @author 李
 * @version 1.0
 * 1.Monster和 monster表有对应关系
 * 2.原生的sql语句查询结果还是要封装成对象
 * 3.因此要求这里的实体类属性名和表的字段名保持相同
 */
public class Monster {
    //属性和表的字段对应
    private Integer id;
    private Integer age;
    private String name;
    private String email;
    private Date birthday;
    private double salary;
    private Integer gender;

    public Monster() {
    }

    public Monster(Integer id, Integer age, String name, String email,
                   Date birthday, double salary, Integer gender) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.email = email;
        this.birthday = birthday;
        this.salary = salary;
        this.gender = gender;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", birthday=" + birthday +
                ", salary=" + salary +
                ", gender=" + gender +
                '}';
    }
}

(4)创建MonsterMapper接口

package com.li.mapper;

import com.li.entity.Monster;

/**
 * @author 李
 * @version 1.0
 * 1.MonsterMapper接口用于声明操作monster表的方法
 * 2.这些方法可以通过注解或者xml文件来实现
 */
public interface MonsterMapper {
    //添加monster
    public void addMonster(Monster monster);
}

(5)创建接口对应的映射文件,实现方法

mybatis – MyBatis 3 | XML 映射器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--说明
  1.这是一个mapper.xml文件
  2.该文件可以去实现对应的接口的方法
  3.namespace 指定当前xml文件和哪个接口对应!
-->
<mapper namespace="com.li.mapper.MonsterMapper">
    <!--配置addMonster方法
     1.id 就是对应接口的方法名
     2.parameterType 方法的入参
     3.写入sql语句
     4.(`age`,`birthday`,`email`,`gender`,`name`,`salary`) 表的字段
     5.#{age},#{birthday},#{email},#{gender},#{name},#{salary} 从传入的Monster对象属性中获取
     6.注意这里的 #{age}对应Monster对象的属性名,其他类推
     -->
    <insert id="addMonster" parameterType="com.li.entity.Monster">
        INSERT INTO `monster`
        (`age`,`birthday`,`email`,`gender`,`name`,`salary`)
        VALUES (#{age},#{birthday},#{email},#{gender},#{name},#{salary})
    </insert>
</mapper>

(6)工具类MybatisUtils,用于获取连接

package com.li.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author 李
 * @version 1.0
 * MybatisUtils工具类可以得到 SqlSession
 */
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    //静态代码块中初始化 SqlSessionFactory-会话工厂
    static {
        try {
            //指定资源文件(配置文件)
            String resource = "mybatis-config.xml";
            //获取配置文件对应的inputStream
            //说明:加载文件时,默认到resource目录对应的==>运行后的工作目录target/classes找
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            System.out.println("sqlSessionFactory=" + sqlSessionFactory.getClass());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //编写方法,返回一个SqlSession对象-会话
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

3.3测试

3.3.1添加

test 目录中创建测试类 MonsterMapperTest.java

package com.li.mapper;

import com.li.entity.Monster;
import com.li.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.Date;

/**
 * @author 李
 * @version 1.0
 */
public class MonsterMapperTest {
    //属性
    private SqlSession sqlSession;
    private MonsterMapper monsterMapper;

    /**
     * 编写方法,完成初始化
     * 当一个A方法标注了注解 @Before时,表示在执行你的目标测试方法前会先执行A方法
     */
    @Before
    public void init() {
        sqlSession = MybatisUtils.getSqlSession();
        //获取到 monsterMapper对象 =class com.sun.proxy.$Proxy7代理对象)
        //底层使用了动态代理机制,返回一个代理对象,通过这个对象去执行你的方法
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println("monsterMapper的类型=" + monsterMapper.getClass());
    }

    @Test
    public void addMonster() {
        for (int i = 0; i < 2; i++) {
            Monster monster = new Monster();
            monster.setAge(10 + i);
            monster.setBirthday(new Date());
            monster.setEmail("kate@qq.com");
            monster.setGender(1);
            monster.setName("松鼠精" + i + "号");
            monster.setSalary(1000 + i * 10);
            monsterMapper.addMonster(monster);
            System.out.println("添加对象--" + monster);
        }
        //如果是增删改,需要提交事务,因为它默认不提交
        if (sqlSession != null) {
            sqlSession.commit();
            //将连接释放回连接池
            sqlSession.close();
        }
        System.out.println("保存成功....");
    }
}

上面的代码一般会出现找不到xxxmapper.xml错误,原因是加载的资源文件时是到target目录下加载的,当maven项目运行时,源工程的MonsterMapper.xml并没有被拷贝到target目录下。

解决方法:在父工程的pom.xml加入build配置,作用是配置resource,防止资源导出失败

<!--将指定的目录以及它们的子目录下的xml、properties文件在build项目时
    导出到对应的target目录下-->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

然后选择build project

如果不行,可能是maven版本冲突,在setting中切换maven版本,然后点击父工程的maven的clean重新构建。


测试结果:

数据库monster表增加了两条记录:

3.3.2返回自增长

有时候我们需要获取数据库中自动生成(AUTO_INCREMENT)的主键,这时候可以使用Mybatis的useGeneratedKeys (开启新增主键返回功能)和 keyProperty(实体的主键属性)来配合获取。

(1)修改映射文件MonsterMapper.xml,在该文件中的方法映射中添加 useGenerateKeys 和 keyProperty

<mapper namespace="com.li.mapper.MonsterMapper">
    <insert id="addMonster" parameterType="com.li.entity.Monster" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `monster`
        (`age`,`birthday`,`email`,`gender`,`name`,`salary`)
        VALUES (#{age},#{birthday},#{email},#{gender},#{name},#{salary})
    </insert>
</mapper>

(2)修改测试类,输出主键

(3)测试结果:

数据库表格:

3.3.3删除

(1)修改 MonsterMapper.java 接口,声明 delMonster() 方法

//根据id删除一个Monster
public void delMonster(Integer id);

(2)在映射文件 MonsterMapper.xml 中实现 delMonster() 方法

<!--配置delMonster方法
    1.java.lang.Integer是Java类型,可以简写为Integer
    2.写入delete语句
 -->
<delete id="delMonster" parameterType="Integer">
    DELETE FROM `monster` WHERE `id`=#{id};
</delete>

(3)修改测试类,添加测试方法

package com.li.mapper;

import com.li.entity.Monster;
import com.li.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.Date;

/**
 * @author 李
 * @version 1.0
 */
public class MonsterMapperTest {
    //属性
    private SqlSession sqlSession;
    private MonsterMapper monsterMapper;

    @Before
    public void init() {
        sqlSession = MybatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println("monsterMapper的类型=" + monsterMapper.getClass());
    }

    @Test
    public void delMonster() {
        //删除id=2的记录
        monsterMapper.delMonster(2);
        //如果是增删改操作,需要提交事务,因为它默认不提交
        if (sqlSession != null) {
            sqlSession.commit();
            //将连接释放回连接池
            sqlSession.close();
        }
        System.out.println("删除成功....");
    }
}

测试结果:

数据库id=2的记录成功被删除:

3.3.4修改&查询

(1)修改 MonsterMapper.java 接口,声明修改和查询的方法

//修改Monster
public void updateMonster(Monster monster);
//查询-根据id
public Monster getMonsterById(Integer id);
//查询所有的Monster
public List<Monster> findAllMonster();

(2) 映射文件 MonsterMapper.xml 中实现方法

<!--配置/实现updateMonster方法
    这里的入参可以使用类型别名,为Java类型设置一个缩写名字,可以降低冗余的全限定类名的书写
    类型别名在mybatis的配置文件中配置,而不是当前的文件-->
<update id="updateMonster" parameterType="Monster">
    UPDATE `monster`
    SET `age`=#{age},`birthday`=#{birthday},`email`=#{email},
    `gender`=#{gender},`name`=#{name},`salary`=#{salary}
    WHERE `id`=#{id};
</update>

<!--配置/实现getMonsterById方法,
resultType 期望从这条语句中返回结果的类全限定名或别名。
注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。-->
<select id="getMonsterById" resultType="Monster">
    SELECT * FROM `monster` WHERE id=#{id};
</select>

<!--实现findAllMonster方法
如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型-->
<select id="findAllMonster" resultType="Monster">
    SELECT * FROM `monster`;
</select>

(3)配置别名

(4)修改测试类,添加测试方法

package com.li.mapper;

import com.li.entity.Monster;
import com.li.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.Date;
import java.util.List;

/**
 * @author 李
 * @version 1.0
 */
public class MonsterMapperTest {
    //属性
    private SqlSession sqlSession;
    private MonsterMapper monsterMapper;

    @Before
    public void init() {
        sqlSession = MybatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println("monsterMapper的类型=" + monsterMapper.getClass());
    }
    
    @Test
    public void updateMonster() {
        Monster monster = new Monster();
        monster.setAge(50);
        monster.setBirthday(new Date());
        monster.setEmail("king@qq.com");
        monster.setGender(0);
        monster.setName("白骨精");
        monster.setSalary(20000);
        monster.setId(3);
        monsterMapper.updateMonster(monster);
        if (sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }
        System.out.println("修改成功..");
    }

    @Test
    public void getMonsterById() {
        Monster monster = monsterMapper.getMonsterById(3);
        System.out.println("monster=" + monster);
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

    @Test
    public void findAllMonster() {
        List<Monster> monsters = monsterMapper.findAllMonster();
        for (Monster monster : monsters) {
            System.out.println("monster="+monster);
        }
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

测试updateMonster()方法:

测试getMonsterById()方法:

测试findAllMonster()方法:

4.日志输出-查看SQL

在开发Mybatis程序时,比如执行测试方法,程序员往往需要查看底层发给MySql的SQL语句到底长什么样,这时应该如何查看?

解决方案:日志输出。

(1)修改Mybatis-config.xml文件,加入日志输出配置,方便分析SQL语句

(2)比如测试updateMonster() 方法时,输出的结果为:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
sqlSessionFactory=class org.apache.ibatis.session.defaults.DefaultSqlSessionFactory
monsterMapper的类型=class com.sun.proxy.$Proxy7
Opening JDBC Connection
Wed Feb 22 19:09:14 CST 2023 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Created connection 1475491159.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@57f23557]
==>  Preparing: UPDATE `monster` SET `age`=?,`birthday`=?,`email`=?, `gender`=?,`name`=?,`salary`=? WHERE `id`=?;
==> Parameters: 50(Integer), 2023-02-22 19:09:14.079(Timestamp), king333@qq.com(String), 0(Integer), 白骨精(String), 20000.0(Double), 3(Integer)
<==    Updates: 1
Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@57f23557]
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@57f23557]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@57f23557]
Returned connection 1475491159 to pool.
修改成功..

Process finished with exit code 0

当进行多表联查的时候,日志输出对我们的调试很有帮助。

5.练习

有关day01-Mybatis介绍与入门的更多相关文章

  1. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  2. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  3. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  4. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  5. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  6. ruby-on-rails - rails : Find tasks that were created on a certain day? - 2

    我有一个任务列表(名称、starts_at),我试图在每日View中显示它们(就像iCal)。deftodays_tasks(day)Task.find(:all,:conditions=>["starts_atbetween?and?",day.beginning,day.ending]end我不知道如何将Time.now(例如“2009-04-1210:00:00”)动态转换为一天的开始(和结束),以便进行比较。 最佳答案 deftodays_tasks(now=Time.now)Task.find(:all,:conditio

  7. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  8. 什么是0day漏洞?如何预防0day攻击? - 2

    什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相

  9. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  10. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

随机推荐