MyBatis框架

目录

一、MyBatis集成

1.项目搭建

1.1.idea中创建maven项目

1.2导入maven包

2.MyBatis集成 

 2.1MyBatis配置文件

2.2.创建MyBatisUtils

2.3 测试Mybatis是否可用

2.4.创建模型

2.5.productMapper接口

 2.6创建productMapper.xml文件

2.7注册mapper.xml

3.1获取单个对象 

二.MyBatis映射器(重要)

1什么是映射器

2创建Domain

3创建映射器接口

4创建SQL映射文件

5注册Mapper

6 实现CRUD操作

三. Sql编写高级特性-高级查询

1什么是高级查询

2 Query规范

3 高级查询实现

3.1.动态SQL - Concat

3.1.1.编写查询对象

3.1.2.编写Mapper查询方法

3.1.3.编写SQL

3.1.4.编写测试

3.2.动态SQL -If

3.2.1.SQL条件增加IF判断

3.3.动态SQL-WHERE

3.3.1.修改SQL增加查询条件

3.3.3.使用WHERE动态SQL

3.4.公共SQL片段的抽取

3.4.1.抽取WHERE条件

3.4.2.抽取查询的列

 

3.5.特殊符号 -“>” , "<"处理

3.5.1.修改查询对象

3.5.2.修改SQL增加条件

5.3.测试代码

3.6.取值表达式 #{}和${}

3.6.1.#{}和${}的相同点

3.6.2.不同点

3.6.3.做个小结


一、MyBatis集成

1.项目搭建

1.1.idea中创建maven项目

1.2导入maven包

以前导包是直接拷备jar包(1个核心包,7个依赖包,1个数据库连接包) ,maven导包都是在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>

    <groupId>cn.ronghuanet</groupId>
    <artifactId>mybatis-day02</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
    	<!-- mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.1</version>
        </dependency>
        <!-- mysql驱动包 -->
        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.26</version>
         </dependency>
         <!-- junit测试包 -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.12</version>
             <scope>test</scope>
         </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
  </dependencies>
    <!-- 局部jdk 1.8配置,pom.xml中 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.MyBatis集成 

 2.1MyBatis配置文件

log4j.properties

#全局日志配置
log4j.rootLogger = info,console

#输出局部的日志信息(自己的包中的日志打印方式)
log4j.logger.自己要扫描包的路径=TRACE


### 配置输出到控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
### 使用System.out打印日志
log4j.appender.console.Target = System.out
### 指定日志的格式布局(日志是有格式的)
log4j.appender.console.layout = org.apache.log4j.PatternLayout
### 日志的打印格式
log4j.appender.console.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n

先准备jdbc.properties

jdbc.username=root
jdbc.password=admin
jdbc.url=jdbc:mysql:///mybatis
jdbc.driverClassName=com.mysql.jdbc.Driver

创建:mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <!-- 加载jdbc.properties-->
    <properties resource="jdbc.properties"/>
    <!--申明操作数据库的环境-->
    <environments default="MYSQL">
        <environment id="MYSQL">
            <!--使用jdbc的事务-->
            <transactionManager type="JDBC"/>
            <!--支持连接池-->
            <dataSource type="POOLED">
                <!--自动补全结构:ctrl+shift+回车-->
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="driver" value="${jdbc.driverClassName}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
       <!-- 加载mapper.xml文件-->
    </mappers>
</configuration>

2.2.创建MyBatisUtils

