【JavaWeb后端学习笔记】Mybatis基础操作以及动态SQL(增、删、改、查)

Mybatis

  • 0、环境准备
    • 0.1 准备数据库表emp;
    • 0.2 准备SpringBoot工程
    • 0.3 配置文件中引入数据库连接信息
    • 0.4 创建对应的实体类
    • 0.5 准备Mapper接口
  • 1、MyBatis基础操作
    • 1.1 删除
    • 1.2 新增(主键返回)
    • 1.3 更新
    • 1.4 查询(解决字段名与类属性名不一致返回null问题)
  • 2、动态SQL
    • 2.1 XML映射文件
    • 2.2 动态SQL标签
  • 3、总结

0、环境准备

开始前需要做五个准备工作:
1.准备数据库表emp;
2.创建一个新的是SpringBoot工程,引入对应的起步依赖(Mybatis、MySQL、Lombok);
3.application.properties引入数据库连接信息(可改用yaml文件);
4.创建数据库表对应的实体类
5.准备Mapper接口

0.1 准备数据库表emp;

运行下面的SQL语句准备数据库数据:

-- 该案例来自黑马程序员
-- 部门管理
create table dept(
    id int unsigned primary key auto_increment comment '主键ID',
    name varchar(10) not null unique comment '部门名称',
    create_time datetime not null comment '创建时间',
    update_time datetime not null comment '修改时间'
) comment '部门表';

insert into dept (id, name, create_time, update_time) values
    (1,'学工部',now(),now()),
    (2,'教研部',now(),now()),
    (3,'咨询部',now(),now()),
    (4,'就业部',now(),now()),
    (5,'人事部',now(),now());

-- 员工管理
create table emp (
    id int unsigned primary key auto_increment comment 'ID',
    username varchar(20) not null unique comment '用户名',
    password varchar(32) default '123456' comment '密码',
    name varchar(10) not null comment '姓名',
    gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
    image varchar(300) comment '图像',
    job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
    entrydate date comment '入职时间',
    dept_id int unsigned comment '部门ID',
    create_time datetime not null comment '创建时间',
    update_time datetime not null comment '修改时间'
) comment '员工表';

