Online Judge(OJ)搭建——3、MVC架构
Model
Model 层主要包含数据的类,这些数据一般是现实中的实体,所以,Model 层中类的定义常常和数据库 DDL 中的 create 语句类似。
通常数据库的表和类是一对一的关系,但是有的时候由于需求变化或者方便起见,Model 层的类有时不和数据库中表相互对应。比如面向对象之组合属性,在 Java 中可以用一个类组合另一个类,表示测试信息、对应多组测试用例的组合,(正常情况下,应该是一张表而不是两张表),而数据库是用两张表存储数据,利用外键关系表示测试信息、对应多组测试用例的关系。
由于数据繁多,为了简化对象的映射,不使用JDBC,而采用持久化框架 MyBatis。
MyBatis 首先需要配置数据源:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- property from external resources -->
<properties resource="config/mybatis/applications.properties"/>
<!-- settings -->
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="false" />
<setting name="autoMappingBehavior" value="PARTIAL" />
<setting name="defaultExecutorType" value="SIMPLE" />
<setting name="defaultStatementTimeout" value="25000" />
<setting name="safeRowBoundsEnabled" value="false" />
<setting name="mapUnderscoreToCamelCase" value="false" />
<setting name="localCacheScope" value="SESSION" />
<setting name="jdbcTypeForNull" value="OTHER" />
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode ,toString" />
-->
</settings>
<!-- type aliases(full class name -> simple class name) -->
<typeAliases>
<!--
<typeAlias alias="Student" type="com.mybatis3.domain.Student" />
-->
<package name="per.piers.onlineJudge.model"/>
</typeAliases>
<!-- type handlers -->
<typeHandlers>
<typeHandler handler="per.piers.onlineJudge.handler.SexTypeHandler" javaType="per.piers.onlineJudge.model.Sex"
jdbcType="BOOLEAN"/>
</typeHandlers>
<!-- environment -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<environment id="production">
<transactionManager type="MANAGED"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/jdbc/mybatis"/>
</dataSource>
</environment>
</environments>
<!-- mappers location -->
<mappers>
<!--
<mapper url="file:///D:/mybatisdemo/app/mappers/TutorMapper.xml" />
<mapper class="com.mybatis3.mappers.TutorMapper" />
-->
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/QuestionMapper.xml"/>
<mapper resource="mapper/CategoryMapper.xml"/>
<mapper resource="mapper/TestDataMapper.xml"/>
<mapper resource="mapper/TestInfoMapper.xml"/>
<mapper resource="mapper/ScoreMapper.xml"/>
<mapper resource="mapper/AdvisorMapper.xml"/>
</mappers>
</configuration>
之后创建工厂对象,再用它创建数据访问对象(DataAccessObject,DAO):
@Bean
public SqlSessionFactory sqlSessionFactory() throws IOException {
ClassLoader classLoader = RootConfig.class.getClassLoader();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(classLoader.getResourceAsStream("config/mybatis/mybatis-config.xml"));
return sqlSessionFactory;
} @Autowired
@Bean
public DataAccessObject dataAccessObject(SqlSessionFactory sqlSessionFactory) {
return new DataAccessObject(sqlSessionFactory);
}
DAO 对象负责数据访问。首先以 Mapper 接口的方式定义访问数据库的函数,之后在 XML 文件中实现该函数,并提供具体实现(SQL 语句细节)。这样做的好处一方面是防止命名错误,传统 MyBatis 方式是根据函数名执行相关 SQL 语句的,不用接口书写很容易出错;另一方面有助于设计(接口)和实现分离,降低耦合性。
public interface UserMapper { public int insertUser(@Param("user")User user); public int updateUser(@Param("user")User user); public int deleteUser(@Param("user") User user); public User selectUser(@Param("user") User user); }
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="per.piers.onlineJudge.mapper.UserMapper">
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="user.id">
INSERT INTO users (email, password, name, sex, role, enabled)
VALUES (#{user.email}, #{user.password}, #{user.name}, #{user.sex}, #{user.role}, #{user.enabled})
</insert>
<update id="updateUser" parameterType="User">
UPDATE users
<trim prefix="SET" suffixOverrides=",">
<if test="user.email != null">email = #{user.email},</if>
<if test="user.password != null">password = #{user.password},</if>
<if test="user.name != null">name = #{user.name},</if>
<if test="user.sex != null">sex = #{user.sex},</if>
<if test="user.role != null">role = #{user.role},</if>
<if test="user.enabled != null">enabled = #{user.enabled},</if>
</trim>
WHERE id = #{user.id}
</update>
<delete id="deleteUser" parameterType="User">
DELETE FROM users
WHERE id = #{user.id}
</delete>
<select id="selectUser" parameterType="User" resultMap="userResult">
SELECT *
FROM users
<if test="user != null">
<where>
<if test="user.email != null">email = #{user.email}</if>
</where>
</if>
</select>
<resultMap id="userResult" type="User">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="password" property="password"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<result column="enabled" property="enabled"/>
<result column="role" property="role"/>
</resultMap>
</mapper>
MyBatis的可以处理基本类型,但有些类型需要自定义转换,就需要 MyBatis 提供的 BaseTypeHandler 进行转换。首先编写 BaseTypeHandler(见下),之后在 MyBatis 配置文件中注册(见上)。
package per.piers.onlineJudge.handler; import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import per.piers.onlineJudge.model.Sex; import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class SexTypeHandler extends BaseTypeHandler<Sex> { @Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Sex sex, JdbcType jdbcType) throws SQLException {
preparedStatement.setInt(i, sex.getId());
} @Override
public Sex getNullableResult(ResultSet resultSet, String s) throws SQLException {
int sex = resultSet.getInt(s);
if (resultSet.wasNull()) {
return null;
} else {
return Sex.getSexType(sex);
}
} @Override
public Sex getNullableResult(ResultSet resultSet, int i) throws SQLException {
int sex = resultSet.getInt(i);
if (resultSet.wasNull()) {
return null;
} else {
return Sex.getSexType(i);
}
} @Override
public Sex getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
int sex = callableStatement.getInt(i);
if (callableStatement.wasNull()) {
return null;
} else {
return Sex.getSexType(i);
}
} }
View
view 层主要是界面(页面)。这里主要是 JSP 页面,因为需要动态展示一些内容。其中还运用了 JavaScript 技术和 AJAX 技术,JavaScript 主要用作页面输入域校验,AJAX 主要用于异步提交需要更新的内容。
<%@page contentType="text/html; charset=UTF-8" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security" %>
<!DOCTYPE html>
<html>
<head>
<%@include file="../common/header.jspf" %>
<title>注册</title>
</head>
<body>
<%@include file="../common/navbar.jspf" %>
<div class="container">
<div class="page-header">
<h1>注册</h1>
</div>
<div class="form-signin" oninput="satisfySubmit()">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">邮箱*</span>
<input type="email" id="email" name="email" value="${email}" class="form-control" placeholder="邮箱长度不超过40个字符"
aria-describedby="basic-addon1" maxlength="40" required oninput="showEmailInputSuggestion()" disabled>
</div>
</div>
<div class="col-md-4">
<p id="emailError" class="text-danger"></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon2">密码*</span>
<input type="password" id="password" name="password" class="form-control"
placeholder="密码长度不少于6个字符,不多于20个字符,只能包括数字和字母"
aria-describedby="basic-addon1" minlength="6" maxlength="20" required
oninput="showAllPasswordSuggestion()">
</div>
</div>
<div class="col-md-4">
<p id="passwordError" class="text-danger"></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon3">确认密码*</span>
<input type="password" id="repassword" name="repassword" class="form-control" placeholder="再次输入密码"
aria-describedby="basic-addon1" minlength="6" maxlength="20" pattern="[\d\w]+" required
oninput="showAllPasswordSuggestion()">
</div>
</div>
<div class="col-md-4">
<p id="repasswordError" class="text-danger"></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon4">姓名</span>
<input type="text" id="name" name="name" class="form-control"
placeholder="你的姓名,可以很酷,不过最多只能有20个字符(中英皆可)"
aria-describedby="basic-addon1" maxlength="20">
</div>
</div>
<div class="col-md-4">
<p></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon5">性别</span>
<div class="form-control">
<div class="radio-inline">
<label>
<input type="radio" name="sex" id="optionsRadios1" value="MALE">
男
</label>
</div>
<div class="radio-inline">
<label>
<input type="radio" name="sex" id="optionsRadios2" value="FEMALE">
女
</label>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<p></p>
</div>
</div>
<br/>
<input type="hidden" id="enabled" name="enabled" value="true"/>
<input type="hidden" id="role" name="role" value="user"/>
<input id="submit" type="button" value="不能注册,请检查相关项填写是否正确" class="btn btn-danger" disabled
onclick="registerUser()">
<br>
<p id="success"></p>
</div>
</div>
<%@include file="../common/footer.jspf" %>
<script src="${pageContext.request.contextPath}/js/user/user.js"></script>
<script src="${pageContext.request.contextPath}/js/user/register.js"></script>
</body>
</html>
function satisfySubmit() {
var submit = document.getElementById("submit");
if (isEmailValid() && isPasswordValid() && isRepasswordValid()) {
submit.setAttribute("type", "submit");
submit.setAttribute("value", "提交注册");
submit.setAttribute("class", "btn btn-success");
submit.removeAttribute("disabled")
} else {
submit.setAttribute("type", "button");
submit.setAttribute("value", "不能注册,请检查相关项填写是否正确");
submit.setAttribute("class", "btn btn-danger");
submit.setAttribute("disabled", "");
}
}
function registerUser() {
xmlhttp = new XMLHttpRequest();
if (xmlhttp != null) {
var email = document.getElementById("email").value;
var password = document.getElementById("password").value;
var name = document.getElementById("name").value;
var sexes = document.getElementsByName("sex");
var sex;
for (var i = 0; i < sexes.length; i++) {
if (sexes[i].checked) sex = sexes[i].value.toUpperCase();
}
var enabled = document.getElementById("enabled").value;
var role = document.getElementById("role").value;
var csrf = document.getElementsByName("_csrf")[0].value;
xmlhttp.onreadystatechange = stateChange;
xmlhttp.open("POST", window.location.pathname, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("&email=" + email + "&password=" + password + "&name=" + name + "&sex=" + sex + "&enabled=" + enabled + "&role=" + role + "&_csrf=" + csrf);
}
} function stateChange() {
var success = document.getElementById("success");
if (xmlhttp.readyState == 4) { // 4 = "loaded"
if (xmlhttp.status == 200) { // 200 = "OK"
success.setAttribute("class", "text-success");
success.innerHTML = "注册成功";
alert("注册成功,点击确定进行登录")
window.location.href = getContextPath() + "/user/information"
} else if (xmlhttp.status == 409) {
success.setAttribute("class", "text-danger");
success.innerHTML = "用户邮箱已存在";
} else if (xmlhttp.status == 500) {
success.setAttribute("class", "text-danger");
success.innerHTML = "服务器可能出现了问题";
}
}
}
Controller
Controller 是 Model 和 View 的粘合剂。Model 的增删改查的操作由 Controller 负责,View 的显示由 Controller 负责。Controller 实质上是 Java EE 的 Servlet。
在 Spring MVC 中,首先配置相关 DispatcherServlet,之后再编写 Controller。
package per.piers.onlineJudge.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration
@EnableWebMvc
@ComponentScan("per.piers.onlineJudge.controller")
public class WebConfig extends WebMvcConfigurerAdapter { @Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setExposeContextBeansAsAttributes(true);
resolver.setSuffix(".jsp");
return resolver;
} @Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
} }
package per.piers.onlineJudge.controller; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import per.piers.onlineJudge.model.User;
import per.piers.onlineJudge.util.DataAccessObject;
import per.piers.onlineJudge.util.ExcelUtil; import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet; @Controller
@RequestMapping("/testManager")
public class UserImportController { private DataAccessObject dao; @Autowired
public UserImportController(DataAccessObject dao) {
this.dao = dao;
} @RequestMapping("/import/user")
public String importUser() {
return "import/user";
} @RequestMapping(path = "/import/user", method = RequestMethod.POST)
public String importResult(@RequestPart("usersFile") MultipartFile usersFile, HttpServletRequest request, Model model) throws IOException {
String path = request.getSession().getServletContext().getRealPath("/") + "/tmp/" + usersFile.getOriginalFilename();
File file = new File(path);
file.getParentFile().mkdirs();
file.createNewFile();
usersFile.transferTo(file);
ExcelUtil excelUtil = new ExcelUtil();
HashSet<String> emails = excelUtil.readColumns(file, "用户邮箱");
try {
if (emails == null) {
model.addAttribute("failure", "读取列用户邮箱出错,可能是没有列用户邮箱");
} else {
User selectUser = new User();
selectUser.setEmail(((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername());
Integer uidAdmin = dao.selectUser(selectUser).getId();
HashMap<String, String> status = dao.importUser(emails, uidAdmin);
StringBuilder builder = new StringBuilder();
for (String key : status.keySet()) {
builder.append(String.format("%s,%s\n", key, status.get(key)));
}
model.addAttribute("success", builder.toString());
}
} catch (Exception e) {
model.addAttribute("failure", e.getMessage());
} finally {
return "import/result";
}
}
}
Spring 技术:这里的 Controller 是由 Spring MVC 提供的。本系统还设计了一个 ErrorController,用户异常处理的 Controller,返回错误的页面。
package per.piers.onlineJudge.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class ErrorController { @RequestMapping(path = "/error/401")
public String error401() {
return "error/401";
} @RequestMapping(path = "/error/403")
public String error403() {
return "error/403";
} @RequestMapping(path = "/error/404")
public String error404() {
return "error/404";
} @RequestMapping(path = "/error/409")
public String error409() {
return "error/409";
} @RequestMapping(path = "/error/500")
public String error500() {
return "error/500";
} }
Spring 技术:异常的捕获和处理是由标有 @ControllerAdvice 注解的类处理,需要定义捕获的异常类型、如何处理(返回的 HTTP 状态码,返回的页面)。
package per.piers.onlineJudge.controller; import org.apache.ibatis.exceptions.PersistenceException;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import per.piers.onlineJudge.Exception.CRUDException;
import per.piers.onlineJudge.Exception.ExistenceException;
import per.piers.onlineJudge.Exception.ExpiryException; import javax.mail.MessagingException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter; @ControllerAdvice
public class GlobalExceptionHandler { @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
@ExceptionHandler(BadCredentialsException.class)
public String badCredentialsExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/401";
} @ResponseStatus(value = HttpStatus.FORBIDDEN)
@ExceptionHandler(value = {ExpiryException.class, IllegalArgumentException.class})
public String illegalStateExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/403";
} @ResponseStatus(value = HttpStatus.CONFLICT)
@ExceptionHandler(ExistenceException.class)
public String existenceExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/409";
} @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = {CRUDException.class, IOException.class, IllegalStateException.class, MessagingException.class, PersistenceException.class})
public String CRUDExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/500";
} public String getExceptionMessage(Exception e) {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
return stringWriter.toString();
} }
Online Judge(OJ)搭建——3、MVC架构的更多相关文章
- 【深入Cocos2d-x】使用MVC架构搭建游戏Four
喜欢Four这个项目,就赶快在GitHub上Star这个项目吧! 喜欢我的文章,来微博关注我吧:王选易在学C艹 点我下载 项目起源 项目Logo: 下面是该游戏的项目地址,各位想参考源代码的同学可以到 ...
- 钟表维修管理系统技术解析(一) MVC架构搭建
钟表维修管理系统技术解析(一) MVC架构搭建 1.1新建项目 第一步:打开VS2010界面,点击左上角文件,点击新建,选择项目 1.1(图1) 第二步:点击网站Web类型,选择ASP.net MV ...
- 【JAVA】基于MVC架构Java技术荟萃案例演练
基于JAVA-MVC技术的顾客管理项目案例总结 作者 白宁超 2016年6月9日22:47:08 阅读前瞻:本文源于对javaweb相关技术和资料汇总,涉及大量javaweb基础技术诸如:Servle ...
- 从零开始学 Java - 搭建 Spring MVC 框架
没有什么比一个时代的没落更令人伤感的了 整个社会和人都在追求创新.进步.成长,没有人愿意停步不前,一个个老事物慢慢从我们生活中消失掉真的令人那么伤感么?或者说被取代?我想有些是的,但有些东西其实并不是 ...
- 【.Net架构】BIM软件架构03:Web管控平台MVC架构
一.前言 上一篇讲述的是将BIM平台后台架构CoreService.sln,该解决方案主要作用是对管控平台的核心业务进行封装,然后让前端的ApiController去调用该解决方案中的对 ...
- MAC OS X El CAPITAN 搭建SPRING MVC (1)- 目录、包名、创建web.xml
一. 下载STS(Spring Tool Suite) 官方地址:http://spring.io/tools/sts 下载spring tool suite for mac 最新版本.这个IDE是很 ...
- Android 四大组件 与 MVC 架构模式
作为一个刚从JAVA转过来的Android程序员总会思考android MVC是什么样的? 首先,我们必须得说Android追寻着MVC架构,那就得先说一下MVC是个啥东西! 总体而来说MVC不能说是 ...
- MVC架构模式分析与设计(一)---简单的mvc架构
首先 我要感谢慕课网的老师提供视频资料 http://www.imooc.com/learn/69 下面我来进行笔记 我们制作一个简单的mvc架构 制作第一个控制器 testController.cl ...
- IntelliMVCCode智能MVC架构的代码助手使用方法
智能代码生成工具,快速帮助开发者提升开发速度,通过工具自动生成MVC架构的大量源代码,节省更多的开发时间. 工具使用的框架:.net4.0,通过工具连接到数据库自动提取数据表或视图中的结构,生成对应的 ...
- 从MVC框架看MVC架构的设计
尽管MVC早已不是什么新鲜话题了,但是从近些年一些优秀MVC框架的设计上,我们还是会发现MVC在架构设计上的一些新亮点.本文将对传统MVC架构中的一些弊病进行解读,了解一些优秀MVC框架是如何化解这些 ...
随机推荐
- the c programing language 学习过程8
glean 捡拾落穗; glean insight 深入了解 modeled模型化 peripheral外围的 himogeneous匀称的 intents 意图 excerpt摘录 intende ...
- lower_bound()返回值
lower_bound()函数实现功能就是二分查找,函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置.如果所有元素都小于val,则 ...
- MyCat 枚举分片设计思考,查询命中条件
Mycat多租户实现的两种方式 MyCat,各种分片规则,仅保证插入的时候分片.表关联,join,查询怎么命中分片条件,还是需要设计. 今天稍微测了一下. ER 分片,此方式,插入的时候能分片,但是查 ...
- MongoDB,分组,聚合
使用聚合,db.集合名.aggregate- 而不是find 管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数.MongoDB的聚合管道将MongoDB文档在一个管道处理完 ...
- yum源配置的三种方法
(一)yum源概述 yum需要一个yum库,也就是yum源.默认情况下,CentOS就有一个yum源.在/etc/yum.repos.d/目录下有一些默认的配置文件(可以将这些文件移到/opt下,或者 ...
- loading加载动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- a链接在新窗口打开
平时用的收集了几种方法 1.在head标签里添加,base最大的用处就是可以改变某一个网页默认的属性 <base target="_blank"/> 2.Jquery ...
- Davinci DM6446 Codec Engine双核通信环境的搭建
根据前几篇文章,一个DM6446的系统已经架构完成.但是有很多人都喜欢TI的机制,毕竟双核软件开发对很多工程师来说是非常麻烦的事情,既然TI提供开发套件和开发包,那么直接做OEM就可以了,底层的东西不 ...
- 笔记︱金融风险控制基础常识——巴塞尔协议+信用评分卡Fico信用分
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 本笔记源于CDA-DSC课程,由常国珍老师主讲 ...
- Css中路径data:image/png;base64的用法详解
今天查看一些网站的css中发现了 background-image:url(data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAAB ...