day50_mybatis
今日内容
0 复习昨日
一、分页插件
二、ORM映射【重点】
三、多表联查 【重点】
四、动态SQL 【重点】
五、$和#
零、复习昨日
mybatis orm框架,作用于持久层,高效开发,只关注sql,其他不用关心
思考MyBatis到底帮你省了哪些事情?
jdbc第四步sql自己编写之外,其他mybatis都做了…
接口文件和映射文件如何关联?
namespace
接口文件中方法又是如何和映射文件中的语句关联?
接口的方法名与映射文件标签的id一致
语句执行时入参都可以有哪些?有什么注意事项?
基本类型,String,Map,List,POJO(javabean/对象)
语句执行后返回的有哪些类型?(出参)
基本类型,字符串,对象
BUG:
1 idea中resuorces和test文件不识别
手动设置标记
2 编码格式
控制台错误提示:
MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
解决方案,在pom文件中加入配置
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
补充: mapper文件位置
mapper映射文件放置位置有两个
- resources(推荐)
- java
- 如果使用这种,还需再pom文件加入build设置,让idea加载java下的xml文件
myabtis-config.xml文件加载映射文件时也要两种方案
使用
<mapper resource="com/qf/mapper/UserMapper.xml"/>
但是这种写法,会随着项目模块的增多,这个地方也会随之配置增多使用
<package name="com.qf.mapper"/>
这种写法可以一次加载一个包下的所有映射文件,但是包结构要与接口文件包结构一致
总结,以后就按照以下写法配置:
- 映射文件全部放在resources
- resources下放映射文件包结构要与java放接口文件包结构一致
- 文件名要一致
一、分页插件
现在我们要学习使用一个常用的mybatis的插件 --> 分页插件-PageHelper
最早: findAll() ---> 查全部
后来要分页: findAll(pageNo,pageSize) ---> 改动SQL 加上 limit x,y
还行count(*)来计数
使用分页插件之后,只编写正常的查询SQL即可,关于分页的操作插件会自动完成.
引入依赖
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.0</version></dependency>
全局配置文件使用插件
<!-- 插件 --><plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"/></plugins>
在查询时使用分页功能
public interface UserMapper {List<User> findAll();
}<select id="findAll" resultType="User">select * from tb_user
</select>@Test
public void findAll() {UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 【在执行查询前设置】// 参数1: 当前页// 参数2: 每页大小PageHelper.startPage(2,2);List<User> all = mapper.findAll( );for (User user : all) {System.out.println(user );}
}
mybatis插件是对运行时某一点进行拦截
pagehelper插件是拦截运行时发出的SQL,自动在SQL后面拼接关键词
后续还可以获得更新消息的分页数据,比如共多少条数据?共多少页?当前页?下一页?目前是不是第一页?
@Testpublic void findAll() {UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 【在执行查询前设置】// 参数1: 当前页// 参数2: 每页大小PageHelper.startPage(2,2);// 执行查询全部List<User> userList = mapper.findAll( );// 后续可以获得更详细的信息PageInfo<User> pageInfo = new PageInfo<>(userList);System.out.println(pageInfo );// 获得总条数System.out.println(pageInfo.getTotal() );// 获得总页数System.out.println(pageInfo.getPages() );// 获得总数据(当前页中的总数据)System.out.println(pageInfo.getList() );}
ps: 可以看源码,中国人开发,注释非常好理解
二、ORM映射
2.1 MyBatis自动ORM失效
MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。
自动ORM失效 |
---|
![]() |
2.2 方案一:列的别名
在SQL中使用 as 为查询字段添加列别名,以匹配属性名。
<mapper namespace="com.qf.mapper.UserMapper"><select id="findUserById" resultType="User">select id as idd,username,password,phone,create_time,sex,money from tb_user where id = #{id}</select>
</mapper>
2.3 方案二:结果映射(ResultMap - 查询结果的封装规则)
通过< resultMap id=“” type=“” >映射,匹配列名与属性名。
<mapper namespace="com.qf.mapper.UserMapper"><!--定义resultMap标签--><resultMap id="findUserByIdResultMap" type="user"><!--关联主键与列名--><id property="idd" column="id" /></resultMap><!--使用resultMap作为ORM映射依据--><select id="findUserById" resultMap="findUserByIdResultMap">select id,username,password,phone,create_time,sex,money from tb_user where id = #{id}</select>
</mapper>
三、 多表联查 【重点】
表关系: 一对一,一对多,多对多
多表联查的SQL
3.1 OneToOne
需求: 实现一对一查询,查询订单以及对应的用户信息
数据: tb_user表, tb_order表
关系:
用户 —> 订单 (1 VS N) 一个用户有多个订单
订单 —> 用户 (1 VS 1) 一个订单只会属于一个人
tb_user表
CREATE TABLE `tb_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',`username` varchar(10) DEFAULT NULL COMMENT '用户名',`password` varchar(10) DEFAULT NULL COMMENT '密码',`phone` varchar(11) DEFAULT NULL COMMENT '手机号',`create_time` date DEFAULT NULL COMMENT '注册时间',`money` double(10,2) DEFAULT NULL COMMENT '账户余额'PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8;
tb_order表
CREATE TABLE `tb_order` (`oid` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单编号',`order_time` datetime DEFAULT NULL COMMENT '订单时间',`order_desc` varchar(255) DEFAULT NULL COMMENT '订单详情',`uid` int(11) DEFAULT NULL COMMENT '关联用户id',PRIMARY KEY (`oid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;INSERT INTO `tb_order` VALUES (1, '2022-11-17 15:06:29', '笔记本电脑', 1);
INSERT INTO `tb_order` VALUES (2, '2022-12-16 11:00:41', 'Cherry键盘', 1);
INSERT INTO `tb_order` VALUES (3, '2022-12-16 11:01:23', 'Logi鼠标', 2);
实体类
public class Order {private int oid;private Date orderTime;private String orderDesc;private int uid;// set get...
}
但是上面的实体类,只有订单信息,我们要查询的是订单和用户! 上面的类就无法展现全部数据,所以需要扩展类
public class OrderVO extends Order {private User user;// set get
}
OrderMapper.java接口文件
public interface OrderMapper {OrderVO findOrderWithUserById(int oid);
}
OrderMapper.xml映射文件
<resultMap id="orderWithUserResultMap" type="OrderVO"><!-- 封装查询主体Order: --><id column="oid" property="oid"/><result column="order_time" property="orderTime"/><result column="order_desc" property="orderDesc"/><result column="uid" property="uid"/><!-- 一对一映射,需要封装关联的User对象 --><!-- 一对一映射,需要特殊标签 association--><!-- property="user" 是OrderVO类中的属性,javaType是user属性的类型 --><association property="user" javaType="com.qf.model.User"><!-- 下面正常的列和属性 一一映射 --><id column="id" property="id"/><result column="username" property="username"/><result column="password" property="password"/><result column="phone" property="phone"/><result column="create_time" property="createTime"/><result column="money" property="money"/></association></resultMap><!-- 多表联查,直接返回resultType无法封装关联的那个对象,就使用使用resultMap手动映射 --><select id="findOrderWithUserById" resultMap="orderWithUserResultMap">SELECTo.*,u.*FROMtb_order o,tb_user uWHEREo.uid = u.idAND o.oid = 1</select>
测试
@Testpublic void findOrderWithUserById() {OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);OrderVO orderVO = mapper.findOrderWithUserById(1);// 获得订单信息int oid = orderVO.getOid( );System.out.println("oid = " + oid);Date orderTime = orderVO.getOrderTime( );System.out.println("orderTime = " + orderTime);String orderDesc = orderVO.getOrderDesc( );System.out.println("orderDesc = " + orderDesc);// 获得订单一家关联的用户信息User user = orderVO.getUser( );System.out.println(user );}
3.2 OneToMore
需求: 一对多,查询用户关联查询出所有的订单
SELECT*
FROMtb_user u
LEFT JOIN tb_order o ON u.id = o.uid
WHEREu.id = 3
目的查询用户,以及关联多个订单,User类不够展现全部数据,那么就创建扩展类UserVO,UserVO类继承User就可以存储用户信息,还需要再UserVO类中添加Order类来存储信息,但是!!不是一个Order类,因为是一对多,一个用户关联多个订单,所有要设置List<Order>
User扩展实体类
public class UserVO extends User{private List<Order> orderList;@Overridepublic String toString() {String s = super.toString( );return s +" \r\n UserVO{" +"orderList=" + orderList +'}';}public List<Order> getOrderList() {return orderList;}public void setOrderList(List<Order> orderList) {this.orderList = orderList;}
}
UserMapper.java接口
public interface UserMapper {UserVO findUserWithOrdersById(int id);
}
UserMapper.xml映射文件
<!-- 一对多 --><resultMap id="userWithOrdersResultMap" type="UserVO"><!-- 封装User对象 --><id column="id" property="id"/><result column="username" property="username"/><result column="password" property="password"/><result column="phone" property="phone"/><result column="create_time" property="createTime"/><result column="money" property="money"/><!-- 一对多关联映射使用collection标签 --><!-- property是UserVO类中关联的属性 --><!-- 不是javaType,是ofType,是指定集合中存储的数据类型 --><collection property="orderList" ofType="com.qf.model.Order"><id column="oid" property="oid"/><result column="order_time" property="orderTime"/><result column="order_desc" property="orderDesc"/><result column="uid" property="uid"/></collection></resultMap><!-- 多表联查,另外的属性不会自动封装,需要使用resultMap --><select id="findUserWithOrdersById" resultMap="userWithOrdersResultMap">SELECT*FROMtb_user uLEFT JOIN tb_order o ON u.id = o.uidWHEREu.id = #{id}</select>
3.3 关联查询总结
正常封装使用resultMap
一对一封装使用association
一对多封装使用collection
四、动态SQL【重点】
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
自己话理解: 帮助我们拼接SQL
常见的动态SQL语法
- SQL片段(官方不是在动态SQL章节)
- where , if
- set
- trim
- foreach
4.1 SQL片段
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。
自己的话: 减少代码重复,主要用于抽取字段,表名等
<!-- 将重复的SQL代码抽取成SQL片段,以供复用 --><sql id="userField">id,username,password,phone,create_time,money,sex</sql><select id="findAll" resultType="User">select<!-- 引入片段 --><include refid="userField"/>fromtb_user</select>
4.2 if
if就是用来判断,主要用于判断要不要拼接对应的条件语句
-- 需求:查询用户,条件是money=1000,如果密码不为空,也根据密码查 select * from tb_user where money = 1000 select * from tb_user where money = 1000 and password= '123456'
UserMapper.java接口方法
public interface UserMapper {/*** 演示if动态sql*/List<User> findByMap(HashMap<String,Object> map);}
UserMapper.xml
<select id="findByMap" resultMap="userResultMap">select<include refid="userField"/>fromtb_userwheremoney = #{money}<if test="password != null and password != ''">and password = #{password}</if></select>
测试
/*** if动态sql*/
@Test
public void showIf() {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);HashMap<String, Object> map = new HashMap<>( );map.put("money",1000);List<User> list = userMapper.findByMap(map);for (User user : list) {System.out.println(user );}
}
4.3 where
如果说只有if,可能会出现这么一种情况
SELECT * FROM tb_user WHERE
多出一个where关键词!!
所以我们需要一个智能的,有条件时帮我们拼接where关键词,没有条件查询时,不拼接where
<!-- 测试if的缺点 --><select id="findUserBySex2" resultType="User">select<include refid="userField"/>fromtb_user<where><if test="sex != null">sex = #{sex}</if></where></select>
所以一般会where和if一起用
4.4 set
用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
UserMapper.java接口方法
public interface UserMapper {int updateUser(User user);
}
UserMapper.xml
<!-- set完成动态更新 --><update id="updateUser">update tb_user<!-- set标签自动拼接SET关键词 --><set><!-- 会自动过滤最后一个, --><!-- 特别注意,因为判断条件是!=null,基本不可能为null,所以将基本类型变为包装类 --><if test="username != null">username = #{username},</if><if test="password != null">password = #{password},</if><if test="phone != null">phone = #{phone},</if><if test="createTime != null">create_time = #{createTime},</if><if test="money != null">money = #{money},</if><if test="sex != null">sex = #{sex},</if></set>where id = #{id}</update>
测试
@Testpublic void testUpdate(){UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = new User( );user.setId(1);// 只更新这个2字段,其他字段不动user.setUsername("QF");user.setPassword("qf666");int i = mapper.updateUser(user);System.out.println(i > 0?"OK":"ERR" );// 增删改要提交sqlSession.commit();}
4.5 foreach
场景: 批量删除
delete from tb_user where id in (1,2,3,...);
String sql = "delete from tb_user where id in ("; int iMax = idsArr.length - 1;// 最大下标 for (int i = 0; i < idsArr.length; i++) {int id = idsArr[i];sql += id;if (i != iMax) {sql += ",";} else {sql += ")";} }
UserMapper.java
public interface UserMapper {// 为了演示动态sql foreachint deleteBatch(List<Integer> ids);
}
UserMapper.xml
<!-- 动态sql foreach --><delete id="deleteBatch">delete from tb_userwhere id in<!--<foreach>开始循环,取出集合中的数据collection,要遍历的集合,此处必须写list (或者可以写collection,arg0,不能写别的)item , 遍历得到结果,命名任意,但是下面#{}内的名字要和这里一致--><foreach collection="list" item="id" open="(" separator="," close=")">#{id} </foreach></delete>
测试
/*** 测试foreach*/@Testpublic void testForeach(){UserMapper mapper = sqlSession.getMapper(UserMapper.class);ArrayList<Integer> list = new ArrayList<>( );list.add(31);list.add(32);list.add(33);int i = mapper.deleteBatch(list);System.out.println("i = " + i);System.out.println(i > 0?"OK":"ERR" );// 增删改要提交sqlSession.commit();}
任务
使用项目中的表,重复1遍
合同加房屋实现多表联查
做笔记,写注释,画图标记
使用项目中的表,重复1遍
合同加房屋实现多表联查
做笔记,写注释,画图标记
相关文章:

day50_mybatis
今日内容 0 复习昨日 一、分页插件 二、ORM映射【重点】 三、多表联查 【重点】 四、动态SQL 【重点】 五、$和# 零、复习昨日 mybatis orm框架,作用于持久层,高效开发,只关注sql,其他不用关心 思考MyBatis到底帮你省了哪些事情? jdbc第四步sql自己编写之外,其他mybatis都做了…...
第十一届“创业江苏”科技创业大赛正式启动
为深入实施创新驱动战略, 推进高水平科技自立自强,强化企业创新主体地位,加速推动创新要素向企业集聚,促进科技和金融深度融合,优化科技创新创业生态,吸引优秀创业团队及企业到苏州创新发展,根据…...

EasyX实现简易贪吃蛇
📝个人主页:认真写博客的夏目浅石. 📣系列专栏:夏目的C语言宝藏 文章目录 前言一、头文件包含二、创建蛇与食物的结构体三、游戏的初始化四、游戏的绘画事件五、蛇的移动事件六、输入方向七、生成食物八、吃食物九、游戏失败的判定…...

Linux下ElasticSearch7.9.2安装配置(包含服务器配置、启动停止脚本、开放端口和elasticsearch-head插件的使用)
Linux下ElasticSearch7.9.2安装配置 前言1.下载安装1.1 使用wget的方式下载1.2 官网下载 2.上传到服务器并解压3.修改es配置文件3.1 es目录简介3.2 修改配置文件 4. 创建用户并赋权5. 服务器修改配置5.1 修改文件句柄数和线程数5.2 关闭swapping5.3 修改虚拟内存 6. 启动es6.1 …...

JS 之 事件Event对象详解(属性、方法、自定义事件)
一、Event对象 1、简介 事件event对象是指在浏览器中触发事件时,浏览器会自动创建一个event对象,其中存储了本次事件相关的信息,包括事件类型、事件目标、触发元素等等。浏览器创建完event对象之后,会自动将该对象作为参数传…...
65寸电视长宽多少厘米
65寸电视的长和宽分别是多少 65寸电视机尺寸是不确定的,要看电视的品牌和具体型号。一般来说,16:9屏幕比例下,65英寸电视的长宽分别为143.90厘米和80.94厘米。电视尺寸指的是电视屏幕对角线的长度,目前电视尺寸普遍以英…...

Python爬取影评并进行情感分析和数据可视化
Python爬取影评并进行情感分析和数据可视化 文章目录 Python爬取影评并进行情感分析和数据可视化一、引言二、使用requestsBeautifulSoup进行影评的爬取1、分析界面元素2、编写代码 三、情感分析1、数据预处理2、情感分析3、数据可视化 一、引言 前几天出了《航海王࿱…...

ubuntu22.04.2安装onlyoffice(不更改默认端口版)
目录 一、配置阿里源 二、postgresql数据库 (一)安装postgresql (二)创建postgresql数据库和用户 三、安装 rabbitmq 四、安装nginx-extras 五、安装ONLYOFFICE Docs (一)Add GPG key (…...

企业如何有效制定企业信息化发展规划?(附信息化模板)
如何有效制定企业信息化发展规划?企业信息化发展规划是一个宏大而又复杂的命题,这篇来掰开揉碎讲一下企业应该如何有效制定信息化发展规划。 这里不给大家灌鸡汤,也不给大家画大饼,就说些实在的。 如果你想找经验方法࿰…...

计算机网络填空题
我会写下自己的答案和理解 希望自己可用在学习中体会到快乐,而不是麻木。 1. 网络协议三要素中语义是指 需要发出何种控制信息,完成何种动作以及做出何种响应 1.在计算机网络中要做到有条不紊的交换数据,就必须遵守一些事…...

【HashMap】为什么用自定义的类做HashMap的Key时需要重写hashcode方法和equals方法
【HashMap】为什么用自定义的类做HashMap的Key时需要重写hashcode方法和equals方法 【一】为什么有这个问题【二】Object类的中的hashcode方法和equals方法【三】重写hashcode【四】重写equals方法【五】hashmap中使用hashcode和equals方法 【一】为什么有这个问题 因为HashMa…...
Flutter自定义对话框返回相关问题汇总
Flutter自定义对话框返回相关问题汇总,详细解释 Flutter是一款流行的移动应用开发框架,它提供了很多内置的对话框,但是有时候我们需要自定义对话框来满足特定需求。在使用自定义对话框时,可能会遇到一些问题,下面是一…...

002docker 安装
官网安装https://docs.docker.com/engine/install/ 系统要求 Centos7 Linux 内核:官方建议 3.10 以上查看Linux内核版本 用于打印当前系统的相关信息(内核版本号,硬件架构,主机名称和操作系统类型等 cat /proc/version uname -a 更新YUM源 生产环境中此步操作…...
软件工程师,全面思考问题很重要
为什么要全面思考问题 □ 在软件开发中,对一个问题思考得越全面,编写出的代码就会越严谨,出现bug的几率就越低;反之,如果没有对一个问题进行全面而深入的思考,编写出的代码就会漏洞百出,出现各种莫名其妙、无法复现的bug的几率也就急剧增加。 □ 软件就是数据加逻辑,数…...

1.Apollo部署-linux
一.官方文档 https://www.apolloconfig.com/#/zh/deployment/quick-start-docker 二.环境准备 1.MySql 5.6.51.单独服务器192.168.2.13 https://downloads.mysql.com/archives/installer/ 2.JDK 1.8.X https://www.oracle.com/java/technologies/downloads/ 三.Apollo部署…...

【HTML】form标签
<form> 标签用于创建 HTML 表单,它是用于收集用户输入的重要元素。表单可以包含各种输入字段、按钮和其他交互元素,用于向服务器发送用户输入数据。 下面是一个简单的 <form> 标签的示例: <form action"/submit-form&q…...

基于SPAD / SiPM技术的激光雷达方案
激光雷达(LiDAR)是一种测距技术,近年来越来越多地用于汽车先进驾驶辅助系统(ADAS)、手势识别和3D映射等应用。尤其在汽车领域,随着传感器融合的趋势,LiDAR结合成像、超声波、毫米波雷达,互为补足,为汽车提供全方位感知…...
使用MATLAB工具模拟单/双频GPS和载波相位差分GPS
第一部分:介绍和背景 在我们的日常生活中,全球定位系统(GPS)发挥了重要的作用。无论是在我们的手机中,还是在各种应用中,GPS都是实现精确位置定位的关键技术。然而,有时候我们可能需要对GPS进行…...
当社恐成为技术面试官
前言 在被不知道多少个面试官拒绝之后,毕业四年之际,我这个社恐也成为了一位面试官。至于社恐为什么能成为面试官,我想放到文末讲,感觉不是重点。 之前被面试,最讨厌的话就是:请简单介绍一下自己 我的内心…...

Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager
Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager 可能你已经知道,Jetpack Compose 默认不包含内置的ViewPager组件。然而,我们可以通过在 build.gradle 文件中添加 accompanist 库依赖,将 ViewPager 功能…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...