INSERT INTO emp
(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
    (1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
    (13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());

0.2 准备SpringBoot工程

创建一个新的空工程。
在这里插入图片描述
创建一个SpringBoot项目模块。推荐将Server URL栏的https://start.spring.io替换成https://start.aliyun.com/
在这里插入图片描述
指定Mybatis、MySQL、Lombok所需依赖,并创建项目。
在这里插入图片描述

项目创建完成。
在这里插入图片描述

0.3 配置文件中引入数据库连接信息

在application.properties配置文件中配置MySQL数据库连接信息。

# 驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
# 连接数据库的用户名
spring.datasource.username=root
# 连接数据库的密码
spring.datasource.password=1234

这些信息可以从IDEA的可视化界面中查到。
下图中Database这一栏可以选择连接哪个数据库。
在这里插入图片描述
为了更方便后续调试,也可以配置MyBatis的日志输出配置。

# MyBatis日志配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

0.4 创建对应的实体类

创建实体类时需要注意成员变量与表的字段一一对应。
使用Lombok提供的注解生成构造方法以及get/set等方法。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Short gender;
    private String image;
    private Short job;
    private LocalDate entrydate;
    private Integer deptId;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

0.5 准备Mapper接口

Mapper接口需要加上@Mapper注解。程序在运行时,会自动创建代理对象,并交给IOC容器管理。

@Mapper
public interface EmpMapper {

}

1、MyBatis基础操作

在Java服务端操作MySQL数据库需要用到MyBatis技术。相关代码通常放在DAO层,在使用MyBatis时习惯叫做Mapper层。对每一个MySQL的数据库表都要有一个相关的Mapper接口,里面定义操作该表对应的接口方法。在方法上通过注解的形式编写相应的SQL语句。
常用的注解有

  • @Select: 查
  • @Delete: 删
  • @Update: 改
  • @Insert: 增

在使用这些注解编写SQL语句时,需要使用接口方法传来的参数,这时需要用到占位符。
占位符有:
#{ } :执行SQL时,会将 #{ } 替换为 ?,生成预编译SQL,会自动设置参数值,能够避免SQL注入风险;推荐使用。
$ { }:拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题。
如果有多个参数,需要保证占位符中的变量名与接口方法形参名相同。推荐保持一致。

1.1 删除

根据ID删除数据。
定义一个接口deleteById(Integer id),接口中需要传入员工ID,使用Integer类型进行接收。
在接口方法上使用@Delete注解编写SQL语句,员工ID数据使用占位符替代。

/**
 * 根据ID删除数据
 * @param id
 */
@Delete("delete from emp where id = #{id}")
void deleteById(Integer id);

在测试类中编写测试方法,调用deleteById()方法。

@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Autowired
    private EmpMapper empMapper;

    @Test
    public void testDelete(){
    	// 删除ID为17的员工数据
        empMapper.deleteById(17);
    }
}

运行之后刷新emp表发现ID为17的员工被删除了。

MySQL中的delete、insert、update语句都有返回值,只要把接口的返回参数从void改成int即可,返回参数是SQL语句操作的数据条数。

1.2 新增(主键返回)

新增员工数据。
定义一个新增数据接口insert(Emp emp),接口中传入一个实体类对象,对象中包含要插入的字段数据。
在接口方法上使用@Insert注解编写SQL语句。接口传入的是一个实体类对象,因此在SQL语句占位符中需要填入对象的属性名,也就是类的成员变量名。

/**
 * 新增员工数据
 * @param emp
 */
@Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +
		"values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
void insert(Emp emp);

在测试类中编写测试方法,调用insert()方法。

@Test
public void testInsert() {
	// 准备一个emp对象
    Emp emp = new Emp();
    emp.setUsername("xiaowang");
    emp.setName("小王");
    emp.setGender((short)1);
    emp.setImage("1.jpg");
    emp.setJob((short)1);
    emp.setEntrydate(LocalDate.of(2020, 12,2));
    emp.setDeptId(1);
    emp.setCreateTime(LocalDateTime.now());
    emp.setUpdateTime(LocalDateTime.now());
    // 使用empMapper调用insert()方法
    empMapper.insert(emp);
    // 查看主键ID
    System.out.println(emp.getId()); // 控制台输出:null
}

运行之后刷新emp表,发现插入了一条数据。

主键返回:
在某些业务场景下,需要获取刚插入的数据的主键ID。如果仅仅使用上面编写的代码是获取不到的。这时只需要在接口方法上再加上一个@Options注解,设置useGeneratedKeys = true,表明需要返回主键,设置keyProperty = “id”,表明将主键值绑定在成员变量 “id” 上。

/**
 * 新增员工数据
 * @param emp
 */
@Options(keyProperty = "id", useGeneratedKeys = true)  // 获取返回的主键
@Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +
"values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
void insert(Emp emp);

1.3 更新

更新员工信息。
定义一个根据ID更新的接口方法updateById(Emp emp),在方法中传入一个Emp对象,对象中包含修改后的数据。
在接口方法上使用@Update注解编写SQL语句。接口传入的是一个实体类对象,因此在SQL语句占位符中需要填入对象的属性名,也就是类的成员变量名。

/**
 * 更新员工信息
 * @param emp
 */
@Update("update emp set username = #{username}, name = #{name}, gender = #{gender}, image = #{image}, job = #{job}, " +
        "entrydate = #{entrydate}, dept_id = #{deptId}, update_time = #{updateTime} where id = #{id}")
void updateById(Emp emp);

在测试类中编写测试方法,调用updateById()方法。

@Test
public void testUpdate() {
    // 准备一个emp对象
    Emp emp = new Emp();
    emp.setId(21);
    emp.setUsername("xiaowang");
    emp.setName("小王");
    emp.setGender((short)1);
    emp.setImage("21.jpg");
    emp.setJob((short)1);
    emp.setEntrydate(LocalDate.of(2022, 12,2));
    emp.setDeptId(2);
    emp.setUpdateTime(LocalDateTime.now());
    // 使用empMapper调用updateById()方法
    empMapper.updateById(emp);
}

运行之后刷新emp表,发现ID为21的员工数据被修改了。

1.4 查询(解决字段名与类属性名不一致返回null问题)

查询操作是使用最多的操作,有根据单个字段的简单查询和复杂条件的复杂查询。
首先尝试实现根据ID字段的简单查询。
定义一个getById(Integet id)方法,接口中传入要查询的员工ID,返回一个Emp员工对象。
在接口方法上使用@Select注解编写SQL语句,形参变量名与占位符中变量名相同。
MyBatis会将查询到的数据自动封装到Emp对象的属性中。

/**
 * 根据ID查询员工信息
 * @param id
 * @return
 */
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id = #{id}")
Emp getById(Integer id);

在测试类中编写测试方法,调用getById()方法。

@Test
public void testGetById() {
	// 查询ID为1的员工信息
    Emp emp = empMapper.getById(1);
    System.out.println(emp);
}
// 输出结果:
// Emp(id=1, username=jinyong, password=123456, name=金庸, gender=1, image=1.jpg, job=4, entrydate=2000-01-01, deptId=null, createTime=null, updateTime=null)

需要注意:表的字段名与类的成员变量名不同,查询到的结果为null。
可以发现输出结果中,deptId,createTime,updateTime这三个属性的值为null。这是因为表中的字段名与类的成员变量名不同造成的。MySQL中表的字段名习惯使用下划线 _ 分隔,Java中成员变量习惯使用驼峰命名法。解决方法有三种。

  1. 第一种
    在配置文件中开启MyBatis的驼峰命名自动映射开关。(推荐使用)
# 开启MyBatis的驼峰命名自动映射开关
mybatis.configuration.map-underscore-to-camel-case=true
  1. 第二种
    给查询字段起别名,别名与类的成员变量名一致。
/**
 * 根据ID查询员工信息
 * @param id
 * @return
 */
@Select("select id, username, password, name, gender, image, job, entrydate, " +
        "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
Emp getById(Integer id);
  1. 第三种
    使用@Results注解和@Result注解。
/**
 * 根据ID查询员工信息
 * @param id
 * @return
 */
@Results({
        @Result(column = "dept_id", property = "deptId"),
        @Result(column = "create_time", property = "createTime"),
        @Result(column = "update_time", property = "updateTime")
})
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id = #{id}")
Emp getById(Integer id);

现在尝试复杂条件查询。
查询满足指定的姓氏、性别、入职时间范围内的员工。
定义一个list接口,编写SQL语句。在某些Spring版本中,当接口参数有多个时,接口参数前需要加@Param注解绑定参数,不然会报错。
从下面的SQL语句中可以看到,name字段使用了like模糊查询,匹配的字符串使用了concat()函数,这是MySQL提供的字符串拼接函数。

@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
        "entrydate between #{begin} and #{end} order by update_time desc")
List<Emp> list(@Param("name")String name, @Param("gender")Short gender,
               @Param("begin")LocalDate begin, @Param("end")LocalDate end);

在测试类中编写测试方法,调用list()方法进行测试。

@Test
public void testList() {
    List<Emp> emps = empMapper.list("张", (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));
    System.out.println(emps);
}

2、动态SQL

2.1 XML映射文件

XML映射文件规范:

  • XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名);
  • XML映射文件的namespace属性为Mapper接口全限定名一致;
  • XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

