MyBatis 增删改查操作

news2025/7/11 16:22:40

什么是 MyBatis?

mybatis 是一款优秀的持久层框架,用于简化 JDBC 开发

MyBatis 本是 Apach 的一个开源项目 iBatis,2021 年这个项目由 apach software foundation 迁移到了 google code,并且改名为 MyBatis。2013 年 11 月迁移到 GitHub

官网:https://mybatis.org/mybatis-3/zh/index.html

持久层

1.负责将数据保存到数据库的那一层代码

2.JavaEE 三层架构:表现层、业务层、持久层

框架

1.框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型

2.在框架的基础之上构建软件编写更加高效、规范、通用、可扩展

JDBC 缺点

JDBC 可参考:https://blog.csdn.net/weixin_46665411/article/details/122346809

1.硬编码

  • 注册驱动,获取连接

  • SQL 语句

2.操作繁琐

  • 手动设置参数

  • 手动封装结果集

MyBatis 快速入门

查询 User 表中,所有数据

1.创建 user 表,添加数据

创建 tb_user

CREATE DATABASE mybatis;
USE mybatis;

DROP table if EXISTS tb_user;

CREATE TABLE tb_user(
 id INT PRIMARY KEY auto_increment,
 username VARCHAR(20),
 `password` VARCHAR(20),
 gender CHAR(1),
 addr VARCHAR(30)
);

INSERT INTO tb_user VALUES(1,'zhangsan','123','男','北京');
INSERT INTO tb_user VALUES(2,'李四','234','女','天津');
INSERT INTO tb_user VALUES(3,'王五','11','男','西安');

2.创建模块,导入模块

3.编写 MyBatis 核心配置文件–>替换连接信息,解决硬编码问题

mybatis-config.xml

<?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"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载SQL映射文件-->
        <mapper resource="userMapper.xml"/>
    </mappers>
</configuration>

4.编写 SQL 映射文件–>统一管理 sql 语句,解决硬编码问题

映射文件 userMapper.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">
<mapper namespace="test">
    <select id="selectAll" resultType="com.mkyuan.pojo.User">
        select * from tb_User;
    </select>
</mapper>

