SpringBoot 基础(二)
SpringBoot基础(二)
一、操作数据库
1. SpringBootJdbc
引入依赖 jdbc 和 mysql
SpringBoot默认支持的连接池策略,如果使用 jdbc 或者 jpa 就会自动连接连接池
- 优先寻找创建Tomcat连接池
- 如果没有Tomcat连接池,会查找创建HikariCP
- 如果没有HikariCP连接池,会查找创建dbcp
- 如果没有dbcp连接池,会查找创建dbcp2
- 可以使用spring.datasource.type属性指定连接池类型,比如其它的连接池 C3P0 或者 druid
application-jdbc.yml
#数据库jdbc连接url地址,serverTimezone设置数据库时区东八区
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
username: xxx
password: xxxxx
driver-class-name: com.mysql.jdbc.Driver
UserDao 接口
public interface UserService {
//获取全部用户数据
public List<User> getUserList();
//新增用户数据
public void createUser(User user);
//获取指定id用户信息
public User getUser(Long id);
//更新指定id用户信息
public void updateUser(Long id,User user);
//删除指定id用户
public void deleteUser(Long id);
}
UserDaoImpl
@Service
public class UserServiceImpl implements UserService { //SpringBoot提供的数据库操作类
@Autowired
JdbcTemplate jdbcTemplate; @Override
public List<User> getUserList() {
return jdbcTemplate.query("select * from users", new BeanPropertyRowMapper(User.class));
} @Override
public void createUser(User user) {
jdbcTemplate.update("insert into users(name,age)values(?,?)",user.getName(),user.getAge());
} @Override
public User getUser(Long id) {
final User user = new User();
/* jdbcTemplate.query("select * from users where id="+id,new RowCallbackHandler() {
* @Override
* public void processRow(ResultSet rs) throws SQLException {
* user.setId(id);
* user.setName(rs.getString("name"));
* user.setAge(rs.getInt("age"));
* }
* });
*/
return jdbcTemplate.queryForObject("select * from users where id=?",new BeanPropertyRowMapper(User.class),id);
return user;
} @Override
public void updateUser(Long id, User user) {
jdbcTemplate.update("update users set name=?,age=? where id=?",user.getName(),user.getAge(),id); } @Override
public void deleteUser(Long id) {
jdbcTemplate.update("delete from users where id=?",id);
} }
2. SpringBoot 整合 Mybatis
引入依赖。mybatis,mysql,druid。
配置 application.yml
#数据库jdbc连接url地址,serverTimezone设置数据库时区东八区
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
username: xxx
password: xxxxx
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #springboot整合mybatis
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.demo.domain
创建 实体bean、dao接口以及相应的 mapper 映射文件
3. SpringBott 使用JPA
1. JPA 介绍
- (Java Persistence(持久化) API):是注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
2. 优势
- 标准化:JPA 是 JCP 组织发布的 Java EE 标准之一,因此符合 JPA 标准的框架都提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。JPA的实现产品有HIbernate,TopLink,OpenJPA等等。
- 容器级特性的支持:JPA框架中支持大数据集、事务、并发等容器级事务。
- JPA简单易用,集成方便:JPA的主要目标之一就是提供更加简单的编程模型。只需要使用 javax.persistence.Entity进行注释。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成。
- 查询能力:JPA的查询语言(JPQL)是面向对象而非面向数据库的。而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
- 高级特性:JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
3. JPA 注解
注解 | 作用 |
---|---|
@Entity | 声明类为实体或表 |
@Table | 声明表名 |
@Basic | 指定非约束明确的各个字段 |
@Embedded | 指定类或它的值是一个可嵌入的类的实例的实体的属性 |
@Id | 指定的类的属性,用于识别(一个表中的主键) |
@GeneratedValue | 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值 |
@Transient | 指定的属性,它是不持久的,即:该值永远不会存储在数据库中 |
@Column | 指定持久属性栏属性 |
@SequenceGenerator | 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列 |
@TableGenerator | 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表 |
@AccessType | 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量 |
@JoinColumn | 指定一个实体组织或实体的集合。这是用在多对一和一对多关联 |
@UniqueConstraint | 指定的字段和用于主要或辅助表的唯一约束 |
@ColumnResult | 参考使用select子句的SQL查询中的列名 |
@ManyToMany | 定义了连接表之间的多对多一对多的关系 |
@ManyToOne | 定义了连接表之间的多对一的关系 |
@OneToMany | 定义了连接表之间存在一个一对多的关系 |
@OneToOne | 定义了连接表之间有一个一对一的关系 |
@NamedQueries | 指定命名查询的列表 |
@NamedQuery | 指定使用静态名称的查询 |
4. JPA入门
加入依赖jpa、mysql、druid(非必须,自带有连接池)、lombok(非必须)。
配置 application.yml
spring:
datasource:
url : jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
type : com.alibaba.druid.pool.DruidDataSource
username : xxx
password : xxxx
driver-class-name : com.mysql.cj.jdbc.Driver
jpa:
hibernate:
# create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表。
# create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
# validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
# update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
ddl-auto: update
show-sql: true
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Person {
@Id
@GeneratedValue
private Long id; @Column(name = "name", nullable = true, length = 20)
private String name; @Column(name = "age", nullable = true, length = 4)
private int age; @Column(name = "password", nullable = true, length = 20)
private String password; @OneToMany(mappedBy = "personId", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Dog> dogs;
}
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {
@Id
@GeneratedValue
private Long id; private String name; private Long personId;
}
5.自定义查询
- 我们dao 需要继承 JpaRepository<Person, Long>,Person 为实体类,Long为主键类型。这个类的内部已经定义好了单表数据操作语句,可以直接使用。但是有的时候,根据业务需求需要自定义一些数据操作,这就需要了解一下方法命名规则,根据方法名会自动生成相应的JPQL。
关键词 | 样例 | SQL符号 | 对应JPQL 语句片段 |
---|---|---|---|
And | findByLastnameAndFirstname | and | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | or | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | = | … where x.firstname = ?1 |
Between | findByStartDateBetween | between xxx and xxx | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | < | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | <= | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | > | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | >= | … where x.age >= ?1 |
After | findByStartDateAfter | > | … where x.startDate > ?1 |
Before | findByStartDateBefore | < | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | is null | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | is not null | … where x.age not null |
Like | findByFirstnameLike | like | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | not like | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | like 'xxx%' | … where x.firstname like ?1(parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | like 'xxx%' | … where x.firstname like ?1(parameter bound with prepended %) |
Containing | findByFirstnameContaining | like '%xxx%' | … where x.firstname like ?1(parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | order by | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | <> | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | in() | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection ages) | not in() | … where x.age not in ?1 |
TRUE | findByActiveTrue() | =true | … where x.active = true |
FALSE | findByActiveFalse() | =false | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | upper(xxx)=upper(yyyy) | … where UPPER(x.firstame) = UPPER(?1) |
6. 数据访问层接口
除了使用按照规则定义方法为,还可以使用 JPQL。
查询使用
@Query
,如果使用原生sql语句,需要使用@Query(value="原生sql",nativeQuery=true)
。对表更新和删除需要使用
@Modifying、@Transactional、@Query
的注解组合。对于
@Transactional
来说,readOnly=true
表明所注解的方法或类只是读取数据。默认值就是这个。readOnly=false
表明所注解的方法或类是增加,删除,修改数据。事物隔离级别
- 隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:
- TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。
- TransactionDefinition.ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别。它允许令外一个事务可以看到这个事务未提交的数据,这种隔离级别会产生脏读,不可重复读和幻像读。
- TransactionDefinition.ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。避免脏读。但是不可重复读和幻读有可能发生
- TransactionDefinition.ISOLATION_REPEATABLE_READ:避免脏读和不可重复读,但是幻读有可能发生。
- TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
事务传播行为
- 事务传播行为指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。TransactionDefinition定义了七种传播行为:
- TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
- TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起
- TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
- TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
- TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 TransactionDefinition.PROPAGATION_REQUIRED。
在进行分页的时候,在方法最后加上一个参数 Pageable。
// JpaRepository 中已经定义有关于单表的操作方法
public interface PersonRepository extends JpaRepository<Person, Long> {
//查询指定用户姓名的用户
public Person findByName(String name);
//查询指定用户姓名的用户
public Person findByNameAndPassword(String name, String password);
//查询包含指定名字的用户
public List<Person> findByNameContaining(String name);
// 排序查询,返回list集合。Sort 在controller层中使用 new Sort(Sort.Direction.fromString("desc"),"id")
public List<Person> findByNameContaining(String name, Sort sort);
//分页查询, 查询计算元素总个数、总页数,数据多的情况下,代价是昂贵的。Pageable 在controller层中使用PageRequest.of(page, size,new Sort(Sort.Direction.fromString("desc"),"id"))
public Page<Person> findByNameContaining(String name , Pageable pageable);
//分页查询,返回的是一个片段,它只知道下一片段或者上一片段是否可用。
public Slice<Person> getByNameContaining(String name, Pageable pageable);
//查询指定用户姓名的用户。使用 :name 作为占位符,需要使用 @Param 注解
@Query("select p from Person p where p.name = :name")
public Person getPerson(@Param("name") String name);
//用户登录验证。使用方法中的参数位置作为占位符
@Query("select p from Person p where p.name = ?1 and p.password= ?2")
public Person login(String name, String password);
//模糊查询用户名里面包含指定字符
@Query("select p from Person p where p.name like %:name%")
public List<Person> getNamesLike(@Param("name") String name);
//查询密码位数是5位数的全部用户,使用mysql原始sql语句进行查询
@Query(value="select * from person where length(password)=5",nativeQuery=true)
public List<Person> getPasswordisFive();
@Modifying
@Transactional(readOnly = true)
@Query("update Person p set p.name=?2 where p.id=?1")
public int UpdateName(Long id, String name);
@Modifying
@Transactional
@Query("delete from Person p where p.name=?1")
public int DeleteName(String name);
//查询指定用户名称,按照id降序排序第一条记录
Person findFirstByNameOrderByIdDesc(String name);
//模糊查询指定用户名称,按照id降序排序前10条记录
public List<Person> findFirst10ByNameLikeOrderByIdDesc(String name);
//查询指定用户名称,按照id升序排序第一条记录
Person findTopByNameOrderByIdAsc(String name);
//模糊查询指定用户名称,按照id升序排序前10条记录
public List<Person> findTop10ByNameLikeOrderByIdAsc(String name);
@Query("select p from Person p join p.dogs d where p.id = ?1")
public Person findPerson(Long id);
}
二、使用 Thymeleaf 模版引擎
介绍:Thymeleaf是xml/xhtml/html5的模板引擎。Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
集成 Thymeleaf
添加依赖 thymeleaf
修改配置 application.yml
spring:
#开始thymeleaf设置
thymeleaf:
#禁用模板缓存
cache: false
为模版注入数据
String message = "Hello, Thymeleaf!";
model.addAttribute("message", message); User u = new User();
u.setId(1L);
u.setName("德鲁伊");
u.setAge(18);
model.addAttribute("user", u); Map<String,Object> map=new HashMap<>();
map.put("src1","1.jpg");
map.put("src2","2.jpg");
model.addAttribute("src", map); List<User> list=new ArrayList<User>();
list.add(u1);
list.add(u2);
model.addAttribute("userList", list); model.addAttribute("href", "http://www.ujiuye.com"); model.addAttribute("flag", "yes");
model.addAttribute("menu", "admin");
model.addAttribute("manager", "manager"); //日期时间
Date date = new Date();
model.addAttribute("date", date);
//小数的金额
double price=128.5678D; model.addAttribute("price", price); //定义大文本数据
String str="Thymeleaf是Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。\r\n" +
"Thymeleaf的主要目标是提供一种优雅和高度可维护的创建模板的方式。为了实现这一点,它建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板被用作设计原型。这改善了设计的沟通,弥补了设计和开发团队之间的差距。\r\n" +
"Thymeleaf也从一开始就设计了Web标准 - 特别是HTML5 - 允许您创建完全验证的模板,如果这是您需要的\r\n" ; model.addAttribute("strText", str); //定义字符串
String str2="JAVA-offcn";
model.addAttribute("str2", str2);
在 resource/templates 下创建模版 index.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="#{title}"></title>
</head>
<body>
<h1 th:text="${message}"></h1>
<hr/> </br>
<img th:src="${src.src1}">
</br>
<img th:src="${src.src2}"/>
</br>
<span th:text="${user.id}"></span>
<span th:text="${user.name}"></span>
<span th:text="${user.age}"></span>
<hr/> <table>
<tr th:each="user,iterStat : ${userList}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${iterStat.index}">index</td>
<td th:text="${iterStat.count}">index</td>
</tr>
</table>
<hr/> <!-- 给标签赋值 th:text -->
<h1 th:text="${userName}"></h1>
<!-- 给属性赋值 th:value、th:属性名称 -->
<input type="text" name="names" th:value="${userName}"/>
</br>
<em th:size="${userName}"></em>
<!-- 字符串拼接 -->
<span th:text="'欢迎来:'+${userName}+'学习!'"></span>
</br>
<!-- 字符串拼接,方式2 -->
<a th:href="${href}"><span th:text="|欢迎来:${userName}学习!|"></span></a>
<hr/> <!-- th:if 条件成立就显示 -->
<h1 th:if="${flag=='yes'}" >中公教育</h1>
<!-- th:unless 条件不成立就显示 -->
<h1 th:unless="${flag=='no'}" >优就业</h1>
<!-- switch选择语句 -->
<div th:switch="${menu}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="${manager}">User is a manager</p>
</div>
<hr/> <!-- 把片段的内容插入到当前位置 -->
<div th:insert="~{footer :: copy}"></div>
</br>
<!-- 使用片段的内容替换当前标签 -->
<div th:replace="~{footer :: copy}"></div>
</br>
<!-- 保留自己的主标签,不要片段的主标签 (官方3.0后不推荐) -->
<div th:include="~{footer :: copy}"></div>
<hr/> 时间:<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}">4564546</span></br>
金额:<span th:text="'¥'+${#numbers.formatDecimal(price, 1, 2)}">180</span> </br>
<!-- # 这里的含义是 如果 atc.text 这个变量多余200个字符,后面显示... -->
<p th:text="${#strings.abbreviate(strText,60)}">内容内容内容</p> <!-- 判断字符串是否为空 -->
<span th:if="${!#strings.isEmpty(str2)}">字符串str2不为空</span></br>
<!-- 截取字符串,指定长度 -->
<span th:text="${#strings.substring(str2,0,4)}">字符串str2的值</span>
<hr/> <form class="form-horizontal" th:action="@{/manageruser/edit}" th:object="${user}" method="post">
<input type="hidden" name="id" th:value="*{id}" />
<div class="form-group">
<label for="name" class="col-sm-2 control-label">name</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" id="name" th:value="*{name}" placeholder="name"/>
</div>
</div>
<div class="form-group">
<label for="age" class="col-sm-2 control-label">age</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="age" id="age" th:value="*{age}" placeholder="age"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" value="Submit" class="btn btn-info" />
<a href="/manageruser/" th:href="@{/manageruser/}" class="btn btn-info">Back</a>
</div>
</div>
</form>
</body>
</html>
<!-- footer.html-->
<body>
<h1 th:fragment="copy">
© 1999-2018 Offcn.All Rights Reserved
</h1>
</body>
SpringBoot 基础(二)的更多相关文章
- (二)SpringBoot基础篇- 静态资源的访问及Thymeleaf模板引擎的使用
一.描述 在应用系统开发的过程中,不可避免的需要使用静态资源(浏览器看的懂,他可以有变量,例:HTML页面,css样式文件,文本,属性文件,图片等): 并且SpringBoot内置了Thymeleaf ...
- SpringBoot基础实战系列(二)springboot解析json与HttpMessageConverter
SpringBoot解析Json格式数据 @ResponseBody 注:该注解表示前端请求后端controller,后端响应请求返回 json 格式数据前端,实质就是将java对象序列化 1.创建C ...
- SpringBoot基础系列-SpringCache使用
原创文章,转载请标注出处:<SpringBoot基础系列-SpringCache使用> 一.概述 SpringCache本身是一个缓存体系的抽象实现,并没有具体的缓存能力,要使用Sprin ...
- 视频作品《springboot基础篇》上线了
1.场景描述 第一个视频作品出炉了,<springboot基础篇>上线了,有需要的朋友可以直接点击链接观看.(如需购买,请通过本文链接购买) 2. 课程内容 课程地址:https://ed ...
- SpringBoot 基础(一)
目录 SpringBoot 基础(一) 一.简介 二.重要注解 三.基本应用开发 1. lombok的使用 2. SpringBoot 的参数传递 3. 对象参数校验 4. 静态资源 四.Spring ...
- SpringBoot基础篇-SpringBoot快速入门
SpringBoot基础 学习目标: 能够理解Spring的优缺点 能够理解SpringBoot的特点 能够理解SpringBoot的核心功能 能够搭建SpringBoot的环境 能够完成applic ...
- 【SpringBoot 基础系列】实现一个自定义配置加载器(应用篇)
[SpringBoot 基础系列]实现一个自定义配置加载器(应用篇) Spring 中提供了@Value注解,用来绑定配置,可以实现从配置文件中,读取对应的配置并赋值给成员变量:某些时候,我们的配置可 ...
- SpringBoot基础实战系列(一)整合视图
SpringBoot整合freemarker 1.添加依赖:springboot基本上是无缝衔接,基本上只需要添加对应的依赖,不需要或者做很少量的配置即可 注:对于springboot项目的创建此处不 ...
- SpringBoot基础实战系列(三)springboot单文件与多文件上传
springboot单文件上传 对于springboot文件上传需要了解一个类MultipartFile ,该类用于文件上传.我此次使用thymeleaf模板引擎,该模板引擎文件后缀 .html. 1 ...
随机推荐
- 0 != null 为什么报指针?
大家好,这是我第一次写博客,来分享我平时工作中遇到的问题及平时学习的技术,如果有写的不好或者不对的地方还望大家能够指出和包涵. 那么接下来就开始说下我工作中遇到的这个问题,我写了一个test,如下: ...
- 前后端分离-Restful最佳实践
前后端分离-Restful最佳实践 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Android端项目测试
目录 一.概述 二.使用工具 三.测试 1.测试主要的两大功能 进入主界面,测试排行榜查看功能是否能运行 测试83端口打卡能否运行 修改个人信息已经注册功能 2.测试参数是否正确 3.测试刷新能否使用 ...
- centos服务器部署flask项目。
已安装的环境nginx,python3,mysql,uwsgi,virtualenv 1,创建虚拟环境 virtualenv -p python3 myblog 2,进入虚拟环境 source myb ...
- php观察者模式(observer pattern)
... <?php /* The observer pattern implements a one-too-many dependency between objects. The objec ...
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
- linux 指定用户 启动 程序
sudo -H -u {username} /bin/bash -c "python test.py &" "&" 后台运行指令 本人亲测可用 ...
- Windows:安装Python2.7、3.6与共存,安装pycharm
Windows:安装Python2.7.3.6与共存,安装pycharm 目录: 1.下载Python2.7.Python3.6 2.安装Python2.7 3.安装Python3.6 4.安装破解p ...
- classpath环境变量解惑
只有使用低于JDK1.5版本的JDK时,才需要设置classpath环境变量. 因为早期版本的JDK没有设计在当前路径下搜索Java类的功能,而且编译和运行java程序时还需要JDK的lib路径下的d ...
- zy的日志报表执行有问题。crontab显示执行了任务,代码中应该有问题
crontab定时任务在日志记录中是执行了 但是在执行脚本的过程中报错了, 找不到问题原因,以后也要在脚本中加入日志记录, 但是奇怪的是在中午和晚上是正常的, 应该是那个时间段的判断逻辑有问题,导致程 ...