创建和使用XML映射文件的步骤:

  1. 在resources文件夹下创建与Mapper接口所在包相同的包。注意创建多级包时,文件夹路径使用下划线分隔。
  2. 创建与Mapper接口同名的.xml文件。
  3. 在XML映射文件中引入MyBatis约束。不需要记忆,用到的时候到MyBatis官方文档中查找。约束如下:
<?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">
  1. 在Mapper接口文件中定义一个接口。例如将1.4节中的list()接口方法通过XML映射形式实现:
List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
  1. 在XML映射文件中实现该接口的SQL语句。
    注意XML映射文件的namespace属性为Mapper接口全限定名一致;全限定名可以通过选中Mapper接口名点击右键,在点击Copy Reference获取。
    在这里插入图片描述
    同时,XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
    下面这段代码中有一点需要注意。动态SQL中比较大小需要使用<![CDATA[ >= ]]>替换。
<mapper namespace="com.wrj.mapper.EmpMapper">
    <select id="list" resultType="com.wrj.pojo.Emp">
        select * from emp
        <where>
            <if test="name != null and name != ''">name like concat('%', #{name}, '%') and</if>
            <if test="gender != null">gender = #{gender} and</if>
            <if test="begin != null">entrydate <![CDATA[ >= ]]>  #{begin} and</if>
            <if test="end != null">entrydate <![CDATA[ <= ]]>  #{end}</if>
        </where>
        order by update_time desc
    </select>
</mapper>

2.2 动态SQL标签

if标签:用于判断条件是否成立。使用 test 属性进行条件判断,如果条件为 true ,则拼接 SQL。
范例:

<if test="name != null and name != ''">name like concat('%', #{name}, '%') and</if>

where标签:如果where标签对中的条件都不成立,则不生成 where 关键字。如果 where 标签对中有多于的 and 或 or ,则删去多于的 and 和 or 。
范例:

<where>
    <if test="name != null and name != ''">name like concat('%', #{name}, '%') and</if>
    <if test="gender != null">gender = #{gender} and</if>
    <if test="begin != null">entrydate <![CDATA[ >= ]]>  #{begin} and</if>
    <if test="end != null">entrydate <![CDATA[ <= ]]>  #{end}</if>
</where>

set标签:在更新数据(update语句中)时,set 标签对可以动态删除包裹的 if 标签对中多于的逗号。
范例:

<set>
	<if test="username != null">username = #{username},</if>
	<if test="name != null">name = #{name},</if>
	<if test="gender != null">gender = #{gender},</if>
	<if test="updateTime != null">update_time = #{updateTime}</if>
</set>

foreach标签:遍历。批量操作时使用。
foreach常用属性:collection:遍历的集合;item:遍历出来的元素;separator:分隔符;open:遍历开始前拼接的SQL片段;close:遍历结束后拼接的SQL片段。
范例:根据id遍历删除批量数据

<delete id="deleteByIds">
	delete from emp where id in
	<foreach collection="ids" item="id" separator="," open="(" close=")">
		#{id}
	</foreach>
</delete>

sql标签与include标签:sql标签抽取代码,include标签调用抽取的代码。sql与include成对使用。
范例:

# <sql></sql>标签对抽取代码,方便复用
<sql id="commonSelect">
	select id, username,name,gender from emp
</sql>

<select id="list" resultType="com.wurongjiang.pojo.Emp">
	# <include></include>标签引用<sql></sql>标签抽取的代码。
	<include refid="commonSelect"/>
	<where>
		<if test="name != null"> name like concat('%',#{name},'%') </if>
		<if test="gender != null"> and gender = #{gender} </if>
	</where>
</select>

3、总结

  1. 在新建SpringBoot项目时,将Server URL栏的https://start.spring.io替换成https://start.aliyun.com/
  2. 在配置文件配置MyBatis时,可以添加日志配置和自动驼峰命名转换配置。
# MyBatis日志配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 开启自动驼峰命名转换
mybatis.configuration.map-underscore-to-camel-case=true
  1. MyBatis常用的编写SQL语句的四个注解@Select、@Delete、@Update、@Insert。
  2. SQL语句中的占位符,#{…}:执行SQL时,会将 #{ } 替换为 ?,生成预编译SQL,会自动设置参数值,能够避免SQL注入风险;${…}:拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题。。
  3. @Delete、@Update、@Insert定义的接口都具有返回值。需要返回值时将返回类型修改成int,返回值为该条SQL语句操作的数据条数。
  4. 主键返回需要在接口方法上再加上一个@Options注解,设置useGeneratedKeys属性和keyProperty属性。动态SQL需要在insert标签对中设置useGeneratedKeys属性和keyProperty属性。
  5. MySQL提供的concat()函数能够拼接字符串。在模糊匹配时,推荐使用。
@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
        "entrydate between #{begin} and #{end} order by update_time desc")
List<Emp> list(@Param("name")String name, @Param("gender")Short gender,
               @Param("begin")LocalDate begin, @Param("end")LocalDate end);
  1. 动态SQL中比较大小需要使用<![CDATA[ >= ]]>替换。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT5 Creator (Mingw编译器) 调用VS2019 (阿里云 oss C++库) 报错的解决方法

方法就是不要用VS2019编译&#xff0c;要用MINgw32编译。注意要安装高版本的qt&#xff0c;其自带的mingw编译器才能支持&#xff0c;找不到qt5cored.dll&#xff0c;就把qt5core.dll改名为qt5cored.dll。 编译命令如下&#xff1a; cmake -G "MinGW Makefiles" ^-…

Scala—Slice(提取子序列)方法详解

Scala—Slice&#xff08;提取子序列&#xff09;方法详解 在 Scala 中&#xff0c;slice 方法用于从集合中提取一个连续的子序列&#xff08;切片&#xff09;。可以应用于多种集合类型&#xff0c;如 List、Array、Seq 等。 一、slice 方法的定义 slice 根据提供的起始索引…

Alibaba EasyExcel 导入导出全家桶

一、阿里巴巴EasyExcel的优势 首先说下EasyExcel相对 Apache poi的优势&#xff1a; EasyExcel也是阿里研发在poi基础上做了封装&#xff0c;改进产物。它替开发者做了注解列表解析&#xff0c;表格填充等一系列代码编写工作&#xff0c;并将此抽象成通用和可扩展的框架。相对p…

基于SpringBoot+Vue的美妆购物网站

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【Altium Designer 】AD如何使用嘉立创元器件的3D封装

1.下载3D封装 以STM32F407VGT6为例&#xff0c;进入嘉立创商城网站&#xff0c;找到需要的元器件封装 复制编号&#xff0c;打开嘉立创EDA&#xff0c;编译器选择专业版&#xff0c;新建工程&#xff0c;点击PCB1 复制编号在搜索框中&#xff0c;点击搜索&#xff0c;然后放置…

轨道力学:兰伯特问题

轨道力学&#xff1a;兰伯特问题 引言 在轨道力学中&#xff0c;兰伯特问题是指在已知两个位置矢量和它们之间的飞行时间的情况下&#xff0c;求解连接这两个位置的轨道路径问题。该问题以18世纪的数学家约翰海因里希兰伯特&#xff08;Johann Heinrich Lambert&#xff09;命…

计算机网络 第5章 运输层

计算机网络 &#xff08;第8版&#xff09; 第 5 章 传输层5.4 可靠传输的原理5.4.1 停止等待协议5.4.2 连续ARQ协议 5.5 TCP报文段的首部格式5.6 TCP可靠传输的实现5.6.1 以字节为单位的滑动窗口5.6.2 超时重传时间的选择 5.7 TCP的流量控制5.7.1 利用滑动窗口实现流量控制 5.…

【AI系统】EfficientNet 系列

EfficientNet 系列 本文主要介绍 EffiicientNet 系列&#xff0c;在之前的文章中&#xff0c;一般都是单独增加图像分辨率或增加网络深度或单独增加网络的宽度&#xff0c;来提高网络的准确率。而在 EfficientNet 系列论文中&#xff0c;会介绍使用网络搜索技术(NAS)去同时探索…

debian编译失败

A、缘由和分析 debian的代码在删除该路径下的2个包后&#xff0c; 重新全编&#xff0c;编译不过的问题。 至于我为什么删除这2个包&#xff0c;这是因为在sdk第一次编译时一些文件已经打包进去了&#xff0c;我现在的修改无法更新进img中&#xff0c;而现在我的项目中不需要…

2024年12月5日Github流行趋势

项目名称&#xff1a;HelloGitHub 项目维护者&#xff1a;521xueweihan, yaowenqiang, daixiang0等项目介绍&#xff1a;分享 GitHub 上有趣、入门级的开源项目。项目star数&#xff1a;95,244项目fork数&#xff1a;9,707 项目名称&#xff1a;Best-websites-a-programmer-sh…

大数据新视界 -- 大数据大厂之 Hive 临时表与视图:灵活数据处理的技巧(上)(29 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

第一部分:基础知识 3. 数据类型 --[MySQL轻松入门教程]

第一部分:基础知识 3. 数据类型 --[MySQL轻松入门教程] MySQL 支持多种数据类型,这些数据类型可以分为几大类:数值类型、字符串类型、日期和时间类型、二进制类型以及枚举和集合。每种类型都有其特定的用途和存储需求。以下是 MySQL 中常用的数据类型的详细介绍: 1. 数值…

百问FB显示开发图像处理 - 图像调整

2.4 图像调整 2.4.1 图像的缩放 2.4.1.1 图像缩放算法浅析 图像缩放算法有很多种&#xff0c;这里参考网友"lantianyu520"所著的"图像缩放算法"。 原理浅析 ​ 要理解这个图像缩放算法的原理&#xff0c;最重要的是需要理解&#xff1a;对于图像上的每…

嵌入式驱动开发详解5(ioctl的使用)

文章目录 ioctl介绍应用层详解驱动层详解ioctl的cmd实验例程 ioctl介绍 linux内核给用户提供了两类系统调用函数&#xff1a;一类是数据操作函数&#xff0c;比如read、write…。 另外一类函数是非数据操作函数&#xff0c;比如ioctl…&#xff0c;用户程序可以用ioctl给底层设…

从零开始使用GOT-OCR2.0——多模态OCR项目:微调数据集构建 + 训练(解决训练报错,成功实验微调训练)

在上一篇文章记录了GOT-OCR项目的环境配置和基于官方模型参数的基础使用。环境安装的博文快速链接&#xff1a; 从零开始使用GOT-OCR2.0——多模态通用型OCR&#xff08;非常具有潜力的开源OCR项目&#xff09;&#xff1a;项目环境安装配置 测试使用-CSDN博客 本章在环境配置…

Facebook:筑牢隐私安全堡垒,守护社交净土

在全球社交媒体平台中&#xff0c;Facebook一直是风靡全球的佼佼者。然而&#xff0c;随着数字化信息的迅速膨胀&#xff0c;用户隐私保护的重要性日益凸显。面对用户对数据安全性的高度重视&#xff0c;Facebook致力于通过一系列措施来确保隐私保护&#xff0c;守护每位用户的…

VBA信息获取与处理第四个专题第二节:将工作表数据写入VBA数组

《VBA信息获取与处理》教程(版权10178984)是我推出第六套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。这部教程给大家讲解的内容有&#xff1a;跨应用程序信息获得、随机信息的利用、电子邮件的发送、VBA互…

python通过ODBC连接神通数据库

1、安装神通数据库 2、安装python 3、安装pyodbc pip3 install pyodbc-5.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 注&#xff1a;pyodbc要和python版本相对应 4、安装unixodbc 5、配置神通数据库ODBC数据源 6、示例代码如下 #!/usr/bin/python…

Vue Web开发(一)

1. 环境配置 1.1. 开发工具下载 1.1.1. HbuilderX 官网地址&#xff1a;https://uniapp.dcloud.net.cn/ 1.1.2. Visual Studio Code 官网地址&#xff1a;https://code.visualstudio.com/Download 1.1.3. Node环境 官网地址&#xff1a;https://nodejs.cn/   正常软件安装…

Tomcat新手成长之路:安装部署优化全解析(下)

接上篇《Tomcat新手成长之路&#xff1a;安装部署优化全解析&#xff08;上&#xff09;》: link 文章目录 7.应用部署7.1.上下文7.2.启动时进行部署7.3.动态应用部署 8.Tomcat 类加载机制8.1.简介8.2.类加载器定义8.3.XML解析器和 Java 9.JMS监控9.1.简介9.2.启用 JMX 远程监…