记一些问题
来源:互联网 发布:2016网络自制剧排行榜 编辑:程序博客网 时间:2024/06/05 06:42
记一些问题
- 记一些问题
- 单词收录
- 快捷键收录IDEA
- 用户账户-自然主键
- 基于Bootstrap的分页工具类
- PathVariable
- 地址通配符优先级
- 继承映射 Mapping inheritance
- Table per class hierarchy
- Table per subclass with joins
- Mixing inheritance strategies 混合继承策略
单词收录
discriminate 分辨,辨别hierarchy 等级制度,分层inheritance 继承polymorphism 多态implicit 含蓄的,不严明的,隐式的explicit 明显的normalize 规范化, 使标准化
快捷键收录(IDEA)
Ctrl+Shift+t 生成测试类Shift+F10 运行测试类的方法Ctrl+U 转到父类Crtl+B 光标跳转(跳到哪里?看情况了)
2017-4-13
用户/账户-自然主键
@Entity@Table(name="peoples")class People { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long pid; @NaturalId(mutable=true) @Column(nullable=false) private String name; @Column(nullable=false, unique=true) private String email; private String password; //头像 String avatar;}
//这里自然主键的设置有什么意义呢?查询会有优化吗?…
可能是这样的,主键Id一般是不知道的,查询时,使用条件查询如where name=”” 或者 email=”“,性能效率不高,所以这里就将name,设置为自然主键,SQL执行顺序为先查找pid,然后再查找用户
这里只是定义了一个自然主键, 那么能否定义多个自然主键呢?
用户登录时,能够使用用户名/邮箱登录,如果邮箱也能设为自然主键,那么不论哪种方式?查询效率应该都是很高的。
多个主键也是可以的,但是查询时,如果有多个自然主键时,只使用一个查询,会出现问题.
如下图:
使用以下的方式(使用所有自然主键来查询),不会出现问题,但明显与需求不一致了…
//这里查询时,只使用name是不行的...public People findByName(String name) { Optional<People> option = currentSession().byNaturalId(People.class).using("name", name).using("email", "1849901944@qq.com").loadOptional(); if(option.isPresent()) { People people = option.get(); log.info(people); return people; } return null; }
?有没有别的办法内,这里就不知道了..
2017-4-14
Spring MVC 如何从一个控制器跳转到另一个控制器?
在返回的路径地址前加上forward:|reddirect:
来选择是转发还是重定向
如果重定向/转发时,后缀有中文出现的话,最终浏览器地址栏中会出现中文乱码
这时需要使用URLEncoder来将编码修改为utf-8
@PostMapping("/login")public String login(People people) throws UnsupportedEncodingException { log.info(people); //people = peopleService.findByName(people.getName()); if(people == null) return "/login"; else { return String.format("redirect:/people/%s", URLEncoder.encode(people.getName(), "utf-8")); //return "forward:/people/" + people.getName(); }}
用户信息模块想要实现如下的功能:
对于形如people/{params}通配符形URL
- 如果params匹配正则表达式[0-9a-b_\u4e00-\u9fa5]*, 则将本参数理解为用户名
- 否则理解为要列举所有用户(分页)。符合page-[0-9]*进行分页查询, 若后缀能够解析成整数,则按照具体页数查询,否则默认从第一页开始查询
不如这样:
- 参数中有”-“,我们就选择使用分页处理,具体页数从参数中获取,默认为1,每页显示大小默认为20
- 没有“-”出现就当成用户处理,这时我们从数据库中查找,有?显示用户信息:用户不存在
<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><c:set var="request" value="${pageContext.request}"/><c:set var="path" value="${request.contextPath}"/><c:set var="basePath" value="${request.scheme}://${request.serverName}:${request.serverPort}${path}/"/><!--上面这一个可能会出问题 request.scheme为空, 这就不好办了-->//感觉与下面联合起来使用情况好些<c:set var="basePath" value="<%=basePath%>"/>
2017-4-15
基于Bootstrap的分页工具类
需求:正常情况下,需要在当前页左边右边分别有3个候选页,当然也有首页 上一页 下一页 尾页
特殊情况下:
- currentPage = 1(第一页/首页) 不显示首页与上一页,显示: 1 2 3 4 下一页 尾页
- 1<= currentPage <= 3时, 左边候选个数=currentpage-1;
- total-3<=currentPage <= total时, 右边候选个数=total-currentPage;
public class Page<T> { /*候选个数:左边右边都为3*/ private final static int CANDICATES_SIZE = 3; private List<T> valueList = new ArrayList<T>(); /*尾页*/ private int endPage; /*上一页*/ private int prevPage; /*下一页*/ private int nextPage; /*当前页*/ private int currentPage; /*显示候选页*/ private int[] candicates; public Page(int currentPage,int rows, int total, List<T> valueList) { this.currentPage = (currentPage < 1) ? 1 : currentPage; this.valueList = valueList; endPage = (int)((double)total/rows + 0.5); nextPage = currentPage + 1; prevPage = currentPage - 1; int left = currentPage > CANDICATES_SIZE ? CANDICATES_SIZE : currentPage-1; int startPage = currentPage - left; int right = (currentPage + CANDICATES_SIZE) < endPage? CANDICATES_SIZE : endPage-currentPage; int len = left + right + 1; candicates = new int[len]; for(int i = 0; i < len; i ++) { candicates[i] = startPage + i; } }}
@PathVariable
这里讲一下@PathVariable,灵活使用确实能够增加开发效率
昨天我将用户列表、用户信息的链接都放到了people/{params}这个通配符里,然后在方法里面判读是列举用户,还是查看单个用户…感觉这样耦合性会有点高,如果现在又要添加一种新的链接类型,那么又要在这个方法里修改了。
今天突然想到Spring中还有这样一种用法:people/page-{page}, 那么含有page-前缀的会被优先匹配到这个地址通配符,显示用户列表,而单个用户的信息,则可以这样people/{name}。
地址通配符优先级
当一个URL地址能够匹配多个地址通配符时,那么是使用哪一个进行匹配呢?
- 地址通配符中变量越少、统配符号(*)越少的 优先级高。如:
/hotels/{hotel}/*
有一个URL变量和一个统配符号*, 会比/hotels/{hotel}/**
优先考虑 - 如果URL变量、统配符号(*)相同, 那么长的的会被优先考虑。如:
/foo/bar*
会比/foo/*
优先考虑。
2017-04-16
继承映射 Mapping inheritance
三种方式(158)
- 所有类都在一个表中,通过设置一个字段(
@DiscriminatorColumn
)来进行区分(@DiscriminatorValue
) - 每一个类都在一个表中,表之间有主从关系,子类的查询需要查询多个表
- 每一个具体类(子类)对应一个表
Table per class hierarchy
@Entity@Table(name="articles")@DiscriminatorColumn(name="type")@DiscriminatorValue("article")public class Article { @Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //发表作者 @JoinColumn(name = "authorid") @ManyToOne(cascade = CascadeType.REFRESH) private People author; //内容 @Lob private String context; //发表时间 @Temporal(value= TemporalType.TIMESTAMP) private Date postTime; //setter 和 getter 略}
@Entity@DiscriminatorValue("question")public class Question extends Article { private String title;}
@Entity@DiscriminatorValue("reply")public class Reply extends Reply {}
最終結果如下:
这种方式,多态通过一种非规范化的数据库模式来实现。通过一个基于行的识别器来区分超类/子类。
Table per subclass with joins
@Entity@Table(name="articles")@Inheritance(strategy = InheritanceType.JOINED)public class Article { @Id @Column(name="aid") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long aid; //发表作者 @JoinColumn(name = "authorid") @ManyToOne(cascade = CascadeType.REFRESH) private People author; //内容 @Lob private String context; //发表时间 @Temporal(value= TemporalType.TIMESTAMP) private Date postTime;}
@Entity@Table(name="questions")public class Question extends Article { private String title;}
@Entity@Table(name="replies")@PrimaryKeyJoinColumn(name="rid")public class Reply extends Article {}
细心的人可能会发现Reply
类要比Question
类多了点东西…
结果如下:
#自动建表SQL语句Hibernate: create table articles ( aid bigint not null auto_increment, context longtext, postTime datetime, authorid bigint, primary key (aid) )Hibernate: create table questions ( title varchar(255), aid bigint not null, primary key (aid) )Hibernate: create table replies ( rid bigint not null, primary key (rid) )Hibernate: alter table articles add constraint FKj05wy4m9xv8nqjnscbno7i2v5 foreign key (authorid) references peoples (pid)Hibernate: alter table questions add constraint FKfnjmh8itrc1ri408e9u8nij8x foreign key (aid) references articles (aid)Hibernate: alter table replies add constraint FK8api2vr7qnl449l6t4cy75k1x foreign key (rid) references articles (aid)
从这里可以看出两个派生类的外键(引用基类主键)的名字是不同,使用@PrimaryKeyJoinColumn(name="rid")
就可以自定义字类的外键名,否则默认外键名和父类的主键是一样的···
Mixing inheritance strategies 混合继承策略
这种方式,就是将前两种方式结合起来使用。先上图(当然不是我画的):
相当于,在第一种情况下,将一个子类抽取出来,放到第二个表中…
@Entity@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@Table(name="articles")@DiscriminatorColumn(name="type")@DiscriminatorValue("article")public class Article { @Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //发表作者 @JoinColumn(name = "authorid") @ManyToOne(cascade = CascadeType.REFRESH) private People author; //内容 @Lob private String context; //发表时间 @Temporal(value= TemporalType.TIMESTAMP) private Date postTime;
@Entity@DiscriminatorValue(value = "reply")public class Reply extends Article {}
@Entity@DiscriminatorValue("question")@SecondaryTable(name="questions",pkJoinColumns = @PrimaryKeyJoinColumn(name = "qid"))public class Question extends Article { @Column(table = "questions", nullable = false) private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}
#自动建表Hibernate: create table articles ( type varchar(31) not null, id bigint not null auto_increment, context longtext, postTime datetime, authorid bigint, primary key (id) )Hibernate: create table questions ( title varchar(255) not null, qid bigint not null, primary key (qid) )Hibernate: alter table articles add constraint FKj05wy4m9xv8nqjnscbno7i2v5 foreign key (authorid) references peoples (pid)Hibernate: alter table questions add constraint FKast1b4f96nx5mjj4efws06nen foreign key (qid) references articles (id)
#Article添加2017-04-16 14:48:24,320 INFO [main] impl.BaseDaoImpl (BaseDaoImpl.java:40) - Save a entity:class community.entity.ArticleHibernate: insert into articles (authorid, context, postTime, type) values (?, ?, ?, 'article')#Question添加2017-04-16 14:48:24,436 INFO [main] impl.BaseDaoImpl (BaseDaoImpl.java:40) - Save a entity:class community.entity.QuestionHibernate: insert into articles (authorid, context, postTime, type) values (?, ?, ?, 'question')Hibernate: insert into questions (title, qid) values (?, ?)#Reply添加2017-04-16 14:48:24,564 INFO [main] impl.BaseDaoImpl (BaseDaoImpl.java:40) - Save a entity:class community.entity.ReplyHibernate: insert into articles (authorid, context, postTime, type) values (?, ?, ?, 'reply')
单个表的话,查询时,则只需要查询一个表就可以了,但是,这种方式会浪费空间,表中有许多的空字段..特别是子类基因突变比较的情况下(用继承,可能都会有点鸡肋)…
多个表的话,查询时,可能需要查询多个表的数据,增加查询时间,但是,这种方式很好的体现了面向对象的性质,多态和继承,另一方面也减少了空间的浪费。
第三种方式,则可以说是以上方式的混血儿,一定程度上,减少了空间,个别子类的查询只需要查询一个表就够了。
那就根据具体情况来选择使用哪种策略吧…
- 记一些问题
- 一些问题。。。
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 一些问题
- 记boost process的一些问题
- requests模块学习
- 跟着Andrew Ng挑战Machine Learning(第二周):多元线性回归+特征缩放
- hdu 2159 FATE
- 同步,异步,阻塞,非阻塞 和 几种网络模型
- 洛谷 2023_[AHOI2009]维护序列_线段树
- 记一些问题
- codeforces 792 B. Counting-out Rhyme (模拟链表||约瑟夫环)
- eclipse 面包屑开关
- ios xcode 字体大全
- 学习笔记:SAE TensorFlow代码
- Erlang/OTP: 基于 Behaviour 的回调函数【转】
- A1063.Set Similarity
- 页面的分页(对之前上传的的代码的一种补充)
- Linux(2)简单的导航指令(下)绝对路径和相对路径