使用代码生成器生成的代码操作数据库

如图10-4所示,mybatis-generator自动生成了Domain、Mapper和XML文件,其中Domain包括了Entity和 Example。Entity和数据库表结构一一对应,Example是我们操作数据库使用最频繁的类,它封装了分页、排序、查询条件等方法,我们做单表CRUD时就会大量使用Example,可以达到过滤条件的目的。Mapper封装了基本的CRUD方法,它和XML定义的Mapper对应,下面是其中一个数据库表对应的Domain、Mapper和XML的部分内容:

public class User implements Serializable {
private Long id;
private Date gmtCreate;private Date gmtModified;private string username;private String password;...
}
public class UserExample implements Serializable {
protected String orderByclause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
private static final long serialversionuID = 1L;private Integer limit;
private Integer offset;
public Criteria andIdIsNull(){
addCriterion( "id is null");return (criteria) this;
}
...
}
public interface UserMapper {
int countByExample(UserExample example);int deleteByExample(UserExample example);int deleteByPrimaryKey(Long id);
int insert(User record);
int insertSelective(User record);
List<User> selectByExample(UserExample example);User selectByPrimaryKey(Long id);
int updateByExampleSelective(@Param(" record") User record,@Param( " example")
UserExample example);
int updateByExample(@Param(" record") User record,@Param("example") UserExample
example);
int updateByPrimaryKeySelective(User record);int updateByPrimaryKey(User record);
}
<mapper namespace="com.lynn.blog .pub.mapper. UserMapper" >
<resultMap id="BaseResultMap" type="com.lynn.blog.pub . domain.entity.User" ><id column= "id" property="id" jdbcType="BIGINT”/>
<result column="gmt_create" property="gmtCreate"jdbcType="TINESTAMP"/><result column="gmt_modified" property="gmtModified" jdbcType="TIMESTAMP"/><result column="username" property="username" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR"/></resultMap>
...
</mapper>

在操作单表时,我们无须针对每个功能都编写一个SQL语句,只需要灵活运用Example即可实现我们想要的功能,Example实现了所有字段的查询条件,如=、!=、>、<、AND、OR、BETWEEN等。

查看Mapper代码,可以发现查询方法为selectByExample,需要传入Example,因此我们可以构建一个Example并设置查询条件。以User为例,如果我们要查询用户名为xxx的用户,则构建的Example 如下:

UserExample example = new UserExample();
example.createcriteria()
.andUsernameEqualTo( ""xxx");

然后调用selectByExample方法,如:

userMapper.selectByExample(example);

新增数据的方法以insert开头,传入的参数是Entity。insert和 insertSelective的区别在于前者不会进行判断,即如果Entity有字段为null,则会将null值保存到该字段中,而后者会判断字段是否为null,如果为null 则不会将null值保存到该字段中。

修改和删除两个方法的使用比较类似,需要注意的是,凡是名称中带有selective的方法均会先判断字段是否为null,否则不会判断,读者在调用时可根据实际场景进行选择。

查询、修改和删除都有两个方式:按ID和按条件。按ID操作时后面都会带上ByPrimaryKey。

如果数据库的某个字段为text类型,则生成时会多生成一个selectByExamplewithBLOBs 方法,在查询时如果只调用selectByExample方法,则不会查询类型为text的字段,此时若要返回该字段,则需调用selectByExamplewithBLOBs方法。

MyBatis应对复杂SQL

MyBatis的一大优势是它是操作原生SQL,因此它可以应对很多复杂场景,而一些大型应用,都存在一些较为复杂的业务场景。前面学习的代码生成器主要针对单表的操作,面对复杂的业务,我们就需要自己编写SQL。

MyBatis提供了多种实现方式,包括XML、注解和Provider,而代码生成器生成了基本的CRUD代码,为了提升代码的扩展性,这里不能直接在原有的Mapper上增加方法,而应扩展一个子Mapper继承代码生成器生成的Mapper,如:

@Mapper
public interface SubBlogMapper extends BlogMapper {
}

代码生成器生成的Entity和数据库一一对应,如果当前业务需要的字段和数据库字段不一致时,也应扩展一个子Entity。扩展方法的代码如下:

@Data
public class SubBlog extends Blog i
**
*用户名*/
private String username;
}

