【Java框架】知识点汇总Day3:MyBatis缓存、动态SQL(含实用类工具基础)(持续更新)
一、实用类工具
1.1 Collections工具类
Collections工具类专门用来操作集合的,添加元素、对元素进行排序、替换元素
- Collections常用方法
| 方法 | 描述 |
| public static void sort(List list,Comparator) | 根据Comparator接口进行排序 |
|
public static void binarySearch(List list,Object k) |
查找元素在集合的下标,要求集合必须是升序排列 |
| public static void reverse(List list) | 对集合元素的顺序进行反转 |
| public static void swap(List list,int i,int j) | 交换两个元素的位置 |
| public static void fill(List list,Object o) | 将集合中的元素全部替换为o |
| public static void min(List list) | 返回集合中的最小值 |
| public static void max(List list) | 返回集合中的最大值 |
| public static boolean replaceAll(List list,Object oldV,Object newV) | 将集合中所有的oldV替换为newV |
| public static boolean addAll(List list,Object ... o) | 向集合中添加元素 |
package com;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test7 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
Collections.addAll(arrayList,"Java","World","Duan","Ye"); //向集合中添加元素
System.out.println(arrayList);
System.out.println(arrayList.get(1));//根据下标找元素
Collections.sort(arrayList, new Comparator<String>() { //按照长度排序
/**
* o1 > o2,返回1
* o1 <o2,返回-1
* o1 = o2 返回0
* @return
*/
@Override
public int compare(String o1, String o2) {
if(o1.length() > o2.length()){
return 1;
}
if(o1.length() < o2.length()){
return -1;
}
return 0;
}
});
System.out.println(arrayList);
Collections.sort(arrayList); //按照ASCII码排序
System.out.println(arrayList);
System.out.println(Collections.binarySearch(arrayList, "Duan")); //查找Duan的下标 ,此时是升序排列(ASCII码)
Collections.reverse(arrayList); //反转所有元素的顺序
System.out.println(arrayList);
Collections.swap(arrayList,1,3);//根据下标交换指定的元素
System.out.println(arrayList);
arrayList.add("Java");
Collections.replaceAll(arrayList,"Java","Test"); //将集合中的Java全部替换成Test
System.out.println(arrayList);
System.out.println(Collections.max(arrayList)); //返回最大值
System.out.println(Collections.min(arrayList));//返回最小值
Collections.fill(arrayList,"Love"); //将集合中所有元素替换成Love
System.out.println(arrayList);
}
}

1.2 泛型
泛型是指在类定义时不指定类中信息的具体数据类型,而是用一个标识符来替代,当外部实例化对象的时候再来指定具体的数据类型。
多态的思想:找父类。
一般定义属性时,就确定了其数据类型,这限制了输出的格式。比如:十点,String。10,Integer。不仅要修改属性的数据类型,相关的getter、setter等方法都要进行更改。使用它们共有的父类:Object 可以,但是无法调用其子类特有的方法。比如String的.length,需要多次转化。使用泛型可解决该问题。
public class Time <T>{
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Time(T value){
this.value = value;
}
}
public class Test7 {
public static void main(String[] args) {
Time<String> time = new Time("十点");
String value = time.getValue();
System.out.println(value);
Time<Integer> time1 = new Time<>(10);
Integer value1 = time1.getValue();
System.out.println(value1);
Time<Float> time2 = new Time<>(10.0f);
Float value2 = time2.getValue();
System.out.println(value2);
}
}
泛型可定义多个。
public class Time <H,M,S>{
private H hour;
private M minutes;
private S second;
public H getHour() {
return hour;
}
public void setHour(H hour) {
this.hour = hour;
}
public M getMinutes() {
return minutes;
}
public void setMinutes(M minutes) {
this.minutes = minutes;
}
public S getSecond() {
return second;
}
public void setSecond(S second) {
this.second = second;
}
}
public class Test7 {
public static void main(String[] args) {
Time<String,Integer,Float> time = new Time();
time.setHour("十四点");
time.setMinutes(41);
time.setSecond(52.2f);
System.out.println("现在的时间是:" + time.getHour() + ":" + time.getMinutes() + ":" + time.getSecond());
}
}
1.3 枚举
Enum是一种有确定取值区间的数据类型,本质上是一种类,具有高效、简洁、安全、方便等特点。
枚举的值被约束到一个特定的范围,只能从该范围中取值。
比如:星期一~星期日,一月~十二月等
package com;
public class Week {
public static final int MONDAY = 0;
public static final int TUESDAY = 1;
public static final int WEDNESDAY = 2;
public static final int THURSDAY = 3;
public static final int FRIDAY = 4;
public static final int SATURDAY = 5;
public static final int SUNDAY = 6;
}
使用Enum会更简单。
package com;
public enum WeekEnum {
MONDAY(0,"周一"),
TUESDAY(1,"周二"),
WEDNESDAY(2,"周三"),
THURSDAY(3,"周四"),
FRIDAY(4,"周五"),
SATURDAY(5,"周六"),
SUNDAY(6,"周日");
private Integer code;
private String value;
WeekEnum(Integer code,String value){
this.code = code;
this.value = value;
}
@Override
public String toString() {
return "WeekEnum{" +
"code=" + code +
", value='" + value + '\'' +
'}';
}
}
package com;
public class Test1 {
public static void main(String[] args) {
System.out.println(WeekEnum.MONDAY);
System.out.println(WeekEnum.WEDNESDAY);
System.out.println(WeekEnum.TUESDAY);
}
}

