Spring事务管理与模板对象

1.事务管理

1.事务回顾

事务指数据库中多个操作合并在一起形成的操作序列

事务的作用

当数据库操作序列中个别操作失败时,提供一种方式使数据库状态恢复到正常状态(A),保障数据库即使在异常状态下仍能保持数据一致性(C)(要么操作前状态,要么操作后状态)。

当出现并发访问数据库时,在多个访问间进行相互隔离,防止并发访问操作结果互相干扰(I

事务的特征(ACID)

原子性(Atomicity)指事务是一个不可分割的整体,其中的操作要么全执行或全不执行

一致性(Consistency)事务前后数据的完整性必须保持一致

隔离性(Isolation)事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离

持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

事务的隔离级

脏读:允许读取未提交的信息

原因:Read uncommitted

解决方案: (表级读锁)

不可重复读:读取过程中单个数据发生了变化

解决方案: Repeatable read (行级写锁)

幻读:读取过程中数据条目发生了变化

解决方案: Serializable(表级写锁)

2.Spring事务核心对象

J2EE开发使用分层设计的思想进行,对于简单的业务层转调数据层的单一操作,事务开启在业务层或者数据层并无太大差别,当业务中包含多个数据层的调用时,需要在业务层开启事务,对数据层中多个操作进行组合并归属于同一个事务进行处理

Spring为业务层提供了整套的事务解决方案

        PlatformTransactionManager

        TransactionDefinition

        TransactionStatus

PlatformTransactionManager(平台事务管理器)

这是一个接口

平台事务管理器实现类:

DataSourceTransactionManager   适用于Spring JDBC或MyBatis

HibernateTransactionManager   适用于Hibernate3.0及以上版本

JpaTransactionManager   适用于JPA

JdoTransactionManager   适用于JDO

JtaTransactionManager   适用于JTA

JPA(Java Persistence API)Java EE 标准之一,为POJO提供持久化标准规范,并规范了持久化开发的统一API,符合JPA规范的开发可以在不同的JPA框架下运行

JDO(Java Data Object )是Java对象持久化规范,用于存取某种数据库中的对象,并提供标准化API。与JDBC相比,JDBC仅针对关系数据库进行操作,JDO可以扩展到关系数据库、文件、XML、对象数据库(ODBMS)等,可移植性更强

JTA(Java Transaction API)Java EE 标准之一,允许应用程序执行分布式事务处理。与JDBC相比,JDBC事务则被限定在一个单一的数据库连接,而一个JTA事务可以有多个参与者,比如JDBC连接、JDO 都可以参与到一个JTA事务中

此接口定义了事务的基本操作

获取事务

TransactionStatus getTransaction(TransactionDefinition definition)

提交事务 

void commit(TransactionStatus status) 

回滚事务 

void rollback(TransactionStatus status)

TransactionDefinition(事务定义的接口)

此接口定义了事务的基本信息

获取事务定义名称

String getName()

获取事务的读写属性

boolean isReadOnly()

获取事务隔离级别

int getIsolationLevel()

获事务超时时间

int getTimeout()

获取事务传播行为特征

int getPropagationBehavior()

TransactionStatus(事务状态的接口)

此接口定义了事务在执行过程中某个时间点上的状态信息及对应的状态操作

获取事务是否处于新开启事务状态

boolean isNewTransaction()

获取事务是否处于已完成状态

boolean isCompleted()

获取事务是否处于回滚状态

boolean isRolbackOnly()

刷新事务状态

void flush()

获取事务是否具有回滚存储点

boolean hasSavepoint()

设置事务处于回滚状态

void setRollbackOnly()

3.事务控制方式

编程式

声明式(XML)

声明式(注解)

4.案例环境

银行转账业务说明

银行转账操作中,涉及从A账户到B账户的资金转移操作。数据层仅提供单条数据的基础操作,未设计多账户间的业务操作

package com.dao;import org.apache.ibatis.annotations.Param;public interface AccountDao {/** 入账操作* name  入账用户名* money  入账金额*/void inMoney(@Param("name") String name, @Param("money") Double money);/** 入账操作* name  出账用户名* money  出账金额*/void outMoney(@Param("name") String name, @Param("money") Double money);}
package com.domain;public class Account {private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
package com.service;public interface AccountService {/** 转账操作* outName  出账用户名* inName  入账用户名* money   转账金额*/public void transfer(String outName, String inName, Double money);
}
package com.service.impl;import com.dao.AccountDao;
import com.service.AccountService;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void transfer(String outName, String inName, Double money) {accountDao.inMoney(outName,money);accountDao.outMoney(inName,money);}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:*.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><bean id="accountService" class="com.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="typeAliasesPackage" value="com.domain"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.dao"/></bean>
</beans>
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.AccountDao"><update id="inMoney">update account set money = money + #{money} where name = #{name}</update><update id="outMoney">update account set money = money - #{money} where name = #{name}</update>
</mapper>
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=123456

5.使用AOP控制事务 (XML)

将业务层的事务处理功能抽取出来制作成AOP通知,利用环绕通知运行期动态织入

范例

public Object tx(ProceedingJoinPoint pjp) throws Throwable {DataSourceTransactionManager dstm = new DataSourceTransactionManager();dstm.setDataSource(dataSource);TransactionDefinition td = new DefaultTransactionDefinition();TransactionStatus ts = dstm.getTransaction(td);Object ret = pjp.proceed(pjp.getArgs());dstm.commit(ts);return ret;
}
<bean id="txAdvice" class="com.aop.TxAdvice"><property name="dataSource" ref="dataSource"/>
</bean>

使用aop:advisor在AOP配置中引用事务专属通知类

<aop:config><aop:pointcut id="pt" expression="execution(* *..transfer(..))"/><aop:aspect ref="txAdvice"><aop:around method="tx" pointcut-ref="pt"/></aop:aspect>
</aop:config>

样例

package com.service.impl;import com.dao.AccountDao;
import com.service.AccountService;
import javafx.application.Platform;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;import javax.sql.DataSource;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}/*private DataSource dataSource;public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}*/@Overridepublic void transfer(String outName, String inName, Double money) {/* //开启事务PlatformTransactionManager ptm = new DataSourceTransactionManager(dataSource);//事务定义TransactionDefinition td = new DefaultTransactionDefinition();//事务状态TransactionStatus ts = ptm.getTransaction(td);*/accountDao.inMoney(outName,money);//int i = 1/0;accountDao.outMoney(inName,money);/*ptm.commit(ts);*/}
}

package com.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;import javax.sql.DataSource;public class TxAdvice {private DataSource dataSource;public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}public Object transactionManager(ProceedingJoinPoint pjp) throws  Throwable{//开启事务PlatformTransactionManager ptm = new DataSourceTransactionManager(dataSource);//事务定义TransactionDefinition td = new DefaultTransactionDefinition();//事务状态TransactionStatus ts = ptm.getTransaction(td);Object ret = pjp.proceed(pjp.getArgs());ptm.commit(ts);return ret;}
}
 <bean id="txAdvice" class="com.aop.TxAdvice"><property name="dataSource" ref="dataSource"/></bean><aop:config><aop:pointcut id="pt" expression="execution(* *..taransfer(..))"/><aop:aspect ref="txAdvice"><aop:around method="transactionManager" pointcut-ref="pt"/></aop:aspect></aop:config>

6.声明式事务(XML)

tx配置----tx:advice

名称:tx:advice

类型:标签

归属:beans标签

作用:专用于声明事务通知

格式

<beans><tx:advice id="txAdvice" transaction-manager="txManager"></tx:advice>
</beans>

基本属性:

id :用于配置aop时指定通知器的id

transaction-manager :指定事务管理器bean

tx配置----tx:attributes

名称:tx:attributes

类型:标签

归属:tx:advice标签

作用:定义通知属性

格式

<tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes></tx:attributes>
</tx:advice>

基本属性:无

tx配置----tx:method

名称:tx:method

类型:标签

归属:tx:attribute标签

作用:设置具体的事务属性

格式

<tx:attributes><tx:method name="*" read-only="false" /><tx:method name="get*" read-only="true" />
</tx:attributes>

说明:通常事务属性会配置多个,包含一个读写的全事务属性,一个只读的查询类事务属性 

样例

开启tx命名空间 

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttps://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!--定义事务管理的通知类--><tx:advice id="txAdvice" transaction-manager="txManager"><!--定义控制的事务--><tx:attributes><tx:method name="*" read-only="false"/><tx:method name="get*" read-only="true"/><tx:method name="find" read-only="true"/><tx:method name="transfer" read-only="false"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="pt" expression="execution(* com.service.*Service.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/></aop:config>

 此时aop.TxAdvice就可以删除了

<!--<bean id="txAdvice" class="com.aop.TxAdvice"><property name="dataSource" ref="dataSource"/></bean><aop:config><aop:pointcut id="pt" expression="execution(* *..transfer(..))"/><aop:aspect ref="txAdvice"><aop:around method="transactionManager" pointcut-ref="pt"/></aop:aspect></aop:config>-->

此段也要删除

aop:advice与aop:advisor区别

aop:advice配置的通知类可以是普通java对象,不实现接口,也不使用继承关系

aop:advisor配置的通知类必须实现通知接口

        MethodBeforeAdvice

        AfterReturningAdvice

        ThrowsAdvice

        ……

7.tx:method属性

<tx:methodname="*"			待添加事务的方法名表达式(支持*号通配符)read-only="false"	设置事务的读写属性,true为只读,false为读写timeout="-1"		设置事务超时时长,单位秒isolation="DEFAULT"	设置事务隔离级别,该隔离级别设定是基于Spring的设定,非数据库端no-rollback-for="java.lang.ArithmeticException"	设置事务中不回滚的异常,多个异常间使用,分割rollback-for=""			设置事务中必回滚的异常,多个异常间使用,分割propagation="REQUIRED"	设置事务的传播行为/>

8.事务传播行为 

事务传播行为描述的是事务协调员对事务管理员所携带事务的处理态度

企业开发过程中,发现同属于同一个事务控制的各个业务中,如果某个业务与其他业务隔离度较高,拥有差异化的数据业务控制情况,通常使用事务传播行为对其进行控制

9.声明式事务(注解)

@Transactional

名称:@Transactional

类型:方法注解,类注解,接口注解

位置:方法定义上方,类定义上方,接口定义上方

作用:设置当前类/接口中所有方法或具体方法开启事务,并指定相关事务属性

范例

@Transactional(readOnly = false,timeout = -1,isolation = Isolation.DEFAULT,rollbackFor = {ArithmeticException.class, IOException.class},noRollbackFor = {},propagation = Propagation.REQUIRES_NEW
)

tx:annotation-driven

名称:tx:annotation-driven

类型:标签

归属:beans标签

作用:开启事务注解驱动,并指定对应的事务管理器

范例

<tx:annotation-driven transaction-manager="txManager"/>

样例

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttps://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><context:property-placeholder location="classpath:*.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><bean id="accountService" class="com.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/><!--<property name="dataSource" ref="dataSource"/>--></bean><bean class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="typeAliasesPackage" value="com.domain"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.dao"/></bean><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><tx:annotation-driven transaction-manager="txManager"/><!-- <tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="*" read-only="false"/><tx:method name="get*" read-only="true"/><tx:method name="find" read-only="true"/><tx:method name="transfer" read-only="false"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="pt" expression="execution(* com.service.*Service.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/></aop:config>-->
</beans>

package com.service;import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Transactional(isolation = Isolation.DEFAULT)
public interface AccountService {/** 转账操作* outName  出账用户名* inName  入账用户名* money   转账金额*/@Transactional(readOnly = false,timeout = -1,isolation = Isolation.DEFAULT,rollbackFor = {},  //java.lang.ArithmeticException.class, IOException.classnoRollbackFor = {},propagation = Propagation.REQUIRED)public void transfer(String outName, String inName, Double money);
}

10.声明式事务(纯注解驱动)

名称:@EnableTransactionManagement

类型:类注解

位置:Spring注解配置类上方

作用:开启注解驱动,等同XML格式中的注解驱动

范例

@Configuration
@ComponentScan("com.lichee")
@PropertySource("classpath:jdbc.properties")
@Import({JDBCConfig.class,MyBatisConfig.class,TransactionManagerConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
public class TransactionManagerConfig {@Beanpublic PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){return new DataSourceTransactionManager(dataSource);}
}

样例

package com.domain;public class Account {private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
package com.dao;import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;public interface AccountDao {@Update("update account set money = money + #{money} where name = #{name}")void inMoney(@Param("name") String name, @Param("money") Double money);@Update("update account set money = money - #{money} where name = #{name}")void outMoney(@Param("name") String name, @Param("money") Double money);}
package com.service;import org.springframework.transaction.annotation.Transactional;
@Transactional
public interface AccountService {public void transfer(String outName, String inName, Double money);
}
package com.service.impl;import com.dao.AccountDao;
import com.service.AccountService;
import org.apache.ibatis.annotations.Arg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import java.io.IOException;
@Service("accountService")
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;public void transfer(String outName, String inName, Double money) {accountDao.inMoney(outName,money);//int i = 1/0;accountDao.outMoney(inName,money);}
}
package com.config;import org.springframework.context.annotation.*;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@ComponentScan("com")
@PropertySource("classpath:jdbc.properties")
@Import({JDBCConfig.class,MyBatisConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
package com.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;public class JDBCConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String userName;@Value("${jdbc.password}")private String password;@Bean("dataSource")public DataSource getDataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}public PlatformTransactionManager gerTransactionManager(DataSource dataSource){return new DataSourceTransactionManager(dataSource);}
}
package com.config;import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class MyBatisConfig {@Beanpublic SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();ssfb.setTypeAliasesPackage("com.domain");ssfb.setDataSource(dataSource);return ssfb;}@Beanpublic MapperScannerConfigurer getMapperScannerConfigurer(){MapperScannerConfigurer msc = new MapperScannerConfigurer();msc.setBasePackage("com.dao");return msc;}
}

jdbc.properties 

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=123456
package com.service;import com.config.SpringConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;//设定spring专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//设定加载的spring上下文对应的配置
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {@Autowiredprivate AccountService accountService;@Testpublic void testTransfer(){accountService.transfer("Jock1","Jock2",100D);}
}

2.模板对象

1.Spring模板对象

TransactionTemplate

JdbcTemplate

RedisTemplate

RabbitTemplate

JmsTemplate

HibernateTemplate

RestTemplate

2.JdbcTemplate

提供标准的sql语句提供API

public void save(Account account) {String sql = "insert into account(name,money)values(?,?)";jdbcTemplate.update(sql,account.getName(),account.getMoney());
}

3.NamedParameterJdbcTemplate 

提供标准的sql语句提供API

public void save(Account account) {String sql = "insert into account(name,money)values(:name,:money)";Map pm = new HashMap();pm.put("name",account.getName());pm.put("money",account.getMoney());jdbcTemplate.update(sql,pm);
}

4.RedisTemplate

RedisTemplate对象结构

public void changeMoney(Integer id, Double money) {redisTemplate.opsForValue().set("account:id:"+id,money);
}
public Double findMondyById(Integer id) {Object money = redisTemplate.opsForValue().get("account:id:" + id);return new Double(money.toString());
}

3.事务底层原理解析

策略模式(Strategy Pattern)使用不同策略的对象实现不同的行为方式,策略对象的变化导致行为的变化

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

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

相关文章

android开发教程百度网盘,高并发系统基础篇

展望未来 操作系统 移动操作系统的演变过程&#xff0c;从按键交互的塞班功能机到触摸屏交互的Android/IOS智能机&#xff0c;从小屏幕手机到全面屏、刘海屏、水滴屏。任何系统无非干两件事&#xff1a;输入和输出&#xff0c;接收到外部输入信号后经过操作系统处理后输出信息…

史称GPT-4最强劲敌——Claude 3 大模型它来了【附体验教程】

Anthropic 的 Claude 3 Sonnet 模型现已在亚马逊云科技的 Amazon Bedrock 正式可用。 Amazon Bedrock 是目前 第一个 也是 唯一 一个提供 Claude 3 Sonnet 的托管服务 。 Claude 3 免费测试体验者福利&#x1f9e7;&#xff1a;https://mp.weixin.qq.com/s/hszLRa8B5zKsTDg2bmI…

Java两周半速成之路(第七天)

一.多态 3.多态的好处: 提高了程序的维护性(由继承保证) 提高了程序的扩展性(由多态保证) 演示&#xff1a; package com.shujia.day08;public class Animal {String name;int age;public Animal() {}public Animal(String name, int age) {this.name name;this.age age…

安装/升级 gcc

文章目录 查看当前 gcc 版本查看 yum 软件库 gcc 版本列表下载最新版本安装 查看当前 gcc 版本 查看 yum 软件库 gcc 版本列表 只有一个4.8的版本&#xff0c;过旧 下载最新版本 wget https://ftp.gnu.org/gnu/gcc/gcc-13.2.0/gcc-13.2.0.tar.gz 安装 ./configure 报错 提示…

2024年Android开发者跳槽指南,超强Android进阶路线知识图谱

一、概述 随着业务的发展&#xff0c;工程的逐渐增大与开发人员增多&#xff0c;很多工程都走向了模块化、组件化、插件化道路&#xff0c;来方便大家的合作开发与降低业务之间的耦合度。现在就和大家谈谈模块化的交互问题&#xff0c;首先看下模块化的几个优势。 模块化的优…

国创证券|645元克!买还是不买?

近日世界金价继续走强。截至记者发稿&#xff0c;纽约商业交易所&#xff08;COMEX&#xff09;黄金主力4月合约突破2100美元/盎司关口&#xff1b;国内方面&#xff0c;SHFE黄金主力合约则摸高498元/克&#xff0c;迫临500元/克的关口。 巨丰投顾高级出资参谋游晓刚对《证券日…

替代TPS7B7701QPWPRQ1/TPS7B7702QPWPRQ1单/双通道 车规级LDO

PC8803具有高输入电压单低压差调节器&#xff08;PC8803SC01/PC8803SCO3&#xff09;/双通道低压差调节&#xff08;PC8803SC02/PC8803SC04&#xff09;&#xff0c;具有精确的电流感测&#xff0c;设计用于在宽输入电压范围内工作 从4.5V到40V。该设备具有45V负载转储电源输入…

微信小程序触屏事件_上划下划事件

一、微信小程序触屏事件 bindtouchstart&#xff1a;手指触摸动作开始 bindtouchmove&#xff1a;手指触摸后移动 bindend&#xff1a;手指触摸动作结束 属性类型说明touchesArray触摸事件&#xff0c;当前停留在屏幕中的触摸点信息的数组 Touch 对象 属性类型说明identi…

pgvector docker部署测试

docker pull pgvector/pgvector:pg16 运行 docker run --name pgvector --restartalways -e POSTGRES_USERpgvector -e POSTGRES_PASSWORDpgvector -v /srv/tlw/pgvectordata:/var/lib/postgresql/data -p 54333:5432 -d pgvector/pgvector:pg16 CREATE EXTENSION vector; --…

总结:大模型技术栈---算法与原理

原文地址&#xff1a;大模型技术栈-算法与原理 1. tokenizer方法 word-level char-level subword-level BPE WordPiece UniLM SentencePiece ByteBPE2. position encoding 绝对位置编码 ROPE AliBi 相对位置编码 Transformer-XL T5/TUPE DeBERTa3. 注意力机制 Mamba,H3,Hyena…

【Redis】Redis持久化模式RDB

目录 引子 RDB RDB的优缺点 小节一下 引子 不论把Redis作为数据库还是缓存来使用&#xff0c;他肯定有数据需要持久化&#xff0c;这里我们就来聊聊两种持久化机制。这两种机制&#xff0c;其实是 快照 与 日志 的形式。快照:就是当前数据的备份&#xff0c;我可以拷贝到磁…

C语言指针的初步认识--学习笔记(3)

1. 字符指针变量 在C语言中&#xff0c;字符串通常被视为字符数组&#xff0c;但它们可以有不同的表示方式。字符指针变量存储的是字符串的地址。这意味着&#xff0c;当你有一个字符串时&#xff0c;你可以通过改变字符指针的值来改变这个字符串&#xff0c;因为你实际上改变的…

保修期内经营者收取维修费用应遵循正当程序原则

↑↑↑“上海高院”头条号为您讲述精彩的法律科普内容 上海市第一中级人民法院在履行司法审判职能的同时&#xff0c;始终高度重视高质量案件工作&#xff0c;总结司法审判经验&#xff0c;努力提高司法审判质量。 在2020年全国法院系统优秀案例分析评选活动中&#xff0c;上海…

合并有序链反转链表(递归版)

每日一题系列&#xff08;day 19&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50…

基于RFID技术+WMS仓储管理应用设计

一、项目背景 1.1 背景 仓储管理是企业对仓库及其内部物资进行计划、组织、控制和协调的管理过程。它在整个物流和经济活动中扮演着重要的角色&#xff0c;连接着生产者和消费者。 不同规模和产品种类的企业有不同的仓储管理流程和需求&#xff0c;但核心部分都包括仓库作业…

设计模式:策略模式 ⑥

一、策略模式思想 简介 策略模式&#xff08;Strategy Pattern&#xff09;属于对象的行为模式。其用意是针对一组算法&#xff0c;将每一个算法封装到具有共同接口的独立的类中&#xff0c;从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。…

msvcp120.dll丢失的解决方法,教你快速解决msvcp120.dll问题

msvcp120.dll是一个在Windows操作系统中至关重要的系统文件&#xff0c;它属于Microsoft Visual C Redistributable Package的一部分。这个动态链接库文件&#xff08;DLL&#xff09;包含了运行某些应用程序所必需的C运行时库函数。当某个程序在运行过程中需要调用这些预先编译…

关于制作一个Python小游戏(三)

目录 前言: 在前面我们已经了解过了关于制作pygame的使用和在里面游戏中的简单操作的内容了,今天我们主要讲的就是关于敌机的出现和如何去操控游戏中英雄飞机和敌机的出现 1.敌机的设计: 1.1敌机出场的实现: 1.1.1游戏启动后,每个一秒钟出现一架敌方飞机 1.1.2每架敌机向屏…

九章云极DataCanvas公司出席WBBA 2024宽带发展大会

2024年2月27日&#xff0c;由全球云网宽带产业协会&#xff08;World Broadband Association, WBBA&#xff09;主办的全球宽带产业盛会——宽带发展大会&#xff08;Broadband Development Congress, BDC&#xff09;&#xff0c;与全球云网宽带产业合作伙伴相约巴塞罗那。九章…

【爬虫】单首音乐的爬取(附源码)

以某狗音乐为例 import requests import re import time import hashlibdef GetResponse(url):# 模拟浏览器headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0}# 发送请求…