比如我们在返回博客列表时,往往需要返回当前博主的用户名等信息,而博客表只关联了用户ID,这时就需要扩展一个子Entity,并且查询时返回子Entity。

以上是一个比较良好的代码设计风格,也符合软件的架构模式,接下来就以博客列表为例,用注解和 Provider两种方式分别讲解如何应对复杂 SQL。

注解

通过注解来查询SQL非常简单,只需要在方法上加入@Select()即可(括号内输入SQL语句),如:

@Select("select* from blog b,user u where b.user_id = u.id limit #{offset},#{limit}")List<SubBlog> selectBlogList(@Param( "offset") int offset,@Param("limit") int limit);

同XML一样,注解也可以使用<if>和<for>等标签,但必须用<script></script>将SQL语句包裹,如:

@Select("<script>select * from blog b,user u where b.user_id = u.id cif test=\ "null !-
title\ ">and b.title = #{title}</if> limit #{offset} ,#{limit}</script>")
List<SubBlog> selectBlogList(@Param("title")String title,@Param("offset") int
offset,@Param( "limit") int limit);

当条件较少时,这种写法没有问题,但如果条件很多,用这种注解的方式就不可取了。注解是写到字符串里面的,所以当单词拼写错误时,编译器不会报错,于是在包含复杂SQL语句的情况下很难排查错误。这时候,就轮到Provider登场了。

Provider

将方法标注为Provider(查询为@selectProvider,新增为@InsertProvider,修改为@UpdateProvider,删除为@DeleteProvider ),然后通过Provider的方法动态生成SQL语句,将上述注解的SQL语句改造成Provider 如下:

SelectProvider(type= BlogProvider.class,method = "selectBlogListProvider")
List<SubBlog> selectBlogList(@Param("title")String title,@Param("offset") int offset,
@Param( "limit") int limit);
public class BlogProvider i
public string selectBlogListProvider(@Param("title")String title,@Param("offset")
int offset,@Param( "limit") int limit){
return new sQL(O{
{
SELECT("*");
FROM("blog b,user u");wHERE("b.user_id = u.id");if(null != title){
wHERE("b.title =#{title}");
}
}
}.toString(+ "limit #{offset},#{limit}";}
}

可以看到,上述代码没有使用@Select注解,而是采用@selectProvider注解,该注解会指定一个类,并指定该类的方法。当调用selectBlogList方法时,MyBatis就会指定BlogProvider类的selectBlogListProvider方法。

selectBlogListProvider方法的参数和 selectBlogList方法的参数保持一致,在方法体内直接返回sQL对象,并使用toString方法转换为字符串返回,其他方法的作用就是动态生成SQL语句(如SELECT("*")表示生成SELECT *,FROM("blog,user u")表示生成FROM blog b ,user u),它最终执行的是Provider生成的SQL语句。读者看到 sQL对象内的代码是否感觉似曾相识呢?没错,它和前面自己写的SQL语句是一样的,只是这里是调用了Java方法,比如SELECT("*")最终返回的就是select *。

通过Provider可以将一些关键词( select、from、where、order by等)用Java代码代替,大大提升了可读性。

功能开发

本节中,我们将正式进入产品的功能开发,根据第5章提供的原型设计,我们可以将产品划分为以下几大模块。

用户管理:主要操作用户表,包括注册登录,用户信息管理等功能。口博客管理:主要操作博客表,包括博客的展示、发布等。

口评论管理:主要操作评论相关表,包括评论的展示、发表、点赞等。分类管理:主要操作分类表,包括分类列表展示等。

搜索服务:主要用于提供搜索引擎服务,开放博客的搜索接口。

对这些模块都创建一个子工程,每一个工程都是一个微服务,如图10-5所示。

图中的public为各微服务的公共类库。

接下来,将以博客列表功能为例,来讲解功能的开发。

(1)创建输入参数Request和输出参数Response:

@Data
public class BlogListRequest i
//加了@NotNull注解表示参数必填@NotNull
private Long categoryId;@NotNull
private Integer offset;@NotNull
private Integer limit;
}
@Data
public class BlogListResponse {i
private Long id;
private string title;private string summary;private String createTime;private Integer viewCount;
}

