day30--mybatis(三)高级

一.Mybatis注解开发单表操作

1.1 MyBatis的常用注解

这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper

映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。

@Insert:实现新增

@Update:实现更新

@Delete:实现删除

@Select:实现查询

@Result:实现结果集封装

@Results:可以与@Result 一起使用,封装多个结果集

@One:实现一对一结果集封装

@Many:实现一对多结果集封装

1.2 MyBatis的增删改查

我们完成简单的student表的增删改查的操作

  • 步骤一:创建mapper接口

    public interface StudentMapper {
        //查询全部
        @Select("SELECT * FROM student")
        public abstract List<Student> selectAll();
    
        //新增操作
        @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
        public abstract Integer insert(Student stu);
    
        //修改操作
        @Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
        public abstract Integer update(Student stu);
    
        //删除操作
        @Delete("DELETE FROM student WHERE id=#{id}")
        public abstract Integer delete(Integer id);
    }
    
    
  • 步骤二:测试类

    public class Test01 {
        @Test
        public void selectAll() throws Exception{
            //1.加载核心配置文件
            InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
    
            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    
            //3.通过工厂对象获取SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            //5.调用实现类对象中的方法,接收结果
            List<Student> list = mapper.selectAll();
    
            //6.处理结果
            for (Student student : list) {
                System.out.println(student);
            }
    
            //7.释放资源
            sqlSession.close();
            is.close();
        }
    
        @Test
        public void insert() throws Exception{
            //1.加载核心配置文件
            InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
    
            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    
            //3.通过工厂对象获取SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            //5.调用实现类对象中的方法,接收结果
            Student stu = new Student(4,"赵六",26);
            Integer result = mapper.insert(stu);
    
            //6.处理结果
            System.out.println(result);
    
            //7.释放资源
            sqlSession.close();
            is.close();
        }
    
        @Test
        public void update() throws Exception{
            //1.加载核心配置文件
            InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
    
            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    
            //3.通过工厂对象获取SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            //5.调用实现类对象中的方法,接收结果
            Student stu = new Student(4,"赵六",36);
            Integer result = mapper.update(stu);
    
            //6.处理结果
            System.out.println(result);
    
            //7.释放资源
            sqlSession.close();
            is.close();
        }
    
        @Test
        public void delete() throws Exception{
            //1.加载核心配置文件
            InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
    
            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    
            //3.通过工厂对象获取SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
            //4.获取StudentMapper接口的实现类对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            //5.调用实现类对象中的方法,接收结果
            Integer result = mapper.delete(4);
    
            //6.处理结果
            System.out.println(result);
    
            //7.释放资源
            sqlSession.close();
            is.close();
        }
    }
    
    
  • 注意:

    修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可

<mappers>
    <!--扫描使用注解的类-->
    <mapper class="com.zhushanglin.mapper.UserMapper"></mapper>
</mappers>

​ 或者指定扫描包含映射关系的接口所在的包也可以

<mappers>
    <!--扫描使用注解的类所在的包-->
    <package name="com.zhushanglin.mapper"></package>
</mappers>
1.3 注解开发总结

注解可以简化开发操作,省略映射配置文件的编写。

  • 常用注解

    @Select(“查询的 SQL 语句”):执行查询操作注解

    @Insert(“查询的 SQL 语句”):执行新增操作注解

    @Update(“查询的 SQL 语句”):执行修改操作注解

    @Delete(“查询的 SQL 语句”):执行删除操作注解

  • 配置映射关系

    <mappers> <package name="接口所在包"/> </mappers>    
    

二.MyBatis注解开发的多表操作

2.1 MyBatis的注解实现复杂映射开发

实现复杂关系映射之前我们可以在映射文件中通过配置来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置

2.2 一对一查询
2.2.1 一对一查询的模型

一对一查询的需求:查询一个用户信息,与此同时查询出该用户对应的身份证信息

1590942011460

2.2.2 一对一查询的语句

对应的sql语句:

SELECT * FROM card;

SELECT * FROM person WHERE id=#{id};
2.2.3 创建PersonMapper接口
public interface PersonMapper {
    //根据id查询
    @Select("SELECT * FROM person WHERE id=#{id}")
    public abstract Person selectById(Integer id);
}