5.编码

  • 定义 POJO 类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String userName;
    private String password;
    private String gender;
    private String addr;
}
  • 加载核心配置文件,获取 SqlSessionFactory 对象
 //1.加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream;
        SqlSessionFactory sqlSessionFactory = null;
        {
            try {
                inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  • 获取 SqlSession 对象,执行 SQL 语句
       //2.获取SqlSession对象,用来执行SQL
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3.执行sql
        List<User> users = sqlSession.selectList("test.selectAll");
  • 释放资源
 //4.释放资源
 sqlSession.close();

Mapper 代理开发

1.定义与 SQL 映射文件同命的 Mapper 接口,并且将 Mapper 接口和 SQL 映射文件放置在同一目录下

2.设置 SQL 映射文件的 nameSpace 属性为 Mapper 接口全限定类名

3.在 Mapper 接口中定义方法,方法名就是 SQL 映射文件中 sql 语句中的 id,并保持参数类型和返回值类型一致

4.编码

  • 通过 SqlSession 的 getMapper 方法获取 Mapper 接口的代理对象

  • 调用对应方法完成 sql 的执行

       //3.执行sql
       //List<User> users = sqlSession.selectList("test.selectAll");
       //3.1获取UserMapper接口的代理对象
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       List<User> users = mapper.selectAll();

细节:如果 Mapper 接口名称和 SQL 映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化 SQL 映射文件的加载

    <mappers>
        <!--加载SQL映射文件-->
        <!--mapper resource="com/mkyuan/mapper/userMapper.xml"/>-->

        <!--Mapper代理方式-->
        <package name="com.mkyuan.mapper"/>
    </mappers>

MyBatis 核心配置文件

类型别名

    <typeAliases >
        <package name="com.mkyuan.pojo"/>
    </typeAliases>

配置各个标签时,需要遵循前后顺序

配置文件完成增删改查

1.创建表 tb_brand

-- 删除tb_brand表
DROP TABLE
IF
	EXISTS tb_brand;-- 创建tb_brand表
CREATE TABLE tb_brand (-- id主键
	id INT PRIMARY KEY auto_increment,-- 品牌名称
	brand_name VARCHAR ( 20 ),-- 企业名称
	company_name VARCHAR ( 20 ),-- 排序字段
	ordered INT,-- 排序字段
	description VARCHAR ( 100 ),-- 描述信息
	`status` INT -- 状态:0:禁用 1启用

);-- 添加数据
INSERT INTO tb_brand ( brand_name, company_name, ordered, description, `status` )
VALUES
	( '三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0 ),
( '华为', '华为技术有限公司', 100, '华为致力于把数字世界带给每个人、每个家庭、每个组织、构建万物互联的智能世界', 1 ),
( '小米', '小米科技有限公司', 50, 'are you ok', 0 )

2.查询所有数据

① 编写接口方法:Mapper 接口

public interface BrandMapper {
    /**
     * 查询所有
     * @return
     */
    List<Brand> selectAll();
}
  • 参数:无

  • 结果:List

② 编写 SQL 语句:SQL 映射文件

  <mapper namespace="com.mkyuan.mapper.BrandMapper">
    <select id="selectAll" resultType="com.mkyuan.pojo.Brand">
        select * from tb_brand;
    </select>
</mapper>

③ 执行方法,测试

   @Test
    public void TestSelectAll() throws IOException {
        //1.获取SqlSessionFactory
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        //4.执行方法
        List<Brand> brands = mapper.selectAll();
        for (Brand brand : brands) {
            System.out.println(brand);
        }
        //5.释放资源
        sqlSession.close();
    }

实体类属性名和数据库名不一致,不能自动封装数据

① 起别名:对不一样的列名起别名,让别名和实体类的属性名一致

  • 缺点:每次查询都要定义一次别名
  • sql 片段:不灵活

② resultMap

  • 定义标签

  • 在< select>标签中使用 resultMap 属性替换 resultType 属性

  <mapper namespace="com.mkyuan.mapper.BrandMapper">
    <!--数据库的字段名称和实体类的属性名称不一样,则不能自动封装数据
       ① 起别名:对不一样的列名起别名,让别名和实体类的属性名一致
         * 缺点:每次查询都要定义一次别名
         *sql片段:不灵活
       ② resultMap
          (1).定义<resultMap>标签
           (2).在<select>标签中使用resultMap属性替换resultType属性
    -->
    <resultMap id="brandResultMap" type="brand">
        <!--
        id:完成主键字段的映射
            column:表的列名
            property:实体类的属性名
        result:完成一般字段的映射
            column:表的列名
            property:实体类的属性名
        -->
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>
    <select id="selectAll" resultMap="brandResultMap">
        select
         *
        from tb_brand;
    </select>

    <!--sql片段-->
   <!-- <sql id="brand_column">
        id,brand_name as brandName,company_name as companyName,ordered,description,status
    </sql>
    <select id="selectAll" resultType="com.mkyuan.pojo.Brand">
        select
        <include refid="brand_column"></include>
        from tb_brand;
    </select>
   -->
</mapper>

3.查看详情

① 编写接口方法:Mapper 接口

 Brand selectById(int id);
  • 参数:id

  • 结果:Brand

② 编写 SQL 语句:SQL 映射文件

<!--   参数占位符
       ① #{}:会将其替换为?,为了防止SQL注入
       ② ${}:拼接sql,会存在SQL注入问题
       ③ 使用时机
           - 参数传递的时候:#{}
           - 表名或者列名不固定的情况下:${} 会存在SQL注入问题
       参数类型: parameterType:可以省略
       特殊字符处理:
           ① 转义字符:
           ② CDATA区
-->

   <!-- <select id="selectById"  resultMap="brandResultMap">
        select * from tb_brand where id= #{id}
    </select>-->
    <select id="selectById"  resultMap="brandResultMap">
        select * from tb_brand where id
        <![CDATA[
            <
        ]]>
        #{id}
    </select>

③ 执行方法,测试

  BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4.执行方法
 Brand brand = mapper.selectById(id);

参数占位符

① #{}:会将其替换为?,为了防止 SQL 注入

② ${}: 拼接 sql,会存在 SQL 注入问题

③ 使用时机

  • 参数传递的时候:#{}

  • 表名或者列名不固定的情况下:${} 会存在 SQL 注入问题

参数类型: parameterType:可以省略

特殊字符处理:

① 转义字符

② CDATA 区

4.条件查询

① 编写接口方法:Mapper 接口

    /**
     * 条件查询
     *        参数类型
     *        1.散装参数:如果方法中有多个参数,需要使用@Param("SQL参数占位符名称")
     *        2.对象参数
     *        3.map集合参数
     * @param status
     * @param companyName
     * @param brandName
     * @return
     */
    List<Brand> selectByCondition(
            @Param("status") int status,
            @Param("companyName") String companyName,
            @Param("brandName") String brandName
    );
    List<Brand> selectByCondition(Brand brand);
    List<Brand> selectByCondition(Map map);
  • 参数:所有查询条件

  • 结果:List< Brand>

② 编写 SQL 语句:SQL 映射文件

    <select id="selectByCondition" resultMap="brandResultMap">
        select *
        from tb_brand
        where status =#{status}
        and company_name like #{companyName}
        and brand_name like #{brandName}
    </select>

③ 执行方法,测试

      @Test
    public void TestSelectByCondition() throws IOException {
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";
        //1.获取SqlSessionFactory
//        Brand brand1 = new Brand();
//        brand1.setStatus(status);
//        brand1.setBrandName(brandName);
//        brand1.setCompanyName(companyName);
        Map map = new HashMap();
        map.put("status", status);
        map.put("companyName", companyName);
        map.put("brandName", brandName);
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        //4.执行方法
        //List<Brand> brands = mapper.selectByCondition(status,companyName,brandName);
        //List<Brand> brand1 = mapper.selectByCondition(brand1);
        List<Brand> brands = mapper.selectByCondition(map);

        for (Brand brand : brands) {
            System.out.println(brand);
        }
        //5.释放资源
        sqlSession.close();
    }

sql 语句设置多个参数有几种方式?

  • 散装参数:需要使用@Param(“SQL 中的参数占位符名称”)

  • 实体类封装参数:只需要保证 SQL 中的参数名和实体类属性名对应上,即可设置成功

  • map 集合:只需要保证 SQL 中参数名和 map 集合的键的名称对应上,即可设置成功

5.动态条件查询

SQL 语句会随着用户的输入或外部条件的变化而变化,我们称之为动态的 SQL

Mybatis 对动态 SQL 有很强大的支撑

if

    <!--
    if:用于判断参数是否有值,使用test进行条件判断
    存在的问题:第一个条件不需要逻辑运输符
    解决方案:
        ① 使用恒等式让所有条件格式都一样
        ② <where>标签替换where关键字
    -->
    <select id="selectByCondition" resultMap="brandResultMap">
        select *
        from tb_brand
        <where>
            <if test="status != null">
                and status =#{status}
            </if>
            <if test="companyName != null">
                and company_name like #{companyName}
            </if>
            <if test="brandName != null">
                and brand_name like #{brandName}
            </if>
        </where>
    </select>

choose(when,otherwise)

 <select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from
        tb_brand
        <where>
            <choose><!--相当于switch-->
                <when test="status != null"><!--相当于case-->
                    status =#{status}
                </when>
                <when test="companyName != null and companyName !=''"><!--相当于case-->
                    and company_name like #{companyName}
                </when>
                <when test="brandName != null and brandName !=''"><!--相当于case-->
                    and brand_name like #{brandName}
                </when>
                <otherwise><!--相当于default-->
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>

6.添加

① 编写接口方法:Mapper 接口

     /**
     * 添加
     * @param brand
     */
    void add(Brand brand);
  • 参数:除了 id 之外的所有数据

  • 结果:void

② 编写 SQL 语句:SQL 映射文件

     <insert id="add" parameterType="brand">
        insert into tb_brand(brand_name,company_name,ordered,description,status)
        values(#{brandName},#{companyName},#{ordered},#{description},#{status})
    </insert>

③ 执行方法,测试

 @Test
    public void TestAdd() throws IOException {
        int status = 1;
        String companyName = "波导手机";
        String brandName = "波导";
        String description ="手机中的战斗机";
        int ordered = 100;
        //1.获取SqlSessionFactory
        Brand brand1 = new Brand();
        brand1.setStatus(status);
        brand1.setBrandName(brandName);
        brand1.setCompanyName(companyName);
        brand1.setDescription(description);
        brand1.setOrdered(ordered);
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        mapper.add(brand1);
        //提交事务
        sqlSession.commit();
        //5.释放资源
        sqlSession.close();
    }

mybatis 事务:

  • openSession():默认开启事务,进行增删改操作后需要使用 sqlSession.commit()手动提交事务

  • openSession(true):可以设置为自动提交事务(关闭事务)

7.添加-主键返回

在数据添加成功后需要获取插入数据库数据的主键的值

比如:添加订单和订单项

  • 添加订单

  • 添加订单项,订单中需要设置所属订单的 id

    <insert id="add" useGeneratedKeys="true" keyProperty="id">
        insert into tb_brand(brand_name,company_name,ordered,description,status)
        values(#{brandName},#{companyName},#{ordered},#{description},#{status})
    </insert>

测试

        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        mapper.add(brand1);
        Integer id = brand1.getId();
        System.out.println(id);

8.修改-修改全部字段

① 编写接口方法:Mapper 接口

     /**
     * 修改
     * @return
     */
    int update(Brand brand);
  • 参数:所有数据

  • 结果:void

② 编写 SQL 语句:SQL 映射文件

<update id="update">
        update tb_brand
        set
        brand_name = #{brandName},
        company_name=#{companyName},
        ordered=#{ordered},
        description=#{description},
        status=#{status}
        where id =#{id}
</update>

③ 执行方法,测试

    @Test
    public void TestUpdate() throws IOException {
        int status = 1;
        String companyName = "波导手机";
        String brandName = "波导plus";
        String description ="波导手机,手机中的战斗机";
        int ordered = 100;
        int id=4;
        //封装对象
        Brand brand1 = new Brand();
        brand1.setStatus(status);
        brand1.setBrandName(brandName);
        brand1.setCompanyName(companyName);
        brand1.setDescription(description);
        brand1.setOrdered(ordered);
        brand1.setId(id);
        //1.获取SqlSessionFactory
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        int count = mapper.update(brand1);
        System.out.println(count);
        //提交事务
        sqlSession.commit();
        //5.释放资源
        sqlSession.close();
    }

9.修改数据-修改动态字段

① 编写接口:Mapper 接口

  • 参数:部分数据,封装到对象中

  • 结果:void

② 编写 SQL 语句:SQL 映射文件

<update id="update">
        update tb_brand
        set
        <if test="brandName!=null and brandName!=''">
            brand_name = #{brandName},
        </if>
        <if test="companyName !=null and companyName !=''">
            company_name=#{companyName},
        </if>
        <if test="ordered!=null">
            ordered=#{ordered},
        </if>
        <if test="description!=null and description !=''">
            description=#{description},
        </if>
        <if test="status!=null">
            status=#{status}
        </if>
        where id =#{id}
    </update>

③ 执行方法,测试

  @Test
    public void TestUpdate() throws IOException {
        int status = 1;
        String companyName = "波导手机";
        String brandName = "波导plus2";
        String description ="波导手机,手机中的战斗机";
        int ordered = 103;
        int id=4;
        //封装对象
        Brand brand1 = new Brand();
        brand1.setStatus(status);
        brand1.setBrandName(brandName);
//        brand1.setCompanyName(companyName);
//        brand1.setDescription(description);
        brand1.setOrdered(ordered);
        brand1.setId(id);
        //1.获取SqlSessionFactory
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        int count = mapper.update(brand1);
        System.out.println(count);
        //提交事务
        sqlSession.commit();
        //5.释放资源
        sqlSession.close();
    }

10.删除一个

① 编写接口方法,Mapper 接口

    /**
     * 删除一个
     * @param id
     */
    void deleteById(int id);
  • 参数:id

  • 结果:void

② 编写 SQL 语句,SQl 映射文件

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

③ 执行方法,测试

@Test
    public void TestDeleteById() throws IOException {
        int id = 5;
        //1.获取SqlSessionFactory
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        mapper.deleteById(id);
        //提交事务
        sqlSession.commit();
        //5.释放资源
        sqlSession.close();
    }

11.批量删除

① 编写接口方法,Mapper 接口

    /**
     * 批量删除
     */
    void deleteByIds(@Param("ids") int[] ids);
  • 参数:id 数组

  • 结果:void

② 编写 SQL 语句,SQL 映射文件

    <!--
    mybatis会将数组参数,封装为一个Map集合
        ①默认:array = 数组
        ②使用@Param注解改变map集合的默认key的名称
    -->
    <delete id="deleteById">
        delete from tb_brand where id=#{id}
    </delete>
    <delete id="deleteByIds">
        delete
        from tb_brand where id in
        <foreach collection="ids" item="id"  separator="," open="(" close=")">
           #{id}
        </foreach>
    </delete>

③ 执行方法,测试

 @Test
    public void TestDeleteByIds() throws IOException {
        int ids[]  = {9,10,11};
        //1.获取SqlSessionFactory
        String resources = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resources);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取mapper接口的代理对象
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        mapper.deleteByIds(ids);
        //提交事务
        sqlSession.commit();
        //5.释放资源
        sqlSession.close();
    }

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

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

相关文章

[附源码]java毕业设计氧气罐管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

js逆向之反调试之无限debugger解决

js逆向之反调试之无限debugger解决 文章目录 js逆向之反调试之无限debugger解决方案一方案二方案三方案一 右击debugger行数位置,点击add conditional breakpoint… 点击add conditional breakpoint.png 添加false,然后按回撤, 刷新网页,发现成功跳过无限debugger 修改成…

TiDB 6.0 新特性

TiDB 6.0 新特性 Placement Rules in SQL小表缓存内存悲观锁Top SQLTiDB Enterprise Manager(TiEM) Placement Rules in SQL Placement Rules in SQL 之前&#xff1a; 跨地域部署的集群&#xff0c;无法本地访问无法根据业务隔离资源&#xff0c;leader全在一个TiKV节点上…

CTFHub | UA注入

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

新发现,新挑战,技术出海的机遇与挑战丨PingCAP DevCon 2022 出海专场

现在报名活动&#xff0c;有机会获得限定好礼哦&#xff01;&#x1f446; 中国企业出海的格局和挑战正在发生重大改变。回到技术管理者熟悉的技术世界&#xff0c;过去两年的技术环境也发生了巨大的变化&#xff0c;开源软件与云服务的结合成为业界共识的潮流&#xff0c;在多…

linux篇【11】:linux下的线程<后序>

目录 一.线程互斥 1.三个概念 2.互斥 &#xff08;1&#xff09;在执行语句的任何地方&#xff0c;线程可能被切换走 &#xff08;3&#xff09;抢票场景中的问题 &#xff08;4&#xff09;解决方案 3.加锁 &#xff08;1&#xff09;加锁介绍 &#xff08;2&#xf…

C语言百日千题系列之《忘情水题》第一日

目录 绪论 1.最大数位置 2.与指定数字相同的数的个数 3.蓝桥杯2013年第四届真题-核桃的数量 4.求所给范围内水仙花数并排列 5.最大值和最小值的差 6.计算书费 7.角谷猜想 8. 最高的分数 9.年龄与疾病 10.-百钱百鸡问题 绪论 本文是C语言百日千题系列《忘情水题》的第…

BCN衍生物:endo-BCN-PEG4-TAMRA,endo-BCN-PEG4-Palmitic,endo-BCN-PEG4-DSPE的特点分享

凯新生物公司小编分享&#xff1a;endo-BCN-PEG4-TAMRA &#xff0c;endo-BCN-PEG4-Palmitic&#xff0c;endo-BCN-PEG4-DSPE这几种的物理相关数据。 1、endo-BCN-PEG4-TAMRA 四甲基罗丹明&#xff08;TAMRA&#xff09;-叠氮化物是一种化学探针&#xff0c;用于直接在活细胞中…

代码随想录算法训练营第八天|二叉树(截止到左叶子之和)

翻转二叉树 Leecode 226.翻转二叉树 链接&#xff1a;https://leetcode.cn/problems/invert-binary-tree/ 用递归来做&#xff0c;若是遇到空节点&#xff0c;直接return 然后交换左右节点&#xff0c;接着递归 class Solution { public:TreeNode* invertTree(TreeNode* r…

Java代码审计——SSH 框架审计技巧

目录 &#xff08;一&#xff09; SSH 框架简介 &#xff08;二&#xff09; Java SSH 框架审计技巧 &#xff08;一&#xff09; SSH 框架简介 上个月介绍了 SSM 框架&#xff0c;即 Spring MVC、Spring 和 MyBatis。接下来介绍 Java Web曾经开发的 SSH 框架&#xff0c;即 …

河北涿州水稻种植历史 国稻种芯·中国水稻节:保定效益双赢

河北涿州水稻种植历史 国稻种芯中国水稻节&#xff1a;保定效益双赢 央视网消息 保定日报讯&#xff08;通讯员张千 刘永兴 王蕾&#xff09;新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农…

浅谈前缀索引

一.什么是前缀索引 所谓前缀索引说白了就是对字符串或前n个字符建立索引 二.为什么选择前缀索引 一般来说使用前缀索引&#xff0c;可能都是因为整个字段的数据量太大&#xff0c;没有必要针对整个字段建立索引&#xff0c;前缀索引仅仅是选择一个字段的前n个字符作为索引&a…

Linux运维工程师的操作规范

&#xff0c;Linux运维工程师的操作规范从事运维有一段时间了&#xff0c;遇到过各式各样的问题&#xff0c;数据丢失&#xff0c;网站挂马&#xff0c;误删数据库文件&#xff0c;黑客攻击等各类问题。 今天简单整理一下&#xff0c;分享给各位小伙伴。 一、线上操作规范 1、…

你可见过如此细致的延时任务详解

概述 延时任务相信大家都不陌生&#xff0c;在现实的业务中应用场景可以说是比比皆是。例如订单下单 15 分钟未支付直接取消&#xff0c;外卖超时自动赔付等等。这些情况下&#xff0c;我们该怎么设计我们的服务的实现呢&#xff1f; 笨一点的方法自然是定时任务去数据库进行轮…

华为机试 - 滑动窗口最大和

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 有一个N个整数的数组&#xff0c;和一个长度为M的窗口&#xff0c;窗口从数组内的第一个数开始滑动直到窗口不能滑动为止&#xff0c; 每次窗口滑动产生一个窗口和&#xff08;窗口内所有数的和&…

常用的框架技术-09 Spring Security Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录1.Spring Security简介1.1 Spring Security概述1.2 Spring Security历史发展1.3 产品的对比1.3.1 Spring Security1.3.2 Shiro1.4 Spring Security 核心类1.4.1 Auth…

qemu 线程 vhost

[rootlocalhost cloud_images]# lsmod | grep vhost_net vhost_net 262144 0 vhost 262144 1 vhost_net tap 262144 1 vhost_net tun 262144 2 vhost_net [rootlocalhost cloud_images]#vhost-net网卡的…

[附源码]SSM计算机毕业设计基于实时定位的超市配送业务管理JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

低碳世界杂志低碳世界杂志社低碳世界编辑部2022年第7期目录

节能环保 挥发性有机物的全厂控制措施 董少军; 1-3 《低碳世界》投稿&#xff1a;cnqikantg126.com 佛山市市政排水管网通沟污泥处理处置工艺设计 张红; 4-6 “双碳”背景下海岸带地区适应气候变化评估与对策研究 王鸿浩;邬乐雅;吴晓晨;张丽佳;黄婧蓼琦;胡斐…

【毕业设计】基于情感分析的网络舆情热点分析系统

文章目录0 前言1 课题背景2 数据处理3 文本情感分析3.1 情感分析-词库搭建3.2 文本情感分析实现3.3 建立情感倾向性分析模型4 数据可视化工具4.1 django框架介绍4.2 ECharts5 Django使用echarts进行可视化展示5.1 修改setting.py连接mysql数据库5.2 导入数据5.3 使用echarts可视…