每一个接口(业务)都应该对应一个请求和一个响应,因此我们在提供接口时,首先要分析该接口接收什么参数,返回什么参数,从而定义Request和 Response。

(2)定义接口:

public interface BlogService i
**
*根据分类ID获得博客列表* @param request
*@return
*/
MultiResult<BlogListResponse> getBlogListByCategoryId(BlogListRequest request);
)

(3)实现接口:

@Service
public class BlogServiceImpl implements BlogService {
@Autowired
private BlogMapper blogMapper;@override
public MultiResult<BlogListResponse> getBlogListByCategoryId(BlogListRequest request){
BlogExample example = new BlogExample();
example.setOffset(request.getOffset());example.setLimit( request.getLimit())3example.createCriteria()
.andCategoryIdEqualTo(request.getcategoryId());
int count = blogMapper.countByExample(example);
if(count > 0){
List<Blog>bloglist = blogMapper.selectByExample(example);if(null != blogList && blogList.size( >e){
List<BlogListResponse> data = new ArrayList<>();blogList.stream( ).forEach(blog ->{
BlogListResponse response = new BlogListResponse();//将blog对象属性复制到response
Beanutils.copyProperties(blog, response);response.setCreateTime
(Dateutils.parseDate2String(blog.getGmtcreate() , "yyyy-MM-
dd HH : mm : ss"));
data.add(response) ;
});
return MultiResult.buildSuccess(data, count);
}
return MultiResult.buildSuccess(new ArrayList<>(), count);
}
return MultiResult.buildSuccess(new ArrayList<>() , count);
}
}

上述代码实现了一个最基本的接口:通过分类ID返回博客列表,其中数据查询部分使用10.2节介绍的代码生成器。我们将查询出的数据进行了一些处理,首先通过BeanUtils.copyProperties将Entity 的数据复制到Response 中,并处理一些数据,比如格式化时间等。

(4)编写控制器,以提供HTTP 调用能力:

@RequestMapping( "{version }/open/blog")@RestController
public class BlogController extends BaseV1controller {
@Autowired
private BlogService blogService;
@PostMapping( "getBlogListByCategoryId")
public MultiResult<BlogListResponse> getBlogListByCategoryId(@Valid @RequestBody
BlogListRequest request,BindingResult result){
validate(result);
return blogService.getBlogListByCategoryId(request);
}
}

控制器的代码其实简单,就是调用service方法。需要注意的是,在调用Service方法之前,应调用validate方法进行参数的合法性校验。

(5)测试。

分别启动register . config . gateway和 blogmgr,用postman请求地址
htp:/localhost:8080/BLOG/v1/open/blog/getBlogListByCategoryld?token=1,可得到如图10-6所示的界面。

网关鉴权

前面已经提到,我们请求的所有接口都需要通过网关来转发,而不是直接请求服务。对于一个HTTP接口来说,安全是最重要的,本节将介绍博客应用的鉴权机制。

细心的读者可以发现,上一节定义的接口地址中带有open接口,其实对于接口,我们可以大致划分为开放接口和私有接口。开放接口指无须用户登录即可访问的接口,私有接口则为登录后才能访问的接口。为了便于区分开放接口和私有接口,我们可以在接口地址“做文章”,即带有open 的为开放接口,带有close的为私有接口。

防止参数被篡改

我们提供的接口是通过网络传输的,如果在传输过程中参数被拦截并将修改后的参数传输给服务器端,后果将非常严重。为了防止此类事件发生,我们需要对参数进行签名并校验。

签名的规则是,客户端将参数名按ASCII 码升序排列,构建形如 key1=valuel&key2=value2……的字符串(后面用url代替该字符串),然后将这个字符串进行MD5加密,如 MD5(url+key)(其中 key为密钥),加密后生成签名字符串,将签名字符串放到请求头( header )中,参数放到请求体( body)中,传递到服务端。服务端以同样的方式签名,将签名后的结果和客户端传递过来的结果进行比较,如果一致说明参数没有被篡改,可以放过,否则中断操作。

这样如果中途有人篡改了参数,服务器签名后和客户端签名必然是不匹配的,有效地保护了参数的合法性。下面就来改造gateway工程的ApiGlobalFilter类,具体的代码如下:

@Value("${api.encrypt.key}")
private string salt;
@Override
public Mono<Void> filter(ServerwebExchange exchange,GatewayFilterChain chain) {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
String body = requestBody( serverHttpRequest);
String uriBuilder = getUr1AuthenticationApi(body);//服务端生成额签名
string sign = MessageDigestutils.encrypt(uriBuilder + salt,Algorithm.MD5);1/从header中取得签名字符串
String signature = serverHttpRequest.getHeaders().getFirst("signature");if (sign l= null && sign.equals(signature)) {
1/以下代码再次包装request,否则会报:Only one connection receive subscriber
allowed.错误
URI uri = serverHttpRequest.getURI();
ServerHttpRequest request = serverHttpRequest.mutate().uri(uri) .build();DataBuffer bodyDataBuffer = stringBuffer(body);
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);request = new ServerHttpRequestDecorator(request){
@override
public Flux<DataBuffer> getBody( {
return bodyFlux;
}
};
return chain.filter(exchange.mutate( ).request(request).build());else {
//签名错误
ServerHttpResponse response = exchange.getResponse();
byte[ ] bits =JSON.to3SONString(SingleResult.buildSuccess(Code.NO_PERMISSION,
"签名错误"))-getBytes(Standardcharsets.UTF_8);
DataBuffer buffer = response.bufferFactory ().wrap(bits);return response.writewith(Mono.just( buffer));
}
}
/**
*将客户端传回的参数按照ASCII 码升序排序生成URL字符串*/
private string getUrlAuthenticationApi(String body){
if(StringUtils.isEmpty( body)) f
return nul1;
}
List<String>nameList = new ArrayList<>()3
StringBuilder urlBuilder = new stringBuilder(;SONObject requestBodyson = null;
requestBody3son = 3SON .parseobject( body);nameList.addAll(requestBodyJson. keySet();
final 3SONObject requestBody3sonFinal = requestBodyson;namelist.stream() . sorted( ).forEach(name -> {
if(null != requestBodysonFinal){
ur1Builder. append( '&' );
urlBuilder.append(name) . append( '=' ).append(requestBody3sonFinal.
getstring(name)) ;
}
});
urlBuilder.deleteCharAt(0);return urlBuilder.tostring();
}
/**
*获得body 数据*@return请求体*/
private string requestBody(ServerHttpRequest serverHttpRequest){
//获取请求体
F1ux<DataBuffer> body = serverHttpRequest.getBody();
AtomicReference<String> bodyRef = new AtomicReference<>();
body . subscribe( buffer ->{
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());DataBufferUtils.release( buffer);
bodyRef.set( charBuffer.toString());});
return bodyRef.get();
}
private DataBuffer stringBuffer(String value)i
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory
( ByteBufAllocator. DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);buffer.write(bytes);
return buffer;
}

上述代码的作用是判断当前请求参数是否正常(即是否被篡改)。首先,调用requestBody方法获得body里的参数(JSON格式),然后调用getUrlAuthenticationApi方法将参数名按照ASCII码升序排列,以key1=value1&key2=value2的形式拼接成字符串urlBuilder,接着通过MD5(urIlBuilder+saltR)的形式加密,返回签名字符串sign,最后从请求头中取得signature进行判断,如果sign和signature相等,则签名通过,否则签名失败,予以拦截。

由于签名验证通过后参数是放到body 中传输的,所以不能直接返回 Mono(如果以form表单形式或者直接放到请求地址中可以直接返回),需要再进行一层包装,否则会抛出“Only one connectionreceive subscriber allowed”异常。正如上述代码中,我们将 body中的参数转成DataBuffer并通过
ServerHttpRequestDecorator类做一层包装后返回。

拦截非法请求

所有私有接口都带有close,而要调用私有接口则必须为已登录用户,程序确认客户端是否为登录用户的依据就是判断token是否合法。

当用户调用登录接口后,服务端会根据用户名、密码和时间戳等信息生成token,并将token保存到Redis返回给客户端。我们要求客户端在调用私有接口时,向请求头传人token,服务端在过滤器里判断当前token是否正确,如果正确,则允许调用接口,否则给出错误提示。

生成token 的方式很随意,读者可以根据自己的喜好来生成,可以用MD5、Base64和AES等算法,下面是使用AES算法生成token的代码,如:

public static String generateToken(String username,string key){
try {
return AesEncryptutils.aesEncrypt(username+ System.currentTimeMillis(),key);}catch (Exception e){
e.printStackTrace();return null;
}
}

token生成后需要将它存入Redis,key为token,value为user.getId()方法获取到的userId:

redis.set(token, user.getId()+"");

这样当客户端传入token时,我们就可以从Redis里根据token读取userId,如果能取到说明token合法,反之为非法请求。私有接口需传入userId并与服务器取得的userId做比较,如果相同则允许访问,否则给出错误信息,具体代码实现如下:

if(uri.getPath().contains("close")){
String token = request.getHeaders().getFirst("token" );if(StringUtils.isNotBlank(token)){
String userId =(String) redis.get(token);if(Stringutils.isNotBlank(userId)){
SONObject json0bject = 3SON. parse0bject(body);if(userId.equals(json0bject.getLong( "userId"))){
return chain.filter(exchange.mutate().request(request).build());}elsei
ServerHttpResponse response = exchange.getResponse();
byte[ ] bits = 3SON.to3SONString(SingleResult.buildSuccess(Code.NO_PERMISSION,
"invalid token")).getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory( ).wrap(bits);return response.writewith(Mono.just(buffer));
}
}else {
ServerHttpResponse response = exchange.getResponse();
byte[] bits = 3SON.to3SONString(SingleResult.buildSuccess(Code.NO_PERMISSION,
"invalid token")).getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory(). wrap(bits);return response.writewith(Mono.just(buffer));
}
}else{
ServerHttpResponse response = exchange.getResponse();
byte[] bits = ]SON.toJSONString(SingleResult.buildSuccess(Code.NO_PERMISSION,
"invalid token")).getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory( ).wrap(bits);
return response.writewith(Mono.just(buffer));
}
}

单元测试

我们将接口开发完成后,整个应用的开发就已接近尾声,最后需要进行测试才能发布应用。

单元测试工具有很多,本书将演示使用JUnit进行单元测试,使用步骤如下。

(1)添加JUnit依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</ artifactId>
</ dependency>

(2)在子工程目录下新建单元测试类,并编写测试代码:

@SpringBootTest(classes = UserApplication.class)@Runwith(SpringJUnit4classRunner.class)
public class TestDB {
@Autowired
private UserService userService;@Test
public void test(o{
try i
LoginRequest request = new LoginRequest();request.setUsername( "lynn" );
request.setPassword("1");
System.out. println(userService.login(request)) ;}catch (Exception e){
e.printStackTrace();
}
}
}

上述代码通过添加@SpringBootTest注解指定启动入口类,@Runwith注解用于指定单元测试启动器,在需要执行的方法上加入@Test即可。

(3)单击右键,选择Run 'test()'运行单元测试方法,如图10-7所示。

小结

本章中我们正式开始了实战项目的功能开发。通过本章的学习,我们了解了如何高效地使用MyBatis,简化我们的持久层开发,亦了解了接口的安全性校验,达到提升系统的安全性的目的。

本文给大家讲解的内容是springcloud实战:使用代码生成器生成的代码操作数据库

