MyBatis从入门到进阶

news2024/11/14 8:10:27

目录

  • MyBatis入门
    • 1、创建项目、数据准备
    • 2、数据库配置
    • 3、编写持久层代码
    • 单元测试
    • 打印日志
  • 基本操作
    • 查询数据
    • 插入数据
    • 删除数据
    • 更新数据
  • MyBatis - xml
    • 插入数据
    • 更新数据
    • 删除数据
    • 查询数据
    • #{}与${}
    • SQL注入
    • 排序
    • like查询
  • MyBatis进阶
    • if标签
    • trim标签
    • where标签
    • set标签
    • foreach标签
    • sql标签和include标签

MyBatis入门

MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作,通过使用简单的 XML 或注解来配置和映射原生信息,使开发者可以专注于编写 SQL 语句。

基本步骤:创建项目和准备数据、数据库配置、编写持久层代码

1、创建项目、数据准备

创建过程和SpringBoot项目一模一样,需要注意的是,下面两个一定选上
在这里插入图片描述

在数据库中创建对应的数据库和表:

-- 创建数据库
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;

-- 使用数据数据
USE mybatis_test;

-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (
        `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
        `username` VARCHAR ( 127 ) NOT NULL,
        `password` VARCHAR ( 127 ) NOT NULL,
        `age` TINYINT ( 4 ) NOT NULL,
        `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',
        `phone` VARCHAR ( 15 ) DEFAULT NULL,
        `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now() ON UPDATE now(),
        PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 

-- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

对应Java中的实体类

@Data
@RestController
@RequestMapping
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createDate;
    private Date updateDate;

}

2、数据库配置

在yml文件中,添加如下的配置:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: '111111'
    driver-class-name: com.mysql.cj.jdbc.Driver

如果是properties格式的,配置如下:

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=false
#连接数据库的⽤⼾名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=111111

3、编写持久层代码

根据规范,一般是Controller层调用Service层接口,Service层调用Dao层接口:
在这里插入图片描述

在MyBatis中持久层又叫Mapper

Controller层:

@RestController
@RequestMapping("/user")
public class UserController {

    //注入UserService
    @Autowired
    private UserService userService;

    @RequestMapping("/selectUserList")
    public List<UserInfo> selectUserList(){
        return userService.selectUserList();
    }
}

Service层:

@Service
public class UserService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    public List<UserInfo> selectUserList() {
        return userInfoMapper.selectAll();
    }
}

Dao层:

MyBatis持久层规范一般叫xxxMapper

@Mapper
public interface UserInfoMapper {
    @Select("select * from user_info")
    List<UserInfo> selectAll();
}

@Mapper注解:表示的是MyBatis中的Mapper接口

@Select注解:代表数据库的select操作

单元测试

如果按照:Controller层调用Service层接口,Service层调用Dao层接口这个规范来进行代码测试,未免有些麻烦,因为我们编写完代码之后,往往只是测试单独的某个功能。我们可以使用SpringBoot帮我们创建好的Test测试类来进行测试

在这里插入图片描述

在test目录中创建测试类,需要给类加上类注解@SpringBootTest注解,才能从Spring中获取Bean,给方法加上@Test注解,可以执行对应的方法。例如:

@SpringBootTest
class MyBatisDemoTests {

    @Test
    void TestFunc() {
    }

}

IDEA自动生成测试类:右键–>Generate–>Test

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

打印日志

yml配置如下:

# 配置日志
mybatis:
  configuration: # 配置打印 MyBatis⽇志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

properties配置如下:

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

配置了上述信息后,会把sql语句以及执行的结果以日志的形式打印出来
在这里插入图片描述

基本操作

查询数据

使用@Select注解

1、通过参数传递

@Mapper
public interface UserInfoMapper {
    //通过参数传递
    @Select("select * from user_info where id=#{id}")
    UserInfo selectAll(Integer id);
}

注意:select操作可能返回多条数据,要使用List接收,如果只返回一条数据,使用对象接收即可

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void selectAll() {
        //使用foreach遍历,类似于for循环
        userInfoMapper.selectAll().forEach(x -> System.out.println(x));
        List<UserInfo> userInfos = userInfoMapper.selectAll();
        /*
    等价于下面代码
    for (UserInfo user:userInfos) {
        System.out.println(user);
    }*/

    }
}

如果参数只有一个,参数名可以不对应,(多个参数必须对应)例如:

@Mapper
public interface UserInfoMapper {
    @Select("select * from user_info where id=#{abc}")
    UserInfo selectById(Integer id);
}
@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void selectById() {
        System.out.println(userInfoMapper.selectById(1));
    }
}

2、多个参数

MyBatis会根据参数名自动匹配

@Mapper
public interface UserInfoMapper {
    @Select("select * from user_info where id=#{id} and age =#{age}")
    UserInfo selectFunc(Integer age,Integer id);
}

3、参数重命名

MyBatis会给参数取名字,第一个参数取名为param1,第二个参数取名为param2…以此类推

@Mapper
public interface UserInfoMapper {
    @Select("select * from user_info where id=#{param1} and age =#{param2}")
    UserInfo selectFunc(Integer id,Integer age);
}

我们也可以自己重命名:

@Mapper
public interface UserInfoMapper {
    @Select("select * from user_info where id=#{id1} and age =#{age1}")
    UserInfo selectFunc(@Param("id1") Integer id,@Param("age1")Integer age);
}

最推荐的写法如下:

参数和注解的名称一致

@Mapper
public interface UserInfoMapper {
    @Select("select * from user_info where id=#{id} and age =#{age}")
    UserInfo selectFunc(@Param("id") Integer id,@Param("age")Integer age);
}

4、数据库的字段命名规范是统一小写字母,单词之间使用下划线分割,而java的规范是属性名称统一小驼峰。但是MyBatis是通过名称来映射的,如何让数据库字段和Java属性名映射起来?

方法1:使用@Results注解映射

@Mapper
public interface UserInfoMapper {
    //下划线命名法转换为驼峰命名法
    @Results(id = "map", value = {
        @Result(column = "delete_flag", property = "deleteFlag"),
        @Result(column = "create_time", property = "createTime"),
        @Result(column = "update_time", property = "updateTime")
    })//建立映射
    @Select("select * from user_info")
    List<UserInfo> selectAll2();

    @ResultMap("map")//注解复用
    @Select("select * from user_info")
    List<UserInfo> selectAll3();
}

方法2:通过配置实现,只需要添加下面的配置信息即可

mybatis:
  configuration: 
    map-underscore-to-camel-case: true # 配置驼峰自动转换
    

插入数据

使用@Insert注解,获取参数直接使用对象的属性名

@Mapper
public interface UserInfoMapper {
    @Insert("insert into user_info(username,`password`,age,gender) values (#{username},#{password},#{age},#{gender})")
    Integer insertUserInfo(UserInfo userInfo);
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertUserInfo() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(11);
        userInfo.setAge(18);
        userInfo.setGender(1);
        userInfo.setUsername("z111");
        userInfo.setPassword("1234");
        userInfo.setPhone("1234567");
        userInfoMapper.insertUserInfo(userInfo);
    }
}

使用@Param注解,可以给对象重命名,重命名之后,需要通过点号获取

@Mapper
public interface UserInfoMapper {
    //对象重命名
    @Insert("insert into user_info(username,`password`,age,gender) values (#{Info.username},#{Info.password},#{Info.age},#{Info.gender})")
    Integer insertUserInfo2(@Param("Info") UserInfo userInfo);//返回值是影响的行数
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertUserInfo2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(11);
        userInfo.setAge(18);
        userInfo.setGender(1);
        userInfo.setUsername("z222");
        userInfo.setPassword("1234");
        userInfo.setPhone("1234567");
        Integer i = userInfoMapper.insertUserInfo2(userInfo);
        System.out.println(i);
    }
}

使用@Options注解,获取主键:

@Mapper
public interface UserInfoMapper {
    @Options(useGeneratedKeys = true, keyProperty = "id")//
    @Insert("insert into user_info(username,`password`,age,gender) values (#{Info.username},#{Info.password},#{Info.age},#{Info.gender})")
    Integer insertUserInfo3(@Param("Info") UserInfo userInfo);//返回值:影响的行数
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertUserInfo3() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(10);
        userInfo.setAge(18);
        userInfo.setGender(0);
        userInfo.setUsername("abcd");
        userInfo.setPassword("13579");
        userInfo.setPhone("1234567");
        Integer i = userInfoMapper.insertUserInfo3(userInfo);
        System.out.println(i);
    }
}

删除数据

使用@Delete注解:

@Mapper
public interface UserInfoMapper {
    @Delete("delete from user_info where id = #{id}")
    Integer delete(Integer id);//返回值:影响的行数
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void delete() {
        userInfoMapper.delete(9);
    }
}

更新数据

使用@Update注解

@Mapper
public interface UserInfoMapper {
    @Update("update user_info set password = #{password} where id =#{id}")
    Integer update(Integer id, String password);
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void update() {
        userInfoMapper.update(1, "6666666");
    }
}

参数为对象:

@Mapper
public interface UserInfoMapper {
    @Update("update user_info set password = #{password} where id =#{id}")
    Integer update2(UserInfo userInfo);
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Test
    void update2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(8);
        userInfo.setPassword("00000");
        userInfoMapper.update2(userInfo);
    }
}

MyBatis - xml

上述的基本操作都是基于注解的方式进行的,下面我们介绍使用xml的方式进行增删查改等基本操作

数据库配置信息还是一样

# 配置数据库信息
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: "111111"
    driver-class-name: com.mysql.cj.jdbc.Driver

配置MyBatis xml文件路径

mybatis:
 mapper-locations: classpath:mapper/**Mapper.xml

表示在mapper路径下的,文件名以Mapper结束的xml文件,classpath指的是resources这个目录,例如:
在这里插入图片描述

插件安装:
在这里插入图片描述

安装好插件之后,可以实现接口和xml文件之间跳转,甚至可以帮我们根据接口中的方法自动生成对应xml的语句

在这里插入图片描述
在这里插入图片描述

定义接口:

@Mapper
public interface UserInfoXmlMapper {
    //查询
    List<UserInfo> queryAllUser();
}

对应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.wpre.mybatisdemo2.mapper.UserInfoXmlMapper">

    <select id="queryAllUser" resultType="com.wpre.mybatisdemo2.model.UserInfo">
        select *
        from user_info
    </select>

</mapper>

在这里插入图片描述

resultType只有查询操作需要写,其他操作不需要

插入数据

使用insert标签,标签内写sql语句

<insert id="insertUser">
    insert into user_info(username, `password`, age, gender)
    values (#{username}, #{password}, #{age}, #{gender})
</insert>

对应的接口:

Integer insertUser(UserInfo userInfo);

测试类:

@Test
void insertUser() {
    UserInfo userInfo = new UserInfo();

    userInfo.setUsername("wpre");
    userInfo.setPassword("wpre");
    userInfo.setAge(18);
    userInfo.setGender(1);

    userInfoXmlMapper.insertUser(userInfo);
}

参数重命名:

Integer insertUser2(@Param("uf") UserInfo userInfo);
<insert id="insertUser2">
    insert into user_info(username, `password`, age, gender)
    values (#{uf.username}, #{uf.password}, #{uf.age}, #{uf.gender})
</insert>

重命名之后,需要通过点号获取

测试类:

@Test
void insertUser2() {
    UserInfo userInfo = new UserInfo();

    userInfo.setUsername("wpre");
    userInfo.setPassword("wpre");
    userInfo.setAge(18);
    userInfo.setGender(1);

    userInfoXmlMapper.insertUser2(userInfo);
}

返回自增id

Integer insertUser(UserInfo userInfo);
<insert id="insertUser3" useGeneratedKeys="true">
    insert into user_info(username, `password`, age, gender)
    values (#{uf.username}, #{uf.password}, #{uf.age}, #{uf.gender})
</insert>

测试类:

@Test
void insertUser() {
    UserInfo userInfo = new UserInfo();

    userInfo.setUsername("wpre");
    userInfo.setPassword("wpre");
    userInfo.setAge(18);
    userInfo.setGender(1);
    Integer result = userInfoXmlMapper.insertUser3(userInfo);
    System.out.println("影响行数"+result+"id:"+userInfo.getId());
}

更新数据

使用update标签

Integer updateUser(Integer id,String password);
<update id="updateUser">
    update user_info
    set password = #{password}
    where id = #{id}
</update>

测试类:

@Test
void updateUser() {
    userInfoXmlMapper.updateUser(1, "12321");
}

删除数据

Integer deleteUserById(Integer id);
<delete id="deleteUserById">
    delete
    from user_info
    where id = #{id}
</delete>

测试类:

@Test
void deleteUserById() {
    userInfoXmlMapper.deleteUserById(1);
}

查询数据

List<UserInfo> queryAllUser();
<select id="queryAllUser" resultType="com.wpre.mybatisdemo2.model.UserInfo">
    select *
    from user_info
</select>

测试类:

@Test
void queryAllUser() {
    userInfoXmlMapper.queryAllUser();
}

xml同样会出现数据库字段名和Java中的属性名不匹配的问题

解决办法:

1、通过sql语句中的as取别名

例如

select delete_flag as deleteFlag,create_time as createTime,
from user_info;

2、建立映射关系

<resultMap id="BaseMap" type="com.wpre.mybatisdemo2.model.UserInfo">
    <id property="id" column="id"></id>
    <result property="deleteFlag" column="delete_flag"></result>
    <result property="createDate" column="create_date"></result>
    <result property="updateDate" column="update_flag"></result>
</resultMap>

在这里插入图片描述

如果使用这种方式映射,建议把所有的字段都写上

使用映射来进行查询:

<select id="queryAllUser2" resultMap="BaseMap">
    select id, username, delete_flag, create_time, update_time
    from user_info
</select>

3、配置驼峰自动转换

mybatis.configuration.map-underscore-to-camel-case=true

#{}与${}

MyBatis的参数赋值有两种方式,一种是使用#符号,一种是使用$符号

#{}:

在这里插入图片描述

${}:
在这里插入图片描述

#{}是预编译SQL, 是即时 S Q L , {}是即时SQL, 是即时SQL{}是直接替换参数。一般情况下,能使用#尽量使用#。

SQL注入

SQL注入(SQL Injection)是一种常见的数据库攻击手段,它允许攻击者插入或“注入”一个或多个SQL语句到原本的查询中,欺骗数据库服务器执行非预期的命令。这种攻击利用了应用程序在构建SQL查询时对用户输入数据的不当处理。

例如:

select * from user_info where username = '';drop table user_info;--'
@Select("select * from user_info where username=${username}")
UserInfo selectById(String username);

如果是即时SQL,传递的参数如果是';drop table user_info;-- 这样一条SQL就变成两条SQL了,在不知不觉中你的表就已经被删除了

排序

结论:排序只能使用${}

//排序
@Select("select * from user_info order by id #{order};")
List<UserInfo> selectUsernameByOrder(String order);

测试类

@Test
void selectUsernameByOrder() {
    userInfoXmlMapper.selectUsernameByOrder("desc");
}

运行结果
在这里插入图片描述

使用的是#{}进行参数赋值,参数是String类型,此时默认加上单引号,所以我们必须使用${}进行参数赋值。

like查询

结论:使用${}

//like查询
@Select("select from user_info where username like '%${name}%' ")
List<UserInfo> selectByLike(String name);

模糊查询+CONCAT可以避免SQL注入问题

//like查询
@Select("select * from user_info where username like CONCAT('%','#{name}','%') ")
List<UserInfo> selectByLike(String name);

MyBatis进阶

if标签

Integer insertUserByCondition(UserInfo userInfo);
<insert id="insertUserByCondition">
    insert into user_info(username, `password`, age, <if test="gender!=null">gender</if>)
    values (#{username}, #{password}, #{age}, <if test="gender!=null">#{gender}</if>)
</insert>

测试类:

@Test
void insertUserByCondition() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("zhangsan");
    userInfo.setPassword("123");
    userInfo.setAge(18);
    userInfoXmlMapper.insertUserByCondition(userInfo);
}

表示的含义是:检查参数gender是否为null,如果参数gender为null,gender就不会被包含在这条SQL语句中;如果参数gender不为null,gender就会被包含在这条SQL语句中。上述测试类中并没有设置gender,gender为空,所以SQL语句为

insert into user_info(username, `password`, age,)
values (username, `password`, age,)

可以发现,上述的SQL语句是有语法错误的,age的后面多了一个逗号,何解?使用trim标签

trim标签

trim标签有4个属性,分别是:

prefix:增加前缀

suffix:增加后缀

prefixOverrides:去除前缀

suffixOverrides:去除后缀

使用方法:if标签嵌套在trim标签中

<trim >
    <if test="">
    </if>
</trim>

例如:

<insert id="insertUserByCondition">
    insert into user_info
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username!=null">
            username,
        </if>
        <if test="password!=null">
            password,
        </if>
        <if test="age!=null">
            age,
        </if>
        <if test="gender!=null">
            gender,
        </if>
    </trim>
    values
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username!=null">
            #{username},
        </if>
        <if test="password!=null">
            #{password},
        </if>
        <if test="age!=null">
            #{age},
        </if>
        <if test="gender!=null">
            #{gender},
        </if>
    </trim>
</insert>

如果逗号写在前面,则需要使用prefixOverrides

where标签

where标签的作用:

1、能够去除多余的and

2、当有查询条件时,生成where关键字

3、没有查询条件时,不生成where关键字

例如:

<select id="selectByCondition" resultType="com.wpre.mybatisdemo2.model.UserInfo">
    select *
    from user_info
    <where>
        <if test="age!=null">
            age = #{age} and
        </if>
        <if test="deleteFlag!=null">
            delete_flag = #{deleteFlag}
        </if>
    </where>
</select>

set标签

set标签的作用:

1、添加set关键字

2、去除末尾的逗号

<update id="updateByCondition">
    update user_info
    <set>
        <if test="username!=null">
            username=#{username},
        </if>
        <if test="password!=null">
            password=#{password},
        </if>
        <if test="gender!=null">
            gender=#{gender},
        </if>
    </set>
    <where>
        id = #{id}
    </where>
</update>

foreach标签

foreach标签处理的是如下SQL语句

delete from user_info where id in (10,11,12)

forecah属性如下:

1、collection:遍历的集合

2、separator:分隔符

3、item:元素的名称

4、open:以xx为开始

5、close:以xx为结束

例如:

Integer foreachDelete(List<Integer> ids);
<update id="foreachDelete">
    delete from user_info where id in
    <foreach collection="ids" separator="," item="id" open="(" close=")">
        #{id}
    </foreach>
</update>

测试类:

@Test
void foreachDelete() {
    userInfoXmlMapper.foreachDelete(List.of(10, 11, 12));
}

sql标签和include标签

sql标签可以把重复冗余的代码片段进行抽取,封装成一个SQL片段,通过使用include标签进行引用

例如:

<sql id="queryAllUser">
    id,username,age,gender,phone,delete_flag,create_time,update_time
</sql>

<select id="queryAllUser" resultType="com.wpre.mybatisdemo2.model.UserInfo">
    select
    <include refid="queryAllUser">
    </include>
    from user_info
</select>

本文结束,感谢阅读~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2240034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaWeb】JavaWeb入门之XML详解

目录 1.XML介绍 1.1.XML概述 1.1.1.什么是XML 1.1.2.XML的作用 1.1.3.XML与HTML的比较 1.1.4.XML和properties&#xff08;属性文件&#xff09;比较 1.1.5.W3C组织 1.2.XML语法概述 1.2.1.XML文档展示 1.2.2.XML文档的组成部分 1.3.XML文档声明 1.3.1.什么是XML文…

wordcloud库基本介绍

文章目录 wordcloud库概述wordcloud库的安装 wordcloud库使用说明配置对象参数 wordcloud应用实例实例: 政府工作报告词云 wordcloud库概述 wordcloud是优秀的词云展示第三方库 词云以词语为基本单位,更加直观和艺术地展示文本 wordcloud库的安装 (cmd命令行) pip install …

VMware和CentOS 7.6 Linux操作系统的安装使用

1. 安装VMware 安装VMware之前&#xff0c;有些电脑是需要去BIOS里修改设置开启cpu虚拟化设备支持才能安装。如果运气不好在安装过程中安装不了的话就自行百度吧。 打开 VMware 的官网: https://www.vmware.com/ 点击 product&#xff0c;往下滑找到 see desktop hypeerviso…

LLM在Transformer上的改动

LLM在Transformer上的改动 1.multi-head共享1.1BERT的逻辑1.2multi-head共享 2.attention的前后网络2.1传统Transformer&#xff1a;2.2GPTJ结构&#xff1a; 3.归一化层的位置&#xff08;LayerNorm&#xff09;4.归一化层函数的选择4.1LayerNorm4.2RMSNorm 3.激活函数4.LLama…

解决SpringBoot3的Validated依赖实现自定义注解失效问题

我们引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> Validated实现自定义注解 我们首先看看自定义注解里面&#xff0c;用到的注解的包 我们…

当微软windows的记事本被AI加持

1985年&#xff0c;微软发布了Windows 1.0&#xff0c;推出了一款革命性的产品&#xff1a;记事本&#xff08;Notepad&#xff09;。这款软件旨在鼓励使用一种未来主义的新设备——鼠标&#xff0c;并让人们可以不依赖VI等键盘工具就能书写文本和编写代码。记事本因其简洁和高…

前端常用布局模板39套,纯CSS实现布局

前端常用布局模板39套&#xff0c;纯CSS实现布局 说明 写博客、官网、管理后台都可以参考以下布局模板&#xff0c;实现模板布局的方式包含&#xff1a;flex、CSS、HTML5、Layout。 不需要下载积分&#xff0c;没有特殊库引用&#xff0c;不用安装任何插件&#xff0c;打开资源…

微服务day07

Elasticsearch 需要安装elasticsearch和Kibana&#xff0c;应为Kibana中有一套控制台可以方便的进行操作。 安装elasticsearch 使用docker命令安装&#xff1a; docker run -d \ --name es \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \ //设置他的运行内存空间&#x…

java常用工具介绍

1. 集成开发环境&#xff08;IDE&#xff09;&#xff1a; • Eclipse&#xff1a;一个开放源代码的、基于Java的可扩展开发平台。它提供了一个框架和一组服务&#xff0c;用于通过插件组件构建开发环境。Eclipse 还包括用于Java开发的工具&#xff08;Java Development Tools,…

C++入门基础知识148—【关于C++ 二元运算符重载】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 二元运算符重载的相关内容&#xff01…

黑马智数Day7

获取行车管理计费规则列表 封装接口 export function getRuleListAPI(params) {return request({url: parking/rule/list,params}) } 获取并渲染数据 import { getRuleListAPI } from /apis/carmounted() {this.getRuleList() }methods: {// 获取规则列表async getRuleList(…

NodeJS的安装 npm 配置和使用 Vue-cli安装 Vue项目介绍

一.前端工程化 前端工程化是使用软件工程的方法来单独解决前端的开发流程中模块化、组件化、规范化、自动化的问题,其主要目的为了提高效率和降低成本 1. NodeJS的安装 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环 境&#xff0c;可以使 JavaScript 运行在服务…

Anolis8.2系统中搭建python环境

文章目录 安装依赖项依赖项介绍 下载python源码包安装python源码包 安装依赖项 [rootPython ~]# dnf install -y gcc make zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel xz-devel libffi-devel uuid-devel libnsl2-d…

51c自动驾驶~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/11638131 #端到端任务 说起端到端&#xff0c;每个从业者可能都觉得会是下一代自动驾驶量产方案绕不开的点&#xff01;特斯拉率先吹响了方案更新的号角&#xff0c;无论是完全端到端&#xff0c;还是专注于planner的模型&a…

基于Python+Django+Vue3+MySQL实现的前后端分类的商场车辆管理系统

项目名称&#xff1a;基于PythonDjangoVue3MySQL实现的前后端分离商场车辆管理系统 技术栈 开发工具&#xff1a;PyCharm、Visual Studio Code (VSCode)运行环境&#xff1a;Python 3.10、MySQL 8.0、Node.js 18技术框架&#xff1a;Django 5、Vue 3.4、Ant-Design-Vue 4.12 …

JAVA后端生成图片滑块验证码 springboot+js完整案例

前言 现在大部分网部都是图片滑块验证码&#xff0c;这个得要与后端联动起来才是确保接口安全性 通过我们系统在发送手机短息时都会选进行滑块验证&#xff0c;但是我们要保证发送短息接口的全安&#xff0c;具体路思如下 那么这个滑块的必须是与后端交互才能保证安全性&…

人工智能大比拼(3)

已知x-,y-6&#xff0c;且下述表达式的值与x的取值无关&#xff0c;求y -10x2y7xy 上述这个很简单的数学题&#xff0c;可是在各家AI之间出现了争议&#xff0c;本期我使用了四个AI&#xff1a;kimi&#xff0c;商量&#xff0c;文心一言&#xff0c;chatyy 先来看一下kimi的表…

SQLI LABS | Less-45 POST-Error Based-String-Stacked-Bilnd

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-45/ 本关是堆…

sol机器人pump机器人如何实现盈利的?什么是Pump 扫链机器人?

什么是Pump 扫链机器人&#xff0c;它的盈利逻辑优化策略是什么&#xff1f; Pump 扫链机器人&#xff0c;通过智能化、自动化的买卖操作帮助投资者实现快速盈利。在此基础上&#xff0c;我们对该机器人的盈利逻辑进行了深度优化&#xff0c;涵盖了买入策略和止盈策略的各个方面…

MYSQL SQL优化总结【快速理解】

1、优化insert操作 批量插入&#xff0c;防止大量与数据库进行访问 手动控制事务&#xff0c;减少事务的频繁开启和提交。 主键顺序插入 2、优化主键 主键优化的点就是避免主键过长&#xff0c;因为如果有二级索引&#xff0c;叶子节点存储的数据时间上是主键&#xff0c;如果主…