public class MybatisUtils {
    private static SqlSessionFactory sessionFactory ;
    static{
        try {
            //提示处理异常快捷键    alt+回车       移动代码的快捷键  alt+上键或者下键
            //快速使用变量接收,    alt+回车
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //根据io流创建SqlSessionFactory对象
            sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession openSession(){
        if (sessionFactory != null) {
            return sessionFactory.openSession();
        }
        return null;
    }
    public static void closeSession(SqlSession sqlSession){
        if (sessionFactory != null) {
            sqlSession.close();
        }
    }
}

2.3 测试Mybatis是否可用

package com.ronghuanet;

import com.ronghuanet.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

/**
 * 测试mybatis集成进来没有
 */
public class MybatisTest {

    @Test
    public void test() throws Exception{
        SqlSession sqlSession = MybatisUtils.openSession();
        System.out.println(sqlSession);
        MybatisUtils.closeSession(sqlSession);

    }
}

 

2.4.创建模型

public class Product {
    private Long id;
    private String name;
    private BigDecimal price;
    /**
     * alt+insert:快速生成setter  getter方法  toString方法   构造方法
     */
	//getter,setter代码略...
}

 

2.5.productMapper接口

public interface ProductMapper {
    Product findOne(Long id);
}

 2.6创建productMapper.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">
<!--注:namespace的内容就是ProductMapper接口的全限定名-->
<mapper namespace="cn.ronghuanet.mybatis._01_batch.mapper.ProductMapper">
    <!--id的值保证ProductMapper接口的方法名一值-->
    <select id="findOne" parameterType="long" resultType="cn.ronghuanet.mybatis._01_batch.domain.Product">
        select * from product where id = #{id}
    </select>
</mapper>

2.7注册mapper.xml

 主配置文件(mybatis-config.xml)中引入

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
     ...
    <mappers>
       <!-- 加载mapper.xml文件-->
        <mapper resource="cn/ronghuanet/mybatis/_01_batch/mapper/ProductMapper.xml" />
    </mappers>
</configuration>

【注意】大家特别注意文件的位置  

 

【注意】创建resources中文件夹的方式(小心再小心)

 

3.1获取单个对象 

public class MyBatisTest {
    /**
     * 定义一个映射器mapper接口,使用mybatis自动为我们创建代理类
     * @throws Exception
     */
    @Test
    public void findOne()throws Exception{
        //获取到会话对象
        SqlSession session = MybatisUtils.openSession();
        //拿到映射对象,可以做相应的操作
        ProductMapper mapper = session.getMapper(ProductMapper.class);
        Product product = mapper.findOne(1L);

        System.out.println(product);
    }
}

二.MyBatis映射器(重要)

1什么是映射器

我感觉到了有点不爽,根据我们上面代码我们已经可以完成单表的CRUD了,但是我们发现我们的dao实现类中出现了大量重复的代码,并且每个方法中的代码都相对比较复杂。手动去拼Sql的Statement很容易出错。

MyBatis的映射器就是用来解决这一问题,映射器其实是一个Interface接口,我们通过编写简单的映射器接口,就可以将我们之前在Dao中做的重复的,看起来比较低级的代码给替换掉。也就是说我们以后不用向之前那样写代码,而是直接调用映射器接口即可完成SQL的调用。我们可以理解为 这个映射器 底层使用了动态代理的方式将复杂的代码进行了处理,屏蔽了细节。--- 如同JPA的接口

2创建Domain

新开一个包 _02_mapper,创建domain/Employee 实体类

public class Employee{
    private Long id;
    private String username;
    private Integer age = 0;
    private Boolean sex;
    //...
}

3创建映射器接口

 创建实体类接口,我们一般给接口命名: XxxMapper ,如 EmployeeMapper ,跟EmployeeMapper.xml同名

import java.util.List;

public interface EmployeeMapper {
    int insert(Employee employee);
    int updateById(Employee employee);
    int deleteById(Long id);
    Employee selectById(Long id);
    List<Employee> selectAll();
}

4创建SQL映射文件

需要注意:SQL映射文件的namespace必须和 映射器接口的全限定名一直,这个非常重要,因为我们在调用映射器接口的时候,底层是通过该接口的 ==全限定名+方法名== 去匹配 SQL映射文件的==namespace+id==。

<?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="cn.ronghuanet.mybatis._02_mapper.mapper.EmployeeMapper">

    <resultMap id="baseResultMap" type="cn.ronghuanet.mybatis._02_mapper.domain.Employee">
        <id column="id" property="id" />
        <result column="username" property="username"/>
        <result column="age" property="age"/>
        <result column="sex" property="sex"/>
    </resultMap>

    <select id="selectAll" resultMap="baseResultMap" >
        select
            id,
            username,
            age,
            sex
        from employee
    </select>
</mapper>

注意:这里是另外一个Mapper,对应的是Employee,所以所有的 有用到实体类的地方都要使用Employee的全限定名。

再次强调:底层是通过映射器接口的 ==全限定名+方法名== 去匹配 SQL映射文件的==namespace+Id==,所以:

  • namespace 需要和 映射器接口的全限定名一致

  • sql的id必须和 映射器的 方法名一致。

这里暂时写了一个查询所有的方法,同学们自行完成其他的几个方法

5注册Mapper

修改mybatis-config.xml文件,添加<mappers> , 注意修改成自己的路径

<mappers>
    <mapper resource="cn//xxxxxxxx/mapper/ProductMapper.xml"/>
    <mapper resource="cn/xxxxxxxxxt/mybatis/mapper/EmployeeMapper.xml"/>
</mappers>

6 实现CRUD操作

//编写测试类,使用Mapper接口映射器进行CRUD

//``java
@Test
public void selectAll() {
    try(SqlSession sqlSession = MyBatisUtil.openSession()){
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        employeeMapper.selectAll().forEach(e ->{
            System.out.println(e);
        });
    }

}
//```

 

三. Sql编写高级特性-高级查询

1什么是高级查询

  1. 高级查询即为多条件查询,为了快速查找想要的信息,过滤掉不需要的信息,这种查询在web项目中是必不可少的。例如一些后台管理系统、招聘网站等;

 根据查询条件查询出相应的内容,可以是多个查询条件任意组合,查询出的结果都是满足查询条件的;

高级查询可以使用Mybatis的动态Sql实现,减少了原始的很多逻辑判断代码,提高开发效率;

2 Query规范

  1. 一般高级查询会将前端传递的参数封装成一个XxxQuery对象,方便维护和扩展;

  2. 一个实体类对应一个Query对象;

    例如:针对上面的页面中的两个查询条件,我们可以写一个XxxQuery类【Xxx是实体类名或模块名或表名】,Controller直接使用这个类型去接收前端传递过来的数据,然后将该对象传递到Mapper中使用动态sql查询;

  3. public class ArticleQuery{
        //文章标题
        private String title;
        //默认启用状态
        private Boolean enable;
         //此处省略getter和setter方法
    }

3 高级查询实现

3.1.动态SQL - Concat

我们先使用一个高级查询案例来演示

3.1.1.编写查询对象

public class EmployeeQuery {
    private Integer sex;
    private String username;
    //...
}

 

3.1.2.编写Mapper查询方法

public interface EmployeeMapper {
    List<Employee> selectForList(EmployeeQuery employeeQuery);
    //...
}

 

3.1.3.编写SQL

方式一 :"%"#{username}"%" 不推荐

<select id="selectForList" resultMap="baseResultMap" >
        SELECT
            id,
            username,
            age,
            sex
        FROM employee WHERE username like "%"#{username}"%"
    </select>

方式二 CONCAT("%",#{username},"%") :标准

 <select id="selectForList" resultMap="baseResultMap" >
        SELECT
            id,
            username,
            age,
            sex
        FROM employee WHERE username like CONCAT("%",#{username},"%")
    </select> 

CONCAT: mysql提供的用来拼接字符串的函数  

3.1.4.编写测试
  @Test
    public void selectForList() {
        try(SqlSession sqlSession = MyBatisUtil.openSession()){
            //查询条件
            EmployeeQuery employeeQuery = new EmployeeQuery() ;
            employeeQuery.setUsername("zs");

            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            employeeMapper.selectForList(employeeQuery).forEach(e ->{
                System.out.println(e);
            });
        }
    }

3.2.动态SQL -If

 在上面的查询中,我们有这样的查询条件 , 其实这样的写法是不合理的,如果 username的值为 “null” 或者“”空字符串呢?是不是这个SQL就查询不出内容了,所以我们在添加查询条件的时候一般==需要判断条件的值不为空的时候在加条件==

3.2.1.SQL条件增加IF判断

<select id="selectForList" resultMap="baseResultMap" >
    SELECT
    id,
    username,
    age,
    sex
    FROM employee
    <if test="username != null">
        WHERE username like concat("%",#{username},"%")
    </if>
</select>

3.3.动态SQL-WHERE

我们上面演示了一个条件的情况,可以通过IF来判断条件的空值然后在加入WHERE。那如果有两个以上的条件呢?

3.3.1.修改SQL增加查询条件

在原本的SQL基础上增加一个age

 <select id="selectForList" resultMap="baseResultMap" >
    SELECT
    id,
    username,
    age,
    sex
    FROM employee
    <if test="username != null and username != ''">
        WHERE username LIKE concat("%",#{username},"%")
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

测试代码

@Test
public void selectForList() {
    try(SqlSession sqlSession = MyBatisUtil.openSession()){
        //查询条件
        EmployeeQuery employeeQuery = new EmployeeQuery() ;
        employeeQuery.setUsername("zs");
        //增加age查询条件
        employeeQuery.setAge(11);
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        employeeMapper.selectForList(employeeQuery).forEach(e ->{
            System.out.println(e);
        });
    }
}
3.3.3.使用WHERE动态SQL

<select id="selectForList" resultMap="baseResultMap" >
        SELECT
            id,
            username,
            age,
            sex
        FROM employee
        <where>
            <if test="username != null and username != ''">
                AND username LIKE concat("%",#{username},"%")
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>

 

在条件外面套一个 <where> 元素 ,里面写IF判断,增加条件 ,所有的条件前面全部用 AND ,Mybatis会自动把第一个条件前面变成where。

注意喔:不要自以为是的把第一个条件前面的AND 变成WHERE 。都用AND就对了。

 

3.4.公共SQL片段的抽取

当我们的SQL中的内容写得比较多的时候,看起来就比较臃肿,加载上有些SQL片段是公共的,比如 selectForList和 selectForCount 拥有相同的 where条件。对于这些内容我们可以进行统一抽取,让SQL的结构看起来更清爽。  

3.4.1.抽取WHERE条件

 

 <sql id="base_where">
        <where>
            <if test="username != null and username != ''">
                AND username LIKE concat("%",#{username},"%")
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </sql>

    <select id="selectForList" resultMap="baseResultMap" >
        SELECT
            id,
            username,
            age,
            sex
        FROM employee
        <include refid="base_where"/>
    </select>

使用 <sql id=""/> 标签来抽取公共的SQL片段,然后使用 <include refid="sql片段ID"/> 来引入抽取的SQL片段 ,代码结构是不是编的清爽了呢?  

3.4.2.抽取查询的列
 

<sql id="base_where">
        <where>
            <if test="username != null and username != ''">
                AND username LIKE concat("%",#{username},"%")
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </sql>
    
    <sql id="base_columns">
           id,username,age,sex
    </sql>

    <select id="selectForList" resultMap="baseResultMap" >
        SELECT 
        <include refid="base_columns"/>
        FROM employee
        <include refid="base_where"/>
    </select>

3.5.特殊符号 -“>” , "<"处理

3.5.1.修改查询对象

public class EmployeeQuery {

    private Integer minAge;
    private Integer maxAage;
    //...

 

3.5.2.修改SQL增加条件

 <sql id="base_where">
        <where>
            <if test="minAge != null">
                and age >= #{minAage}
            </if>
            <if test="maxAge != null">
                and age <= #{maxAge}
            </if>
            <if test="username != null and username != ''">
                AND username LIKE concat("%",#{username},"%")
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </sql> 

 

因为在XML里面, "<" 符号是一个特殊符号

这个SQL一写出来IDEA编译器就会检查出错,直接测试的话会出现如下错误  

使用 CDATA 原样输出, <![CDATA[ 内容 ]]> 这个是固定格式

<if test="maxAge != null">
        <![CDATA[
            and age   <=  #{maxAge}
        ]]>
    </if>

 

5.3.测试代码
@Test
    public void selectForList() {
        try(SqlSession sqlSession = MyBatisUtil.openSession()){
            //查询条件
            EmployeeQuery employeeQuery = new EmployeeQuery() ;
            //employeeQuery.setUsername("zs");
            //增加age查询条件
            //employeeQuery.setAge(11);
            employeeQuery.setMinAge(10);
            employeeQuery.setMaxAge(20);
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            employeeMapper.selectForList(employeeQuery).forEach(e ->{
                System.out.println(e);
            });
        }
    }

 

3.6.取值表达式 #{}和${}

我们之前的SQL中取方法传入的参数值使用的都是#{} , 其实${}也可以用来取值,但是他们有有着很大的区别,和不同的使用场景。

3.6.1.#{}和${}的相同点

都可以用来取值

3.6.2.不同点

其实==#{}的底层就是使用的 “?”占位符==的方式来拼接SQL,而==${}使用的是直接把拼接到SQL中==。 如有两条SQL如下:

 <select id="selectById" parameterType="long" resultType="...Employee">
        select * from employee where id = #{id}
    </select>
-----------------------------------------------------------------------------------------------------
    <select id="selectById" parameterType="long" resultType="...Employee">
        select * from employee where id = ${id}
    </select>

上面是接受==普通数据类型的参数==, 他们表现出如下区别:  

 

使用#{}正常取值,使用${}抛出异常,根据异常我们可以看到,其实他去参数值找了一个名字叫 “getId”的属性。说白了就是这个==它默认是取对象的属性值。而不能用来取一个普通值。==

增加一个方法,我们把SQL的参数类型修改为对象类型Employee,(mapper接口也要改哦)如有下面SQL:

 

3.6.3.做个小结

# 的特点

  • # 它可以用来取任意值 ,普通值和对象都可以

  • # 使用的占位符 ?拼接SQL,有效防止SQL注入 - 预编译

  • # 使用预编译性能较高

  • # 在接受字符串的时候会给字符串的两边加上“”引号 ,如username=zs ,使用 where username = #{username} 最终效果 where username = "zs" ,而使用 where username = ${username} 最终效果 where username = zs ,值的两边没有引号,会导致SQL异常,出现找不到 column的情况。

$ 的特点

  • $ 它只能取对象中的属性值。

  • $ 没有使用?占位符,直接拼接参数到SQL有SQL注入的风险 - 没有预编译

  • $ 没有使用预编译,性能比 #低一点

  • $ 在接受字符串的时候,不会给字符串的两边加上“”引号,所以一般用来接受字段名或者表名的时候用如:

select id,${fieldName}  from ${tableName} order by ${orderColumns}

如何选择? 尽量用 #{} 来取值 ,${}一般用来动态排序。

例如: 表明 , 字段名,或者 排序条件 需要动态传入的时候,可以使用${}。

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

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

相关文章

vue3项目报Parsing error: Cannot find module ‘typescript‘

vue3项目报Parsing error: Cannot find module ‘typescript’ 解决办法&#xff0c;安装typescript&#xff0c;然后一定记得 退出vscode&#xff0c;再重新打开项目即可。 npm install typescript --save-dev

【产品经理方法论——BRD文档模板】

一、BRD(Business Requirement Document)商业需求文档 BRD文档是面对公司高层&#xff0c;目的是获得公司资金、资源的支持开展项目。一般的BRD文档展示方式是PPT。 下面的思维导图是BRD文档的六大模块。 方案背景方案预测产品规划盈利模式收益与成本风险与对策 1. 方案背景 …

2024038期传足14场胜负前瞻

2024038期售止时间为3月10日&#xff08;周日&#xff09;20点30分&#xff0c;敬请留意&#xff1a; 本期深盘多&#xff0c;1.5以下赔率3场&#xff0c;1.5-2.0赔率2场&#xff0c;其他场次是平半盘、平盘。本期14场整体难度中等偏上。以下为基础盘前瞻&#xff0c;大家可根据…

FreeRTOS学习笔记-基于stm32(3)中断管理

一、什么是中断 通俗点讲就是让CPU停止当前在做的事&#xff0c;转而去做更紧急的事。 二、中断优先级分组 这个紧急的事也有一个等级之分&#xff0c;优先级越高越先执行。stm32使用中断优先配置寄存器的高4位&#xff0c;共16级的中断优先等级。 stm32的中断优先等级可以分为…

链表|142.环形链表

ListNode *detectCycle(ListNode *head) {ListNode *fast head, *slow head;while (fast && fast->next) {// 这里判断两个指针是否相等&#xff0c;所以移位操作放在前面slow slow->next;fast fast->next->next;if (slow fast) { // 相交&#xff0c…

【Godot4自学手册】第二十二节完成主人公的闪现功能

这一节我们主要自学主人公的闪现功能&#xff0c;当按下鼠标右键&#xff0c;我们的主人公根据不同的方向进行瞬间移动&#xff0c;并在身后留下一串残影&#xff0c;具体效果如下&#xff1a; 一、新建ghost场景 新建Node2D场景&#xff0c;命名为Ghost&#xff0c;存储到S…

《vtk9 book》 官方web版 第3章 - 计算机图形基础 (3 / 6)

3.8 演员几何 我们已经看到了光照属性如何控制演员的外观&#xff0c;以及相机如何结合变换矩阵将演员投影到图像平面上。剩下的是定义演员的几何形状&#xff0c;以及如何将其定位在世界坐标系中。 建模 计算机图形学研究中的一个重要主题是建模或表示物体的几何形状。…

第五十四回 高太尉大兴三路兵 呼延灼摆布连环马-AI通过构建并训练CNN网络来进行飞机识别

呼延灼举荐了百胜将韩滔和天目将彭玘做先锋。 两军对战&#xff0c;韩滔和秦明斗二十回合&#xff0c;呼延灼与林冲斗在一起&#xff0c;花荣与彭玘斗在一处&#xff0c;后彭玘与一丈青扈三娘斗在一起&#xff0c;被扈三娘抓住。 尽管梁山占优&#xff0c;宋江也没有乘胜追击&…

❤ Vue3项目搭建系统篇(二)

❤ Vue3项目搭建系统篇&#xff08;二&#xff09; 1、安装和配置 Element Plus&#xff08;完整导入&#xff09; yarn add element-plus --savemain.ts中引入&#xff1a; // 引入组件 import ElementPlus from element-plus import element-plus/dist/index.css const ap…

B端系统升级,登录页必在升级之列,不容置疑。

进行B端界面升级时&#xff0c;首先升级登录页有以下几个原因&#xff1a; 用户体验&#xff1a;登录页是用户进入系统的第一个页面&#xff0c;用户首先接触到的界面。通过升级登录页&#xff0c;可以提升用户的第一印象&#xff0c;增强用户对系统的信任感和好感度&#xff…

基于Unity3D引擎RPG游戏设计与开发

目 录 摘 要 I Abstract II 引 言 1 1.相关技术 3 1.1 Unity基础界面 3 1.2 C#脚本编写 3 1.3 Unity脚本 3 1.4 Unity物理引擎 3 1.5 UGUI 3 1.6 Unity动画系统 4 1.7 本章小结 4 2. 系统分析 5 2.1游戏内容需求分析 5 2.2游戏流程需求分析 5 2.3游戏场景需求分析 5 2.4怪物系…

GPT-4-turbo还是大家心中第一!Claude 3竞技场人类投票成绩出炉:仅居第三

Claude 3的竞技场排名终于揭晓了&#xff1a; 在仅仅3天的时间里&#xff0c;20000张投票使得排名的流量达到了前所未有的高度。 最后&#xff0c;Claude 3的"大杯"模型Opus以1233的分数赢得了胜利&#xff0c;成为了第一个能和GPT-4-Turbo匹敌的选手。 "中杯…

基于范围的for循环(C++11)和auto

auto C11中&#xff0c;标准委员会赋予了auto全新的含义即&#xff1a; auto不再是一个存储类型指示符&#xff0c;而是作为一个新的类型 指示符来指示编译器&#xff0c;auto声明的变量必须由编译器在编译时期推导而得。 int a 10;auto b a;auto c a;auto d TestAuto(…

Vue:自动按需导入element-plus图标

自动导入使用 unplugin-icons 和 unplugin-auto-import 从 iconify 中自动导入任何图标集。 完整vite.config.js参考模板 https://download.csdn.net/download/ruancexiaoming/88928539 导入element-plus图标 命令行安装unplugin-icons pnpm i -D unplugin-icons//没有安装自…

银河麒麟V10 安装部署大数据管理软件 DataSophon

一、概览 1、愿景 致力于快速实现部署、管理、监控以及自动化运维大数据云原生平台&#xff0c;帮助您快速构建起稳定、高效、可弹性伸缩的大数据云原生平台。 2、DataSophon是什么 《三体》&#xff0c;这部获世界科幻文学最高奖项雨果奖的作品以惊艳的"硬科幻"…

Joe主题网站

一款博客网站源码 发现源码为大家内置了主题 清爽又强大真正的永久可用的一条源码&#xff0c;该版本为整合版本&#xff0c;内置了Joe主题&#xff0c;搭建后直接启用即可~ 安装环境要求&#xff1a; PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff0c;…

一个爬虫自动化数据采集的故事~

目录 一、原文二、故事前半段背景内容三、正经的讲点DrissionPage知识四、故事的收尾 一、原文 原文来自一个爬虫自动化数据采集的故事~ , 建议点击链接看文章末尾的视频笔者不擅长自动化&#xff0c;一个小小故事分享给大家&#xff0c;仅个人观点 二、故事前半段背景内容 …

C#中对象的相等性与同一性的判断方法总结

C#对象的相等性与同一性 1. 概述与准备1.1 概述1.2 准备 2. Equals(Object)2.1 功能&#xff1a;2.2 实例&#xff1a;2.3 扩展&#xff1a;2.4 重写此方法 3. Equals(Object, Object)3.1 功能3.2 实例 4. ReferenceEquals(Object, Object)4.1 功能4.2 使用场景&#xff1a;4.3…

突破编程_前端_JS编程实例(自适应表格列宽)

1 开发目标 针对如下的表格组件&#xff1a; 根据表格的各个列字符串宽度动态调整表格列宽&#xff1a; 2 详细需求 本组件目标是提供一个自动调整 HTML 表格列宽的解决方案&#xff0c;通过 JS 实现动态计算并调整表格每列的宽度&#xff0c;以使得表格能够自适应容器宽度&a…

Matlab|配电网智能软开关(sop)规划模型

目录 1 主要内容 目标函数 2 部分程序 3 程序结果 3.1 sop选址定容优化模型 3.2 对比算例&#xff08;不含sop&#xff09; 4 下载链接 1 主要内容 该程序参考文献《基于改进灵敏度分析的有源配电网智能软开关优化配置》&#xff0c;采用二阶锥算法&#xff0c;以改进的…