  1. 下篇文章给大家讲解的是springcloud实战:服务间通信,SpringCloudNetflix Ribbon和OpenFeign;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 前端对大额数据进行千分位分割

    前端对大额数据千分位分割可以是用js自带的toLocaleString()方法 let a9800821.68console.log(a.toLocaleString())输出结果是 9,800,821.68...

    2024/4/13 8:40:40
  2. 记录Vue动态添加菜单路由

    前言&#xff1a; 管理系统默认只存在登录页面这一个路由。 import Vue from vue import VueRouter from vue-router Vue.use(VueRouter) const routes [{path: /login,name: Login,component: () > import(/views/Login.vue),meta: {title: "登录",isSub: fal…...

    2024/4/28 1:27:20
  3. 蓝桥杯真题训练

    #蓝桥杯真题训练 1-数列求值&#xff1a; 给定数列 1, 1, 1, 3, 5, 9, 17, \cdots1,1,1,3,5,9,17,⋯&#xff0c;从第 44 项开始&#xff0c;每项都是前 33 项的和。 求第 2019032420190324 项的最后 4位数字 a, b, c, d 1, 1, 1, 0 for i in range(4, 20190325):d (a b…...

    2024/4/27 22:30:52
  4. vue创建项目出现npm ERR syscall mkdir

