大家好,我是
方圆
这是一些知识点的总结和记录,可食用!
我觉得在集成Mybatis时问题并不大
@Mapper
@Component
public interface UserMapper {
@Select("select * from user where id = #{id}")
User selectById(@Param("id") int id);
@Insert("insert into user (id,name) values (#{id},#{name})")
int insertUser(User user);
}
@Mapper
,标记该类是一个Mapper@Select
@Insert
@Service
public class UserService {
...
@Transactional
public boolean tx(){
User user1 = new User(2,"222");
userMapper.insertUser(user1);
User user2 = new User(3,"333");
userMapper.insertUser(user2);
return true;
}
}
@Transactional
标记@Data
public class Result<T> {
private int code;
private String msg;
private T data;
/**
* 成功时调用
*/
public static <T> Result<T> success(T data){
return new Result<T>(data);
}
/**
* 失败时调用
*/
public static <T> Result<T> error(T data){
return new Result<T>(data);
}
private Result(T data){
this.data = data;
}
private Result(int code,String msg){
this.code = code;
this.msg = msg;
}
private Result(CodeMsg codeMsg){
if(codeMsg != null){
msg = codeMsg.getMsg();
code = codeMsg.getCode();
}
}
}
code用来保存状态码
,msg状态信息
,data是返回的对象
(泛型)public class Result<T>
看类声明的语句
,其中使用了泛型,这表示返回对象时,我们对其类型是“已知”的,不必强转,增加了灵活性
public static <T> Result<T> success(T data){
return new Result<T>(data);
}
其中的方法语句,在返回值中标记了泛型
,需要我们在函数定义的中在返回值前加上
,可以把它想象成正常的返回值,像String等等,只不过用T来表示罢了
不过,在调用这个方法的时候用两种方法
Result.success("Success")
;Result.success("Success")
;两种使用方法的结果都是一样的,不过第二种更能突出它是泛型方法的使用
,推荐。
private Result(T data){
this.data = data;
}
最后这个实在简单,在构造方法参数中使用泛型,传什么类型就自动为什么类型。
下面是CodeMsg类的代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CodeMsg {
private int code;
private String msg;
//通用错误码
public static CodeMsg SUCCESS = new CodeMsg(0,"success");
...
}
Java泛型详解:和Class的使用。泛型类,泛型方法的详细使用实例
我们的最终目的是要创建出JedisPool
,用来创建出Jedis与服务器中Redis进行交互
首先,需要在配置文件application.properties中写好配置信息
,比如主机地址、端口号、最大连接数等等
redis.host=182.xxx.xxx.xxx
redis.port=6379
redis.timeout=3
redis.poolMaxTotal=10
redis.poolMaxIdle=10
redis.poolMaxWait=3
写好配置文件,我们要对其进行读取,创建读取配置信息的配置类
@Data
@Component
//读取配置文件的注解,指定前缀,读以redis打头的
@ConfigurationProperties(prefix = "redis")
public class RedisConfig {
private String host;
private int port;
private int timeout;
private int poolMaxTotal;
private int poolMaxIdle;
private int poolMaxWait;
}
@ConfigurationProperties(prefix = "redis")
,用来读取前缀是redis的配置信息,字段与要读取的信息一致接下来就是要创建JedisPool
@Service
public class JedisPoolFactory {
@Autowired
RedisConfig redisConfig;
@Bean
public JedisPool jedisPool(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
jedisPoolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
jedisPoolConfig.setEvictorShutdownTimeoutMillis(redisConfig.getTimeout() * 1000);
return new JedisPool(jedisPoolConfig,
redisConfig.getHost(),redisConfig.getPort(),redisConfig.getTimeout() * 1000);
}
}
RedisConfig,作为Bean自动装配进来,我们还要建立JedisPoolConfig
来设置一些参数,供建立JedisPool时读取
以上,完成了与服务器Redis的建立连接过程
毕竟我们这个是高并发的项目,那么多个人在对同一个key进行读取时,如果不对key值进行修饰,很容易发生数据损坏,所以,我们采用了前缀修饰
,在设计模式中,是对模板方法模式
的应用
接口
,其中有两个方法,获得失效时间和获取前缀public interface KeyPrefix {
//添加失效时间
int expireSeconds();
//获取前缀
String getPrefix();
}
抽象类
,它就像是一个模板
,为其他实现该抽象类的子类,建立了一个模板(我在说什么???应该传达清楚了)两种构造函数
,一种为无失效时间的,另一种为有失效时间的抽象类中构造方法的理解:其中的构造方法与普通类中的构造方法
长得一样
,不过它不能用来构造自己
,因为它是抽象的,不能实例化,但是一旦子类实现了该抽象类,那么子类便可以调用其抽象类的构造函数进行实例化
public abstract class BasePrefix implements KeyPrefix{
private int expireSecond;
private String prefix;
public BasePrefix(String prefix){
this(0,prefix);
}
public BasePrefix(int expireSecond,String prefix){
this.expireSecond = expireSecond;
this.prefix = prefix;
}
@Override
public int expireSeconds(){
return expireSecond;
}
@Override
public String getPrefix() {
//获取前缀,前面添加类名
return getClass().getSimpleName() + ":" + prefix;
}
}
实现类
public class UserKey extends BasePrefix {
public UserKey(String prefix) {
super(prefix);
}
//UserKey的两种前缀形式,一种是根据id另一种根据name
public static UserKey getById = new UserKey("id");
public static UserKey getByName = new UserKey("name");
}
它的构造函数就是用的抽象父类中的构造函数
,而且定义了两个静态字段,一种是根据Id来生成前缀,前缀格式会根据getPrefix()方法,表示为类名+:+id
@Service
public class RedisService {
@Autowired
JedisPool jedisPool;
public <T> boolean set(KeyPrefix keyPrefix,String key,T value){
//获取Jedis对象
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String str = beanToString(value);
if(str == null || str.length() <= 0){
return false;
}
String realKey = keyPrefix.getPrefix() + key;
int seconds = keyPrefix.expireSeconds();
if(seconds <= 0){
jedis.set(realKey,str);
}else{
//设置超时时间
jedis.setex(realKey,seconds,str);
}
return true;
}finally {
returnToPool(jedis);
}
}
...
}
JedisPool
,用Jedis连接池来拿出Jedis
与Redis服务器建立连接。value值转换为String类型
,让Redis能够识别添加前缀
,生成realKey;获取其中的失效时间setex()方法
private <T> String beanToString(T value){
if(value == null){
return null;
}
//进行类型判断,这里用到了?通配符
Class<?> clazz = value.getClass();
if(clazz == int.class || clazz == Integer.class){
return "" + value;
}else if(clazz == long.class || clazz == Long.class){
return "" + value;
}else if(clazz == String.class){
return (String)value;
}else{
//如果是对象的话,用JSON的静态方法转String
return JSON.toJSONString(value);
}
}
@SuppressWarnings("unchecked")
private <T> T stringToBean(String str,Class<T> clazz){
if(str == null || str.length() <= 0 || clazz == null){
return null;
}
if(clazz == int.class || clazz == Integer.class){
return (T) Integer.valueOf(str);
}else if(clazz == long.class || clazz == Long.class){
return (T) Long.valueOf(str);
}else if(clazz == String.class){
return (T) str;
}else{
//转化成对象的JSON静态方法
return JSON.toJavaObject(JSON.parseObject(str),clazz);
}
}
@SupressWarings("unchecked")
,镇压警告呼!!!