1.4 Math
Math常用方法

1.5 Random
Random是用来产生一个随机数的,并且可以指定任意的区间,在此区间产生一个随机数。
| 方法 | 描述 |
| public Random() | 创建一个无参的随机数构造器 |
| public Random(long seed) | 使用long数据创建一个随机数 |
| public boolean nextBoolean() | 创建一个随机的boolean值 |
| public double nextDouble() | 创建一个随机的double值 |
| public float nextFloat() | 创建一个随机的float值 |
| public int nextInt() | 创建一个随机的int值 |
| public long nextLong() | 创建一个随机的long值 |
public class Test{
public static void mian(String[] args){
Random random = new Random();
for(int i = 0;i < 3; i++){
int b = random.nextInt(10);
System.out.print(b);
}
}
}
1.6 StringBuffer
String的底层是用数组来存值的,数组长度不可变
StringBuffer和String类似,底层也是一个数组,但是是一个可扩容的动态数组
StringBuffer默认的数组长度为16
| 方法 | 描述 |
| public StringBuffer() | 创建一个空的StringBuffer |
| public StringBuffer(String str) | 创建一个str的StringBuffer |
| public int length() | 获取长度 |
| public StringBuffer append(String str) | 追加字符串 |
| public StringBuffer delete(int start,int end) | 删除指定区间内的字符串 |
package com;
public class Test1 {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("Hello World");
StringBuffer java = stringBuffer.append("Java");
System.out.println(java);
StringBuffer delete = stringBuffer.delete(3,6);//包含左边不包含右边
System.out.println(delete);
StringBuffer reverse = stringBuffer.reverse();
System.out.println(reverse);
StringBuffer duan = stringBuffer.insert(8,"Duan");
System.out.println(duan);
}
}
二、Mybatis缓存
延迟加载是在多表关联查询的情况下使用,如果是单表,则延迟加载不起作用,单表的情况下,如何提升程序运行的效率?
可以使用缓存,减少java程序和数据库的交互次数,从而提升程序的运行效率。
当查询出数据后,将数据保存到缓存中,当下一次需要使用相同的数据时,直接从缓存中取出数据,不需要再访问数据库。
一级缓存默认开启,无法关闭,SqlSession级别的缓存,同一个SqlSession的情况下,一级缓存有效,如果有两个SqlSession,则一级缓存失效,一级缓存不需要进行任何配置,直接使用即可。
二级缓存 是比一级缓存作用域更大的缓存机制,它是Mapper级别的,只要是同一个Mapper,无论使用多少个SqlSession,二级缓存都是存在的。
二级缓存默认是关闭的,需要手动开启。
2.1 一级缓存
public class Test1 {
public static void main(String[] args) {
InputStream resourceAsStream = Test1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Mapper的代理对象
ClassMapper mapper = sqlSession.getMapper(ClassMapper.class);
Class classes = mapper.getById(2);
System.out.println(classes.getName());
Class classes1 = mapper.getById(2);
System.out.println(classes1.getName()); //同一条数据,只会出现一条查询语句。(因为在同一个sqlsession中,默认开启了一级缓存)
}
}