    文章目录解决方法1解决方法2在vscode执行vue命令时出现&#xff1a;npm ERR! code EPERMnpm ERR! syscall mkdirnpm ERR! path D:\software\nodejs\node_cache_cacachenpm ERR! errno EPERM…或出现&#xff1a;npm ERR! code EPERMnpm ERR! syscall opennpm ERR! path D:\soft…...

    2024/4/17 22:20:28
  5. 前后端日期格式化

    import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; 入参格式 DateTimeFormat(pattern "yyyy-MM-dd") 出参格式化 JsonFormat(pattern "yyyy-MM-dd", timezone "GMT8") pr…...

    2024/4/19 8:49:41
  6. 【论文笔记】Why Attentions May Not Be Interpretable?

    Why Attentions May Not Be Interpretable? arxiv地址 工作背景 关于attention 机制的可解释性有很强的争议&#xff0c;所以本文作者试图找到影响attention可解释性的根本原因。作者提出根本影响因素之一是 : combinatorial shortcuts(attention除了要高亮重要的part, e.g…...

    2024/4/13 8:40:35
  7. 赛事编排顺时针转法--PHP实现

    public function clockwise() { // 蛇形编排&#xff0c;单数补0轮空 $n 6; //队伍数量&#xff0c;也可以直接传入队伍名称的数组&#xff0c;索引从0开始&#xff0c;例&#xff1a;[0>杨威队,1>黎明队,...] if ($n % 2 0) { $count range(1, $n); } else { $count …...

    2024/4/28 0:10:44
  8. MyBatis学习:高级查询(一对一映射)

    一、一对一映射 假设在权限系统中&#xff0c;一个用户只能拥有一个角色&#xff0c;即用户和角色之间的关系限制为一对一的关系。 1.1 使用自动映射处理一对一关系 一个用户拥有一个角色&#xff0c;我们在用户类SysUser中添加角色类SysRole字段。如下&#xff1a; public …...

    2024/4/27 18:44:26
  9. Linux下tar bz gz等压缩包的压缩和解压

    Linux下tar bz gz等压缩包的压缩和解压 - 云社区 - 腾讯云 Linux下用户经常需要备份计算机系统中的数据&#xff0c;为了节省存储空间&#xff0c;常常将备份文件进行压缩&#xff0c;本文是对压缩和解压命令的大致总结 .tar.gz  解压&#xff1a;tar zxvf FileName.tar.gz…...

    2024/4/28 3:28:37
  10. iView输入框校验失败

    bug:第一次校验可以&#xff0c;如果本页面有保存按钮&#xff0c;点击保存后刷新页面校验就失效了。 解决办法&#xff1a; 方法一&#xff1a;可能是页面中过多的if语句&#xff0c;没有跳出if语句。所以要为if语句加 else{ return false; // 也不是万能语句&#xff0c;…...

    2024/4/13 8:41:30
  11. 更为系统的操作数据库-MyBatis

    更为系统的操作数据库-MyBatis MyBatis是一个基于ORM对象关系映射的框架&#xff0c;其提供的Mapper方式的动态代理&#xff0c;让我们只要关心SQL&#xff0c;其余复杂的操作由框架来完成&#xff0c;特别是ResultMap&#xff0c;对于复杂查询颇多的业务&#xff0c;选择MyBat…...

    2024/4/13 8:41:35
  12. MyBatis查找到多值时Mapper层接收类型和Mapper.xml层返回类型

    由于根据条件查出来的值为多个&#xff0c;Mapper层用List<返回值的类型>来接收&#xff0c;Mapper.xml层返回类型即为返回值的类型1://分类查找相对应的全部指南标题 List<String> queryTittles(Param("busguideBelongClass") String busguideBelongCla…...

    2024/4/27 21:33:02
  13. 在微控制器平台等小型物联网设备上运行 JavaScript

    当谈到嵌入式开发时&#xff0c;您通常首先查看您在硬件级别尝试做什么。例如&#xff0c;如果您需要读取某种传感器并将公式应用于其值&#xff0c;以便您可以在某处显示结果&#xff0c;您可以查看哪些微控制器带有模数转换器 (ADC)&#xff0c;并且还可以驱动一个显示器。适…...

    2024/4/28 5:56:56
  14. vue-amap 实现高德地图定位 + 搜索

    1. map子页面 html&#xff1a; <template><div class"amap-page-container"><!-- 搜索条件 是个对象searchOption 属性是city城市名&#xff0c;citylimit&#xff1a;false&#xff1b; 搜索回调函数 --><el-amap-search-boxclass"sea…...

    2024/4/19 10:13:23
  15. MySQL Binlog Digger 4.28

    下载地址: https://download.csdn.net/download/bournetai/79996644 修正了4.27版本一些已知bug...

    2024/4/18 17:34:20
  16. 2022最新H5盲盒交友系统

    2022最新H5盲盒交友系统 测试环境&#xff1a;NginxPHP7.2Mysql5.6 删除PHP7.2的禁用函数&#xff0c;安装扩展sg11 网站运行目录 /public 伪静态设置为 thinkphp 数据库配置文件路径 /.env 后台登录地址&#xff1a;/admin 后台登录账号&#xff1a;admin 学习资料地址&a…...

    2024/4/13 8:41:40
  17. uniapp app上传

    使用jpm-upload控件 jpm-upload 上传 upload 示例代码 基础用法 <template><view class"content"><jpm-upload :url"url" :name"name" :headers"headers" :formdata"formdata" upload"upload"…...

    2024/4/15 15:19:32
  18. java中equals的重写(equals和==的区别)

    和equals的区别...

    2024/4/13 8:41:25
  19. MFC文本编程--退格键的操作

    // 退格键的操作 COLORREF clr dc.SetTextColor(dc.GetBkColor()); // 设置使用背景颜色 dc.TextOut(0, 0, m_strLine); // 在界面上输出原来的文字信息&#xff0c;因为使用的文字颜色与背景色一致&#xff0c;所以看不到 m_strLine m_strLine.Left(m_strLine.GetLength()…...

    2024/4/20 11:14:47
  20. cv_bridge 与opencv 版本不匹配的解决

    问题描述&#xff1a; ubuntu18.04安装的ros 默认的opencv版本和cv_bridge 版本为3.2.0 但是在使用其他程序包的时候有时候需要用到其他版本的opencv。再调用cv_bridge的时候会发生调用冲突&#xff1b; 解决&#xff1a; 1. 卸载原来的 cv-bridge sudo apt-get remove ros…...

    2024/4/5 2:20:47

最新文章

  1. Node.js -- 包管理工具

    文章目录 1. 概念介绍2. npm2.1 npm 下载2.2 npm 初始化包2.3 npm 包(1) npm 搜索包(2) npm 下载安装包(3) require 导入npm 包的基本流程 2.4 开发依赖和生产依赖2.5 npm 全局安装(1) 修改windows 执行策略(2) 环境变量Path 2.6 安装包依赖2.7 安装指定版本的包2.8 删除依赖2.…...

    2024/4/28 7:11:30
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. javaWeb网上零食销售系统

    1 绪 论 目前&#xff0c;我国的网民数量已经达到7.31亿人&#xff0c;随着互联网购物和互联网支付的普及&#xff0c;使得人类的经济活动进入了一个崭新的时代。淘宝&#xff0c;京东等网络消费平台功能的日益完善&#xff0c;使得人们足不出户就可以得到自己想要的东西。如今…...

    2024/4/27 19:08:10
  4. 面试经典算法系列之双指针1 -- 合并两个有序数组

    面试经典算法题1 – 合并两个有序数组 LeetCode.88 公众号&#xff1a;阿Q技术站 问题描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#…...

    2024/4/27 20:48:48
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/26 18:09:39
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/28 3:28:32
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/26 23:05:52
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/27 4:00:35
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/27 9:01:45
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/28 1:22:35
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/26 19:46:12
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/27 11:43:08
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/27 8:32:30
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57