2.2.4 使用注解配置Mapper
public interface CardMapper {
    //查询全部
    @Select("SELECT * FROM card")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "number",property = "number"),
            @Result(
                    property = "p",             // 被包含对象的变量名
                    javaType = Person.class,    // 被包含对象的实际数据类型
                    column = "pid",             // 根据查询出的card表中的pid字段来查询person表
                    /*
                        one、@One 一对一固定写法
                        select属性:指定调用哪个接口中的哪个方法
                     */
                    one = @One(select = "com.zhushanglin.one_to_one.PersonMapper.selectById")
            )
    })
    public abstract List<Card> selectAll();
}
2.2.5 测试类
public class Test01 {
    @Test
    public void selectAll() throws Exception{
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取CardMapper接口的实现类对象
        CardMapper mapper = sqlSession.getMapper(CardMapper.class);

        //5.调用实现类对象中的方法,接收结果
        List<Card> list = mapper.selectAll();

        //6.处理结果
        for (Card card : list) {
            System.out.println(card);
        }

        //7.释放资源
        sqlSession.close();
        is.close();
    }

}

2.2.6 一对一配置总结
@Results:封装映射关系的父注解。
	Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
	column 属性:查询出的表中字段名称
	property 属性:实体对象中的属性名称
	javaType 属性:被包含对象的数据类型
	one 属性:一对一查询固定属性
 @One:一对一查询的注解。
	select 属性:指定调用某个接口中的方法
2.3 一对多查询
2.3.1 一对多查询的模型

一对多查询的需求:查询一个课程,与此同时查询出该该课程对应的学生信息

1590942772892

2.3.2 一对多查询的语句

对应的sql语句:

SELECT * FROM classes

SELECT * FROM student WHERE cid=#{cid}
2.3.3 创建StudentMapper接口
public interface StudentMapper {
    //根据cid查询student表
    @Select("SELECT * FROM student WHERE cid=#{cid}")
    public abstract List<Student> selectByCid(Integer cid);
}

2.3.4 使用注解配置Mapper
public interface ClassesMapper {
    //查询全部
    @Select("SELECT * FROM classes")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "name",property = "name"),
            @Result(
                    property = "students",  // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出的classes表的id字段来查询student表
                    /*
                        many、@Many 一对多查询的固定写法
                        select属性:指定调用哪个接口中的哪个查询方法
                     */
                    many = @Many(select = "com.zhushanglin.one_to_many.StudentMapper.selectByCid")
            )
    })
    public abstract List<Classes> selectAll();
}
2.3.5 测试类
public class Test01 {
    @Test
    public void selectAll() throws Exception{
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取ClassesMapper接口的实现类对象
        ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);

        //5.调用实现类对象中的方法,接收结果
        List<Classes> list = mapper.selectAll();

        //6.处理结果
        for (Classes cls : list) {
            System.out.println(cls.getId() + "," + cls.getName());
            List<Student> students = cls.getStudents();
            for (Student student : students) {
                System.out.println("\t" + student);
            }
        }

        //7.释放资源
        sqlSession.close();
        is.close();
    }

}

2.3.6 一对多配置总结
@Results:封装映射关系的父注解。
	Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
	column 属性:查询出的表中字段名称
	property 属性:实体对象中的属性名称
	javaType 属性:被包含对象的数据类型
	many 属性:一对多查询固定属性
@Many:一对多查询的注解。
	select 属性:指定调用某个接口中的方法
2.4 多对多查询
2.4.1 多对多查询的模型

多对多查询的需求:查询学生以及所对应的课程信息

1590943489827

2.4.2 多对多查询的语句

对应的sql语句:

SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id
SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}
2.4.3 添加CourseMapper 接口方法
public interface CourseMapper {
    //根据学生id查询所选课程
    @Select("SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}")
    public abstract List<Course> selectBySid(Integer id);
}

2.4.4 使用注解配置Mapper
public interface StudentMapper {
    //查询全部
    @Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "name",property = "name"),
            @Result(column = "age",property = "age"),
            @Result(
                    property = "courses",   // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出student表的id来作为关联条件,去查询中间表和课程表
                    /*
                        many、@Many 一对多查询的固定写法
                        select属性:指定调用哪个接口中的哪个查询方法
                     */
                    many = @Many(select = "com.zhushanglin.many_to_many.CourseMapper.selectBySid")
            )
    })
    public abstract List<Student> selectAll();
}

