对于数据库的增删改操作需要在方法上面添加注解@transactional,增删改成功返回1否则返回0。如果throws的是Exception而不是DaoException则需要写成@transactional(rollbackFor = Exception.class)
,mybatis generration,
insert和insertselective,第一个必须每个属性都要有值,第二个可以不用有值。
selectByExample和 selectByExampleWithBLOBS,后面一个可以吧数据库中的text数据也查出来,查询全部就要把条件设置为null。
:
@RequestMapping("/rest/item/query/item/desc/{id}")
@ResponseBody
public EgoResult showTbItemDesc(@PathVariable long id){
return tbItemDescService.selectTbItemDescById(id);
}
,{}大括号代表的json Object类型,jdk中为object,[]小括号代表的是json Array 在jdk中表现为List
…Application.class 不要放在同级目录下,如下:
如果放在了com.ego.potal的包下,其他项目的com.ego.sender等包下的类,启动类不会加载到
redis,cache,SpringSecurity,RabbitMQSender
package com.ego.portal.config;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//缓存配置对象
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L)) //设置缓存的默认超时时间:30分钟
.disableCachingNullValues() //如果是空值,不缓存
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) //设置key序列化器
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); //设置value序列化器
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
}
package com.ego.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//使用BCrypt算法加密
@Bean
protected PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//form表单登录验证
http.formLogin()
.loginProcessingUrl("/login") //处理登录post请求接口,无需自己实现
.successForwardUrl("/loginSuccess") //登录成功转发接口
.loginPage("/"); 未登录跳转页面,设置了authenticationentrypoint后无需设置未登录跳转
//谁可以访问什么
http.authorizeRequests()
.antMatchers("/","/css/**","/js/**").permitAll() //都可以访问(静态资源)
.anyRequest().authenticated(); //除上面的其他的所有http请求都要验证
//关闭打开的csrf保护
http.csrf().disable();
// deny禁止iframe调用
http.headers().frameOptions().disable();
}
}
package com.ego.sender.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SenderConfig {
@Value("${ego.rabbitmq.content.queueName}")
private String contentQueue;
/**
* 如果没有队列,帮助创建队列。
*
* @return
*/
@Bean
public Queue queue() {
return new Queue(contentQueue);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange("amq.direct");
}
@Bean
// 参数名和方法名一直就是从spring容器中获取对应方法的返回值,将队列和交换器绑定在一起
public Binding binding(Queue queue, DirectExchange directExchange){
return BindingBuilder.bind(queue).to(directExchange).withQueueName();
}
}
#Nginx地址
ego:
fastdfs:
nginx: http://192.168.8.129:8888/
#静态变量
bigad:
categoryid: 89
rabbitmq:
content:
queueName: content
#dubbo配置
dubbo:
application:
name: ego-manager
registry:
address: zookeeper://192.168.8.128:2181
#tomcat端口
server:
port: 8081
#视图解析器
spring:
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
#扫描其他的application-*.yml
profiles:
active: commons,redis
#RabbitMQ
spring:
rabbitmq:
host: 192.168.8.132
username: root
password: root
#redis
spring:
redis:
host: 192.168.8.130
因为HTTPClient是同步请求,所以要交给RabbitMQ消息队列进行异步请求,
RabbitMQ最主要的就是两点:
1.可以实现异步请求,提高了性能。
2.可以实现消息队列,先进的先执行,排队功能
可以使其访问另外一个项目的控制器,完成控制器所完成的内容
//调用的代码块
HttpClientUtil.doGet("http://localhost:8082/bigad");
/**
* 被调用的控制器
* 更新大广告到redis,被rabbitMQ_receive的HTTPClient调用
* @return
*/
@RequestMapping("/bigad")
@ResponseBody
public String RedisAddBigAd(){
tbContentService.showBig2();
System.out.println("Controller");
return "ok";
}
redis:./redis-server redis-conf
solr: ./solr start -force
rabbitMQ:
./rabbitmq-server -detached
FastDFS:
service fdfs_storge start
service fdfs_tra start
nginx: ./nginx
zookeeper: ./zkServer.sh start
redis 没有修改,对其新增操作就包括修改,
solr没有修改,只能删除和新增
如果定义的类的变量,方法中引用时都要去新建一个,例如
//应该直接在方法中创建一个变量,这样:
String key = cartRedisKey+tbUser.getId();
//不应该直接更改类的变量,因为如果别的方法再次调用,有可能会显示你这个方法更改之后的值,不再是原先的值了,
cartRedisKey = cartRedisKey+tbUser.getId();
//另外,如果定义一个获取不到值的变量,则不会给内存地址,即:
List<CartPojo> cartPojoList = (List<CartPojo>) redisTemplate.opsForValue().get(cartKey);
//如果上面的redisTemplate没有获取到到值,则为null,并且不会给cartPojoList分配内存地址,
//就不能够使用cartPojoList.add()函数
//改为如下代码:
List<CartPojo> cartPojoList = new ArrayList<>();
cartPojoList = (List<CartPojo>) redisTemplate.opsForValue().get(cartKey);
//在List和Map中循环遍历,不需要再将值重新放入到Map或者list中,因为他已经自动更改了,例如:
//而且Map和List更改的都是一开始声明的变量,而不是Map自己创建的,即是这些变量储存的内存地址,
//当更改时,更改的都是原先的变量的值
public class Test {
public static void main(String[] args) {
Map<Integer,TbUser> map = new HashMap<>();
System.out.println(map.toString()==null);
System.out.println(map.size()==0);
TbUser tbUser1 = new TbUser();
tbUser1.setId(1l);
TbUser tbUser2 = new TbUser();
tbUser2.setId(2l);
TbUser tbUser3 = new TbUser();
tbUser3.setId(3l);
map.put(1,tbUser1);
map.put(2,tbUser2);
map.put(3,tbUser3);
for (Integer key :
map.keySet()) {
if (key.equals(2)){
//在中间进行map中变量的更改是可以的,并且不必再次放入到Map中
map.get(key).setId(100l);
}
}
for (Integer key :
map.keySet()) {
System.out.println("map循环遍历"+map.get(key).getId());
}
List<TbUser> list = new ArrayList<>();
list.add(tbUser1);
list.add(tbUser2);
list.add(tbUser3);
for (TbUser tu :
list) {
//List也是可以突然更改,并不用再次取出放入等操作
if (tu.getId()==3L){
tu.setId(300L);
}
}
for (TbUser tu :
list) {
System.out.println("List循环"+tu.getId());
}
//原先的值已经更改,代表之前的操作是对原有变量的操作
System.out.println(tbUser1.getId());
System.out.println(tbUser2.getId());
System.out.println(tbUser3.getId());
}
}
public class TbUser {
private Long id;
@Override
public String toString() {
return "TbUser{" +
"id=" + id +
'}';
}
public TbUser() {
}
public TbUser(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
如果不是传递类,则直接可以变量接收
如果把类当做参数进行RabbitMQ传递,要将被传递的类进行序列化,
public class OrderPojo implements Serializable {
public static final long serialVersionUID=1L;
同时,如果在Receive中接收这个参数数据,需要进行反序列化,并且接收参数代表是同步消息。不再异步,但是队列特点还在,可以处理高并发
public void orderCreate(Message msg) {
byte[] body = msg.getBody();
InputStream is = new ByteArrayInputStream(body);
ObjectInputStream objectInputStream = null;
objectInputStream = new ObjectInputStream(is);
OrderPojo orderPojo = (OrderPojo) objectInputStream.readObject();
}
1.自己创建exception并进行抛出
public class DaoException extends RuntimeException{
public DaoException(String message) {
super(message);
}
}
//方法中返回参数直接,方法名抛出,注意事务回滚
throws DaoException
throw new DaoException("更改商品和商品描述信息失败");
@Override
//声明式事务注解,监听到异常会事务回滚,注意这个注解!!
@Transactional
public int updateTbItemByIds(long[] ids, int status) throws DaoException{
int index = 0;
for (long id :
ids) {
TbItem tbItem = new TbItem();
tbItem.setId(id);
tbItem.setStatus((byte) status);
tbItem.setUpdated(new Date());
index+=tbItemMapper.updateByPrimaryKeySelective(tbItem);
}
if (index == ids.length){
return 1;
}
throw new DaoException("批量更改商品状态失败");
}
@RequestMapping("/cart/order-cart.html")
//请求参数是:?id=159575547860068&id=159575388563078
public String showOrderCart(@RequestParam List<Long> id,Model model){
@RequestMapping("/cart/deleteByIds")
@ResponseBody
//请求参数是:?id=159598520930496&ids=159575547860068,159575388563078
public int deleteCartByIds(Long userId,Long[] ids){
提交git错误,commit中应该可以恢复,之后每个项目都要保存一下,或者及时提交到github中,可以在github中更新!!!!
1.要注意配置类放行静态资源
2.CacheRedis储存到redis中数据会出现乱码判断结果时忽略乱码
内容即可。这是因为默认对 Redis 的 value 序列化器使用 JdkSerializationRedisSerializer 序列化器。
更换序列化器后同时也会解决 redis 中数据前面出现乱码的问题。
下 面 整 个 代 码 的 目 的 : 把 redis 的 value 序 列 化 器 修 改 为
GenericJackson2JsonRedisSerializer,就支持返回值为对象或集合了。
3.springboot访问不到资源,修改MODULE_WORKING_DIR$
4.BeanUtils.copyProperties(被复制对象, 粘贴内容的对象);