1、数据灵异事件,可先检查实现类的事务,判断是否是因为事务问题。
1.1、检查mybatis配置文件,是否有问题
1.2、检查字段是否对应
一个有意思的java学习网站:http://how2j.cn/k/socket/socket-ip-port/399.html
数据库方面
inner join 在表中存在至少一个匹配时返回行 ,只显示存在匹配的
select a.name,b.age from atable a left join btable b on a.ip=b.ip;
left join 查询主表中与外表匹配的行,外表中未匹配也显示主表余下内容。
select a.name,b.age from atable a left join btable b on a.ip=b.ip;
right join 与 left join 相反
select a.name,b.age from atable a left join btable b on a.ip=b.ip;
full join 返回主表和外表的所有行,没有则显示空字段。
select a.name,b.age from atable a left join btable b on a.ip=b.ip;
union 合并两个和多个select语句的结果集 union的内部的select语句必须拥有相同数量的列及数据类型。但如果遇到相同的字符,则只保留一个
select name from table1
union
select name from table2
union all与union相同,但遇到相同字符也会显示
select name from table1
union all
select name from table2
创建索引
create index indexName on tableName(columnName)
distinct 找出不同值
eg : select distinct columnName from tableName;
联查表的时候不要将所有条件都扔在where后边,视具体情况进行条件放置。
在查询一对多的时候 才用mapper文件中插入collection,例如下方对主表中关联了key和reply表,为两个1对多的关系,采用以下方式进行查询。
<resultMap id="newBaseMap" type="xxxx.PO">
<id column="id" jdbcType="VARCHAR" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="reply_type" jdbcType="INTEGER" property="replyType"/>
<result column="type" jdbcType="INTEGER" property="type"/>
<result column="create_time" jdbcType="INTEGER" property="createTime"/>
<collection property="keyList" ofType="keyPO" select="getKeyList" column="id" >
<result column="rule_id" property="ruleId" jdbcType="VARCHAR"/>
<result column="match_type" property="matchType" jdbcType="INTEGER"/>
<result column="rule_key" property="ruleKey" jdbcType="VARCHAR"/>
</collection>
<collection property="replyList" ofType="replyPO" select="getReplyList" column="id">
<result column="rule_id" jdbcType="VARCHAR" property="ruleId"/>
<result column="reply_content" jdbcType="VARCHAR" property="replyContent"/>
</collection>
</resultMap>
如果要进行批量修改或其他批量操作时,记得在配置文件中的,数据库url后加上 &allowMultiQueries=true 允许批量操作
java*
查询每日的数据统计:新建list把里边的数据都设置为0,将查询出来的东西赋值给list中,最后返回赋值后的list
如果有构造方法,一定要填上无参构造器
理清每个实体类的构成,在dao层中进行对应,查看具体查的是什么东西,再根据此储备在实现类中与页面对比查看业务逻辑。
如果需要遍历map,则使用entryMap遍历,效率最高’
此处转载一个排序算法——堆排序的方法,思路调理都很清晰:堆排序的方法
使用Beanutils下的copyProperties方法的时候,如果需要忽略某个参数,则在方法参数中添加忽略字段的数组。
例:我不需要复制example2中的ID属性到example1中,则这样写
BeanUtils.copyProperties(example2,example1,new String[]{“id”})
即可复制除了ID的其他所有相对应的字段
设置实体类时,尽量用基本类型,在插入数据库时,如果前端传值为空,则会插入基本类型的默认值。例如int与Integer,如果age设置为int类型,前端没有传age这个参数,则到数据库为0,如果age设置为Integer,前端没有传age这个参数,则数据库为null
利用函数对int类型的数组进行转化: https://blog.csdn.net/zx000003/article/details/82691578
Spring Boot 框架相关**
1.配置了mybatis之后 ,需在springboot配置文件中添加扫描
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.config-location=classpath:mybatis-config.xml
2.遇见跨域问题 ,在springboot项目中添加一个配置类
如下
/**
* 跨域配置
*
* @author sT
*/
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean DoCorsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置你要允许的网站域名,如果全允许则设为 *
config.addAllowedOrigin("*");
// 如果要限制 HEADER 或 METHOD 请自行更改
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// 这个顺序很重要,为避免麻烦请设置在最前
bean.setOrder(0);
return bean;
}
}
3
定义统一异常返回对象/src/main/java/com/study/demo/domain/Result.java
/**
* Http请求返回的最外层对象
*/
public class Result<T> {
/* 错误码 */
private Integer code;
/* 提示信息 */
private String msg;
/* 具体内容 */
private T data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
定义错误返回接口
package com.study.demo.utils;
import com.study.demo.domain.Result;
public class ResultUtil {
public static Result success(Object object){
Result result = new Result();
result.setCode(0);
result.setMsg("成功");
result.setData(object);
return result;
}
public static Result success(){
return success(null);
}
public static Result error(Integer code,String msg){
Result result = new Result();
result.setCode(code);
result.setMsg(msg);
result.setData(null);
return result;
}
}
PageHelper分页插件的使用
1.导入pageHelper依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
2.在mybatis配置文件中加入配置
3.在启动类中注入bean//配置mybatis的分页插件pageHelper
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("offsetAsPageNum","true");
properties.setProperty("rowBoundsWithCount","true");
properties.setProperty("reasonable","true");
properties.setProperty("dialect","mysql"); //配置mysql数据库的方言
pageHelper.setProperties(properties);
return pageHelper;
}
4.示例
4.1 新建实体类pagePO,封装pageNum以及pageSize (也可不封装,视具体情况而定)
4.2 Service层
PageInfo <ExamplePO> queryForWeChatUsers(Example qo);
4.2 ServiceImple层
@Override
/*exampleDTO中继承了pagePO*/
public PageInfo<ExamplePO> queryForWeChatUsers(ExampleDTO qo) {
PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
List<ExamplePO> list = ExampleDao.queryForWhat(qo);
return new PageInfo(list);
}
4.3 controller层
如为rest风格,则直接返回PageInfo(list), 如果为其他,则返回一个list即可
使用spring注解完成对数据增删查改日志的记录
其中不完整,需再根据具体情况加入各种包。
1.新建注解类,注明OperatorLog (后可根据具体情况更改)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperatorLog {
String name() default ""; (可修改name为其他,例如ege,则注解中的name改为ege)
}
2.新建操作日志类 (此处为示例,只做修改的日志)
@Component
public class OperatorLogAspect {
/**
* 校验2个参数有 @OperatorLog 的属性是否相等,如果不相等,则添加描述
*
* @param oldObj 旧对象
* @param newObj 新对象
* @return
*/
public String check(Object oldObj, Object newObj) {
StringBuilder memo = new StringBuilder();
Class<?> classA = oldObj.getClass();
Class<?> classB = newObj.getClass();
//1.先比较两个类型是否一样
if (!(classA.isAssignableFrom(classB))) {
throw new RException(ExceptionEnum.OBJECT_NOT_EQUAL);
}
//2.遍历取值
Field[] declaredFields = classA.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
//判断对象是否含有@OperatorLog 注解
OperatorLog annotation = declaredField.getAnnotation(OperatorLog.class);
if (annotation != null) {
try {
//取出新旧对象的当前值进行对比
Object o = declaredField.get(oldObj);
Object o1 = declaredField.get(newObj);
if (!o.equals(o1)) {
String memo1 = "将" + annotation.name() + "由【" + o + "】改为了【" + o1 + "】;";
memo.append(memo1);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return memo.toString();
}
3.在实体类所需要日志记录的地方加上@OperatorLog注解
例
@Getter (lambook插件)
@Setter
public class ExamplePO{
@OperatorLog(name = "姓名")
private String name;
}
4.在实现类或者controller层中,获取到修改之前的ExamplePO和修改之后的ExamplePO,放入check方法中,输出memo ,(如果修改之前为1,修改之后为2),则输出memo为: 将姓名由 【1】 改为了 【2】。
当springboot项目启动报出找不到主类的时候,应检查启动类的包导入情况,例如今天就出现导入DataSourceAutoConfiguration包出错的情况, 我这里选择了最简单的方法,在启动类加上@SpringbootConfiguration注解,解决了问题。
5.@Autowired注入为null的情况
检查是否是在静态方法中使用使用注册了容器的方法,
如果在通常类中想加入@Autowired注入类,需先将自己使用@Component注解注册为组件,
6.springboot注册拦截器
1 自定义类实现handleIntercepter接口
2 自定义类继承WebMvcConfigurationSupport 并重写 addInterceptors方法
eg:
//重写prehandle方法
@Componet
public class PersonInterceptorImplements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {
//具体业务逻辑、
return 结果
}
}
public class PersonInterceptor extends WebMvcConfigurationSupport {
@Autowired
private PersonInterceptorImplements personInterceptor
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(personInterceptor)
//添加所有路径拦截
.addPathPatterns("/**")
//拦截除以下路径
.excludePathPatterns(
"/"
, "/login/**"
)
;
registry.addInterceptor(apolloInterceptor)
.addPathPatterns("/apollo/**");
super.addInterceptors(registry);
}
mybatis注意事项
在xml文件中,使用“ < sql > ”标签的时候,注意和对应的< incluce >标签所在sql中的使用关系,避免出现类型转换错误
使用有则修改无则新增:
例子
insert into user(id,name,age)
values(#{id},#{name},#{age})
on duplicate key update name=values(name)
如果传入的数据在数据库中存在id与age,则修改name
linux方面**
从git上获取项目并运行-----省去本地打包的时间
(linux需要配置好git,mvn,java)
1.在linux新建文件夹,配置git项目。
2.新建脚本 start.sh (此脚本是为了方便已经打包过的jar包运行)
cd target /*进入target文件夹(需新建)*/
echo '------------------------------------杀掉上一个进程------------------------------------' /*输出文字*/
ps aux|grep base-0.0.1.jar|awk '{print $2}'|xargs kill -9 /*kill掉上一个jar包运行的进程*/
DATE=$(date +%Y%m%d) /*日志文件相关*/
fileName=${DATE}.log /*日志文件相关*/
echo ${fileName} /*输出日志文件名*/
nohup java -Dfile.encoding=utf-8 -jar base-0.0.1.jar --server.port=8089 & /*后台运行jar包,其中可指定nohup.hup的输出地址,此处省略*/
sleep 1 /*休眠*/
3.新建脚本 build.sh (此脚本是为了从git上pull项目到本地并进行打包)
git pull origin develop /*从项目库的develop分支中拉取项目,如果只有主支,则 git pull*/
mvn clean package -D maven.test.skip=true /*打包项目 */
echo '------------------------------------打包完成------------------------------------' /*输出文字*/
sleep 1 /*休眠*/
sh start.sh /*启动start.sh脚本*/
4.日志文件在target里的nohup.out里
示例:
1.配置git
git config --global user.name ‘xxxxx’
git config --global user.email ‘XXXXX@XX.com’
获取ssh公钥(此处需注意,如果之前有人在服务器上进行过此操作,需指定其他位置进行获取,不然会影响之前的项目)
ssh-keygen -t rsa -C ‘youremail’ -f /home/example/id_rsa
此处获取到SSH公钥,与git匹配。
在/home/workspace下新建项目目录
cd /home/workspace
mkdir demo
/*先进行克隆操作,将项目克隆下来,避免出现版本问题 */
git clone <SSH链接>
将项目克隆下来之后,执行 build.sh 等待执行完毕即可