2.4.5 测试类
public class Test01 {
    @Test
    public void selectAll() throws Exception{
        //1.加载核心配置文件
        InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

        //2.获取SqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        //3.通过工厂对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取StudentMapper接口的实现类对象
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        //5.调用实现类对象中的方法,接收结果
        List<Student> list = mapper.selectAll();

        //6.处理结果
        for (Student student : list) {
            System.out.println(student.getId() + "," + student.getName() + "," + student.getAge());
            List<Course> courses = student.getCourses();
            for (Course cours : courses) {
                System.out.println("\t" + cours);
            }
        }

        //7.释放资源
        sqlSession.close();
        is.close();
    }

}
2.4.6 多对多配置总结
@Results:封装映射关系的父注解。
	Result[] value():定义了 Result 数组
@Result:封装映射关系的子注解。
	column 属性:查询出的表中字段名称
	property 属性:实体对象中的属性名称
	javaType 属性:被包含对象的数据类型
	many 属性:一对多查询固定属性
@Many:一对多查询的注解。
	select 属性:指定调用某个接口中的方法

三.构建sql

3.1 SQL 构建对象介绍
  • 我们之前通过注解开发时,相关 SQL 语句都是自己直接拼写的。一些关键字写起来比较麻烦、而且容易出错。
  • MyBatis 给我们提供了 org.apache.ibatis.jdbc.SQL 功能类,专门用于构建 SQL 语句
  • 1590943921472
3.2 查询功能的实现
  • 定义功能类并提供获取查询的 SQL 语句的方法。

  • @SelectProvider:生成查询用的 SQL 语句注解。

    type 属性:生成 SQL 语句功能类对象

    method 属性:指定调用方法

3.3 新增功能的实现
  • 定义功能类并提供获取新增的 SQL 语句的方法。

  • @InsertProvider:生成新增用的 SQL 语句注解。

    type 属性:生成 SQL 语句功能类对象

    method 属性:指定调用方法

3.4 修改功能的实现
  • 定义功能类并提供获取修改的 SQL 语句的方法。

  • @UpdateProvider:生成修改用的 SQL 语句注解。

type 属性:生成 SQL 语句功能类对象

method 属性:指定调用方法

3.5 删除功能的实现
  • 定义功能类并提供获取删除的 SQL 语句的方法。

  • @DeleteProvider:生成删除用的 SQL 语句注解。

    type 属性:生成 SQL 语句功能类对象

    method 属性:指定调用方法

四.综合案例

4.1 系统介绍

​ 我们之前在做学生管理系统时,使用的是原始JDBC操作数据库的,操作非常麻烦,现在我们使用MyBatis操作数据库,简化Dao的开发。

4.2 环境搭建(略)
4.3 代码改造
  • 步骤一:新增MyBatis配置文件 MyBatisConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!--configuration 核心根标签-->
<configuration>

    <!--引入数据库连接的配置文件-->
    <properties resource="config.properties"/>

    <!--配置LOG4J-->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>

    <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
    <environments default="mysql">
        <!--environment配置数据库环境  id属性唯一标识-->
        <environment id="mysql">
            <!-- transactionManager事务管理。  type属性,采用JDBC默认的事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- dataSource数据源信息   type属性 连接池-->
            <dataSource type="POOLED">
                <!-- property获取数据库连接的配置信息 -->
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>

    <!--配置映射关系-->
    <mappers>
        <package name="com.zhushanglin"/>
    </mappers>
</configuration>

  • 步骤二: 删除StudentDaoImpl,修改StudentDao
package com.zhushanglin.dao;

import com.zhushanglin.domain.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.ArrayList;

/*
    Dao层接口
 */
public interface StudentDao {
    //查询所有学生信息
    @Select("SELECT * FROM student")
    public abstract ArrayList<Student> findAll();

    //条件查询,根据id获取学生信息
    @Select("SELECT * FROM student WHERE sid=#{sid}")
    public abstract Student findById(Integer sid);
    
    //新增学生信息
    @Insert("INSERT INTO student VALUES (#{sid},#{name},#{age},#{birthday})")
    public abstract int insert(Student stu);
    
    //修改学生信息
    @Update("UPDATE student SET name=#{name},age=#{age},birthday=#{birthday} WHERE sid=#{sid}")
    public abstract int update(Student stu);
    
    //删除学生信息
    @Delete("DELETE FROM student WHERE sid=#{sid}")
    public abstract int delete(Integer sid);
    
  }
  • 步骤三:修改`StudentServiceImpl
 package com.zhushanglin.service.impl;
  
  import com.zhushanglin.dao.StudentDao;
  import com.zhushanglin.domain.Student;
  import com.zhushanglin.service.StudentService;
  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;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * 学生的业务层实现类
   * @author 清华程序员
   * @Company http://www.zhushanglin.com
   */
  public class StudentServiceImpl implements StudentService {
  
      @Override
      public List<Student> findAll() {
          ArrayList<Student> list = null;
          SqlSession sqlSession = null;
          InputStream is = null;
          try{
              //1.加载核心配置文件
              is = Resources.getResourceAsStream("MyBatisConfig.xml");
  
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  
              //3.通过工厂对象获取SqlSession对象
              sqlSession = sqlSessionFactory.openSession(true);
  
              //4.获取StudentDao接口的实现类对象
              StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  
              //5.调用实现类对象的方法,接收结果
              list = mapper.findAll();
  
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              //6.释放资源
              if(sqlSession != null) {
                  sqlSession.close();
              }
              if(is != null) {
                  try {
                      is.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
  
          //7.返回结果
          return list;
      }
  
      @Override
      public Student findById(Integer sid) {
          Student stu = null;
          SqlSession sqlSession = null;
          InputStream is = null;
          try{
              //1.加载核心配置文件
              is = Resources.getResourceAsStream("MyBatisConfig.xml");
  
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  
              //3.通过工厂对象获取SqlSession对象
              sqlSession = sqlSessionFactory.openSession(true);
  
              //4.获取StudentDao接口的实现类对象
              StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  
              //5.调用实现类对象的方法,接收结果
              stu = mapper.findById(sid);
  
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              //6.释放资源
              if(sqlSession != null) {
                  sqlSession.close();
              }
              if(is != null) {
                  try {
                      is.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
  
          //7.返回结果
          return stu;
      }
  
      @Override
      public void save(Student student) {
          SqlSession sqlSession = null;
          InputStream is = null;
          try{
              //1.加载核心配置文件
              is = Resources.getResourceAsStream("MyBatisConfig.xml");
  
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  
              //3.通过工厂对象获取SqlSession对象
              sqlSession = sqlSessionFactory.openSession(true);
  
              //4.获取StudentDao接口的实现类对象
              StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  
              //5.调用实现类对象的方法,接收结果
              mapper.insert(student);
  
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              //6.释放资源
              if(sqlSession != null) {
                  sqlSession.close();
              }
              if(is != null) {
                  try {
                      is.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
  
      @Override
      public void update(Student student) {
          SqlSession sqlSession = null;
          InputStream is = null;
          try{
              //1.加载核心配置文件
              is = Resources.getResourceAsStream("MyBatisConfig.xml");
  
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  
              //3.通过工厂对象获取SqlSession对象
              sqlSession = sqlSessionFactory.openSession(true);
  
              //4.获取StudentDao接口的实现类对象
              StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  
              //5.调用实现类对象的方法,接收结果
              mapper.update(student);
  
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              //6.释放资源
              if(sqlSession != null) {
                  sqlSession.close();
              }
              if(is != null) {
                  try {
                      is.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
  
      @Override
      public void delete(Integer sid) {
          SqlSession sqlSession = null;
          InputStream is = null;
          try{
              //1.加载核心配置文件
              is = Resources.getResourceAsStream("MyBatisConfig.xml");
  
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  
              //3.通过工厂对象获取SqlSession对象
              sqlSession = sqlSessionFactory.openSession(true);
  
              //4.获取StudentDao接口的实现类对象
              StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  
              //5.调用实现类对象的方法,接收结果
              mapper.delete(sid);
  
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              //6.释放资源
              if(sqlSession != null) {
                  sqlSession.close();
              }
              if(is != null) {
                  try {
                      is.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
  }

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

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

相关文章

【数据结构】从前序与中序遍历,或中序与后序遍历序列,构造二叉树

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; 首先&#xff0c;根据先序遍历可以确定根节点E&#xff0c;再在中序遍历中通过E确定左树和右数 &#xff1b; 设立inBegin和inEnd&#xff0c;通过这两个参数的游走&#xff0c;来进行子树的创建&a…

springboot配置集成RedisTemplate和Redisson,使用分布式锁案例

文章要点 自定义配置属性类集成配置RedisTemplate集成配置分布式锁Redisson使用分布式锁简单实现超卖方案 1. 项目结构 2. 集成RedisTemplate和Redisson 添加依赖 依赖的版本与继承的spring-boot-starter-parent工程相对应&#xff0c;可写可不写 <!--spring data redis…

SylixOS网卡多 IP 配置

概述 网卡多 IP 是指在同一个网络接口上配置和绑定多个 IP 地址。 引进网卡多 IP 的目的主要有以下几个&#xff1a; 提供服务高可用性。通过在同一接口绑定多个 IP 地址&#xff0c;然后在服务端使用这些 IP 地址启动多个服务实例。这样在任意一 IP 出现问题时&#xff0c;可…

Ollama教程——使用Ollama与LangChain实现Function Calling(函数调用)的详细教程(一)

@[toc](Ollama教程——使用Ollama与LangChain实现Function Calling(函数调用)的详细教程(一)) 在本教程中,我们将介绍如何使用Ollama和LangChain实现函数调用任务。这种方法可以大大提高AI模型在特定任务上的性能。本文将详细解释如何设置、使用OllamaFunctions,并通过多个…

openEuler Embedded 系统 实时性

openEuler Embedded 系统 & 实时性 1 介绍1.1 概述1.2 openEuler 23.09 Embedded1.3 openEuler 重要节点1.4 系统构建工具1.5 openEuler Embedded 诞生的需求背景运动控制系统实时性需求高嵌入式OS主要供应商来自老美&#xff0c;市场碎片化严重 1.6 总体架构1.7 openEuler…

AI预测体彩排3采取888=3策略+和值012路一缩定乾坤测试6月3日预测第10弹

昨天的第二套方案已命中&#xff01;今天继续基于8883的大底进行测试&#xff0c;今天继续测试&#xff0c;好了&#xff0c;直接上结果吧~ 首先&#xff0c;888定位如下&#xff1a; 百位&#xff1a;6,4,7,8,2,9,1,0 十位&#xff1a;2,3,4,1,6,7,8,…

000002 - Hadoop环境安装

Hadoop及其大数据生态圈 1. 背景2. 实践2.1 Linux服务器准备2.2 在其中一台服务器上安装JDK2.3 在其中一台服务器上安装HADOOP2.4 本地模式运行一个hadoop案例 3. 自动化部署 1. 背景 要搭建Hadoop集群环境&#xff0c;我们需要执行如下 准备三台Linux服务器&#xff0c;服务…

基于三元组一致性学习的单目内窥镜里程计估计

文章目录 TCL: Triplet Consistent Learning for Odometry Estimation of Monocular Endoscope摘要方法实验结果 TCL: Triplet Consistent Learning for Odometry Estimation of Monocular Endoscope 摘要 单目图像中深度和姿态的估计对于计算机辅助导航至关重要。由于很难获…

Rye一个强大的Python包管理工具

这是一个由Flask框架作者用rust开发并维护的一个python包管理工具&#xff0c;经过个人体验和使用还是非常不错的&#xff0c;尽管它还并非正式版本&#xff0c;但其易用性和便捷性均值得我们来体验&#xff01; 其中他对python各版本的管理比其他同类工具要好&#xff0c;安装…

Cognita:一款面向生产环境的开源、模块化 RAG 框架

一、引言&#xff1a;RAG 技术的兴起和挑战 1.1、从关键词搜索到 RAG 在大模型技术火起来之前&#xff0c;我们处理海量数据中的信息检索问题&#xff0c;往往依靠的是传统的关键词搜索和全文检索方法。这些方法虽然在一定程度上帮助我们找到了信息&#xff0c;但它们在语义理…

SpringBoot——全局异常处理

目录 异常 项目总结 新建一个SpringBoot项目 pom.xml Result&#xff08;通用的响应结果类&#xff09; MyBusinessException自定义异常类 GlobalExceptionHandler全局异常处理类 ExceptionController控制器 SpringbootExceptionApplication启动类 参考文章&#xff1a…

【计算机-ARM】

计算机-ARM ■ 指令集■ 1. RISC■ 2. CISC ■ ARM简介■ 1.■ 2. ■ ARM-CPU体系架构■ 1. M0■ 2. M3■ 3. M4■ 4. M7■ 5. M7■ 6. M7 ■ ARM-寄存器■ 1. 通用寄存器■ 2.■ 3.■ 4. ■ ARM-工作模式■ ARM-寄存器组■ ARM-异常向量表■ 由于soc0x00000000 是存放IROM芯片…

基于.NetCore和ABP.VNext的项目实战七:全局异常处理并日志记录

ABP框架已经默认为我们实现了全局的异常模块,这里我们自定义全局异常模块,先在HelloWorldController中写一个异常接口,测试下ABP的默认全局异常: [HttpGet][Route("Exception")]public string Exception(){throw new NotImplementedException("这是一个未实…

常用技巧-PPT时你真的做对了吗?

常用技巧-PPT时你真的做对了吗&#xff1f; PPT时通常会通过多种表现手法将信息转化为图表&#xff0c;更好的凸显自己的专业素养。将数据转化为图表是对的&#xff0c;那么你真的用对了图表了吗&#xff1f; 话不多说&#xff0c;直接上干货&#xff1a; 时间线图 时间线是…

Jmeter实战教程入门讲解

前言 通过前面对Jmeter元件的讲解&#xff0c;大家应该都知道常用元件的作用和使用了。编写Jmeter脚本前我们需要知道Jmeter元件的执行顺序&#xff0c;可以看看我这篇性能测试学习之路&#xff08;三&#xff09;—初识Jmeter来了解下。下面我将以工作中的一个简单的实例带大…

突破性技术: 大语言模型LLM量化激活outliers异常值抑制

LLM过去有两种突破性技术大大提升了量化精度&#xff0c;分别是group-wise量化和GPTQ/AWQ量化。前者相比于过去的per-tensor和per-channel/per-axis量化提出了更细粒度的对channel拆分为更小单元的量化方式&#xff0c;后者通过巧妙的算法明显提升了4bit量化的精度。 LLM量化存…

【面试八股总结】MySQL索引(二):B+树数据结构、索引使用场景、索引优化、索引失效

参考资料&#xff1a;小林coding、阿秀 一、为什么InnoDB采用B树作为索引数据结构&#xff1f; B 树是一个自平衡多路搜索树&#xff0c;每一个节点最多可以包括 M 个子节点&#xff0c;M 称为 B 树的阶&#xff0c;所以 B 树就是一个多叉树。 B 树与 B 树的差异&#xff1a;…

【UE5 刺客信条动态地面复刻】实现无界地面01:动态生成

为了快速上手UE5&#xff0c;开启了《复刻刺客信条动态地面》的技术篇章&#xff0c;最终希望复刻刺客信条等待界面的效果&#xff0c;这个效果大体上包括&#xff1a; 基础的地面随着任务走动消失和出现的基础效果地板的Bloom和竖起的面片辉光效果 既然是新手&#xff0c;&am…

CSS学习笔记之高级教程(五)

23、CSS 媒体查询 - 实例 /* 如果屏幕尺寸超过 600 像素&#xff0c;把 <div> 的字体大小设置为 80 像素 */ media screen and (min-width: 600px) {div.example {font-size: 80px;} }/* 如果屏幕大小为 600px 或更小&#xff0c;把 <div> 的字体大小设置为 30px …

器利而事善——datagrip 的安装以及简单使用

一&#xff0c;安装 下载&#xff1a;直接到官网下载即可&#xff0c; 破解&#xff1a;这是破解连接&#xff1a;https://pan.baidu.com/s/11BgOMp4Z9ddBrXwCVhwBng &#xff0c;提取码&#xff1a;abcd&#xff1b; 下载后&#xff0c;选择倒数第三个文件&#xff0c;打开da…