废话两句:这篇博客主要是总结记录工作中常用的东西,真正做到开箱即用、接地气。第一版记个流水帐吧,后面慢慢做性能比较。
虽然不能访问Youtobe这些东西,但是谷歌搜索和wiki还是没有什么问题的。对我而言,谷歌搜搜bug解决方案简直不要太美好。
格式化JSON数据:没装这个插件的话,JSON默认显示一大串字符串
外文官方文档必备佳品:遇到那么几个不认识的单词,鼠标选中就可以翻译,再也不用切网页。
原因很简单:慕课网的视频体验很好,既有PPT,又有清晰的代码展示,也有对应的资源下载。最重要的是,老师在认认真真讲课,而不是像某些视频课中一样东拉西扯,浪费时间。
B站上面的项目视频很多,质量还可以。缺点就是很多视频都是盗版,经常碰到缺一两集或者没有配套资源。有时候老师会瞎鸡巴扯,比较浪费时间,建议用来扩展知识面。
由于绝大部分新手或者工作一两年左右的开发都没有足够的耐心和能力去看完类似《Java编程思想》之类的经典书籍(如果工作游刃有余,看看这些经典肯定受益匪浅),下面我只推荐一些比较简单却很有必要认真看看的书:
不推荐项目使用SSM框架,因为配置项目真的太浪费时间了,会让人有种错觉:学了半天,就学了配些xml文件。使用Springboot开发起来很爽,主要体现在:
Springcloud是一套微服务框架,基于Springboot开发.对于初级程序员而言,公司使用Springboot还是Springcloud其实区别并不大.而且微服务拆分合理的话,甚至会比springboot开发起来更爽快:因为面对需求变更,可能只需要去重新组合一下现有的微服务,而不用重新开发.
常用的组件如下(这里仅作简要介绍,后面在Springcloud项目中详细介绍):
整体用法和SSM框架一致,常规使用MVC模式进行开发。
springboot
国外常用的框架:只是一个持久化规范,底层的实现基本是Hibernate。优点有如下几条:
缺点也很明显:
基于以上缺点,不少公司是JdbcTemplate和JPA混搭使用。废话不再多说,下面开始介绍JPA的基本用法,以及常用实现。
JPA使用步骤
注解 | 作用 |
---|---|
@Entity | 表明这是一个实体类 |
@Table | 当表名与类名不一致时,必须配置 |
@Id | 主键标识 |
@Column | 列名映射 |
@GenaratedValue | 主键自增 |
@UpdateTimestamp | 更新操作:自动更新时间 |
@OneToOne | 一对一映射 |
@OneToMany | 一对多映射 |
@ManyToOne | 多对一映射 |
@ManyToMany | 多对多映射 |
@JoinColumn | 主控方标明关联表的字段 |
@JoinTable | 标明此表为多对多关联表 |
@Transient | 不会映射到数据库 |
@Temporal | 调整时间精度 |
JPA实体类代码示例如下,特别注意要实现序列化接口:
@Data
@Entity(name= SystemTable.CMVS_TURNING_CHNNAL_DETAIL)
public class TurningChannelDetail implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "\"order\"")
private Integer order;
@ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name = "id",insertable = false,updatable = false)
private TurningInfo TurningInfo;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "domain_channelId", insertable = false, updatable = false)
@Where(clause = "IS_DELETE = 0")
private DeviceChannel DeviceChannel;
@Column(name = "update_time")
@org.hibernate.annotations.UpdateTimestamp
private Timestamp updateTime;
}
注意,失败原因可能如下:
包导的不对: import javax.persistence.*;
配置文件不对: spring.jpa.hibernate.ddl-auto=update或者yml缩进错误(jpa属于spring下一级,而不是datasource下一级)
注解写的不对:不要忘记@Entity
启动类位置不对:实体类和启动类应位于同一根目录
spring:
datasource:
url: jdbc:mysql://localhost:3306/jsonDemo
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
#支持自动建表
ddl-auto: update
show-sql: true
open-in-view: true
database: mysql
编写DAO层代码:继承JpaRepository
[{"id":"1","name":"yq","sex":"man"},{"id":"2","name":"yy","sex":"woman"}]
JSONArray objectArray=JSONArray.parseArray(jsonStr)
/JSONArray objectArray=jsonObject.getJSONArray("属性")
{"id":"1","name":"yq","sex":"man"}
JSONObject obj=JSONObject.parseObject(jsonStr)
/JSONObject obj=jsonArray.getJSONObject(i)
综合测试:前端发送一个含有ID数组的对象,后台需要ID的list,其代码实现如下:
//前端需要发送json格式,使用jsonStringfy方法;后端需要使用@RequestBody注解接收json字符串
//使用postman发送如下json字符串:
{
"alarmInfoIdList": [{
"id": 1
}, {
"id": 2
}]
}
//后端代码如下:
@Controller
@RequestMapping("/json")
@Slf4j
public class JsonController {
@ResponseBody
@RequestMapping(value = "/jsontoobject",method = {RequestMethod.POST})
public String jsonToObject(@RequestBody String jsonStr){
//字符串外面是{},故为json对象,使用JSONObject接收
JSONObject jsonObject=JSONObject.parseObject(jsonStr);
//而alarmInfoIdList属性外面是[],故为json数组,使用JSONArray接收
JSONArray jsonArray=jsonObject.getJSONArray("alarmInfoIdList");
List<String> list=new ArrayList<>();
for(int i=0;i<jsonArray.size();i++){
JSONObject object= jsonArray.getJSONObject(i);
list.add(object.getString("id"));
}
list.stream().forEach(System.out::println);
return "true";
}
}
//结果:
1
2
@Service
public class DeviceModelService {
@Autowired
private DeviceModelRepository deviceModelRepository;
@Transactional
public void saveAndFlush(String msg) throws Exception{
deviceModelRepository.deleteAll();
//注意使用JSONArray,则其JSON必须为数组形式,诸如:
//JSONArray: [{"id":"1","name":"yq","devType":"car"},{"id":"2","name":"yy","devType":"bike"}]
//JSONObject: {"id":"1","name":"yq","devType":"car"}
JSONArray arr = JSONArray.fromObject(msg);
for(int i=0; i<arr.size(); i++) {
JSONObject obj = arr.getJSONObject(i);
DeviceModel model = new DDeviceModel();
model.setId(obj.getInt("ID"));
model.setName(obj.getString("Name"));
model.setTypeId(obj.getInt("DevTypeID"));
model.setTypeName(obj.getString("DevTypeName"));
model.setVendorId(obj.getInt("DevVendorID"));
model.setVendorName(obj.getString("DevVendorName"));
model.setStreamAgent(obj.getInt("DevStreamAgent"));
deviceModelRepository.saveAndFlush(model);
}
}
}
在这里,我将不会赘述如何去搭建框架。原因非常简单:项目框架搭建只需要做一次,而且网上非常多的教程。最重要的是:企业开发时,直接给你设定好框架,你只是负责其中一个模块。
开发Vue项目之前,需要对下表概念有所理解
概念 | 理解 |
---|---|
template | 模板:即视图部分 |
data | 实例中的数据部分,需要数据时应在此处注册 |
vue实例 | 实例就是数据和模板的整合者 |
componet | 实际就是vue实例 |
概念 | 理解 |
---|---|
components | 子组件需要在父组件注册才能使用 |
computed | 计算属性:计算比较复杂的逻辑,自带缓存 |
watch | 侦听器 |
methods | 实例方法,可以在此操作data以及computed的数据 |
created | 实例创建时:初始化方法 |
mounted | 钩子函数:数据挂载时初始化参数 |
概念 | 理解 |
---|---|
v-text | 文本绑定,会自动转义 |
v-html | html绑定,不会自动转义 |
v-model:select | 双向绑定/表单输入绑定:主要用在input,textarea,select元素上 |
v-bind:id | 简写:id=’’ ‘’,属性/参数绑定,单向:data–>template |
v-on:click | 简写@click,事件绑定:绑定到特定方法,触发对应方法 |
v-if | 根据if条件判断是否实际渲染,当变化不频繁时使用 |
v-show | 更改display属性为none |
v-for | 遍历list中的元素,可以实现轮播图和动态表单等 |
事件修饰符 | .stop ,.prevent,.capture,.self,.once,.passive等等 |
概念 | 理解 |
---|---|
props | 子组件可以直接获取父组件中data对应的值 |
$emit | 子组件调用父组件的事件@click,将子组件的数据动态传递到父组件的方法中 |
$refs | 通过$refs可以直接调用子组件的方法和属性,但必须在mounted之后才能获取值 |
对于Vue组件而言,选择有很多,我这里优先选择iView或者Element.具体使用完全参考官方的API,重点关注组件的属性以及提供的事件(通常会有回调的数据,特别关注此类数据的流向: 组件 -->data/props).
前面其实已经有介绍各种数据的流向,这里做一个总结,让大家更直观的感受到数据的走向.
数据流向