public class Test1 {
public static void main(String[] args) {
InputStream resourceAsStream = Test1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(); //第一个sqlSession
//获取Mapper的代理对象
ClassMapper mapper = sqlSession.getMapper(ClassMapper.class);
Class classes = mapper.getById(2);
System.out.println(classes.getName());
sqlSession.close();//关闭了缓存
sqlSession = sqlSessionFactory.openSession(); //第二个sqlSession
mapper = sqlSession.getMapper(ClassMapper.class);
Class classes1 = mapper.getById(2);
System.out.println(classes1.getName()); //此时会调用两次数据库,因为不是同一个sqlSession,一级缓存失效。
}
}

2.2 开启二级缓存
1.config.xml配置二级缓存
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
2.mapper.xml中配置
<?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="com.myspring.mapper.ClassMapper">
<!--二级缓存开启配置-->
<cache></cache>
<select id="getById" parameterType="java.lang.Integer" resultType="com.myspring.entity.Class">
select * from class where id = #{id};
</select>
</mapper>
3.实体类实现序列化接口
package com.myspring.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class Class implements Serializable {
private Integer id;
private String name;
private List<Student> students;//一个班级有多个学生
}

只执行一次SQL,二级缓存生效。
三、MyBatis动态SQL
3.1 建表
use sys;
create table user( id int primary key auto_increment,username varchar(11),password varchar(11),age int);
3.2 创建实体类
package com.myspring.entity;
import lombok.Data;
@Data
public class User1 {
private int id;
private String username;
private String password;
private int age;
}
3.3 UserMapper
package com.myspring.mapper;
import com.myspring.entity.User1;
public interface UserMapper {
public User1 get(User1 user1);
}
<?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="com.myspring.mapper.UserMapper">
<!-- 你的映射语句 -->
<select id="get" parameterType="com.myspring.entity.User1" resultType="com.myspring.entity.User1">
select * from user where id = #{id} and password = #{password} and username = #{username} and age = #{age}
</select>
</mapper>
3.4 config.xml注入mapper.xml
<mappers>
<mapper resource="com/myspring/mapper/UserMapper.xml"></mapper>
</mappers>
3.5 测试
public class Test1 {
public static void main(String[] args) {
InputStream resourceAsStream = Test1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(); //第一个sqlSession
//获取Mapper的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User1 user1 = new User1();
user1.setId(1);
user1.setAge(25);
user1.setPassword("123456");
user1.setUsername("张三");
User1 user2 = mapper.get(user1);
System.out.println(user2);
}
}

此时只要四个属性其中有一个不写,输出结果就为null。
动态SQL解决该问题。
<?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="com.myspring.mapper.UserMapper">
<!-- 你的映射语句 -->
<!-- <select id="get" parameterType="com.myspring.entity.User1" resultType="com.myspring.entity.User1">-->
<!-- select * from user where id = #{id} and password = #{password} and username = #{username} and age = #{age}-->
<!-- </select>-->
<select id="get" parameterType="com.myspring.entity.User1" resultType="com.myspring.entity.User1">
select * from user
<where>
<if test="id != null" >
id = #{id}
</if>
<if test="username != null">
and username = #{username}
</if>
<if test="password != null">
and password = #{passwoed}
</if>
<if test="age != null">
and age = #{age}
</if>
</where>
</select>
</mapper>
此时,四个属性,测试类中只用不管写几个,结果都会输出。SQL写几个就出现几个。
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User1 user1 = new User1();
user1.setId(1);
user1.setAge(25);
// user1.setPassword("123456");
user1.setUsername("张三");
User1 user2 = mapper.get(user1);
System.out.println(user2);

动态SQL使用<choose><when></when></choose>也可以(跟mybatis版本有关系,新版本不支持)。
更多推荐
所有评论(0)