一、集合
1.1 Set接口
Set接口是Collection的子接口,Set接口以散列的形式存储数据,所以元素是无序的,可以存储一组无序且唯一的对象。
1.2 Set接口的实现类
HashSet存储一组无序且唯一的元素,这里的无序是指元素的存储顺序和遍历顺序不一致。
java
import java.util.HashSet;
import java.util.Iterator;
public class Test6 {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add("Hello");
hashSet.add("World");
hashSet.add("Java");
hashSet.add("World");
System.out.println(hashSet.size());//因为Set的元素唯一,所以存的元素只有3个,只有1个World
//无序,需要使用迭代进行遍历
Iterator iterator = hashSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
hashSet.remove("Hello");
Iterator iterator1 = hashSet.iterator();
while(iterator1.hasNext()){
System.out.println(iterator1.next());
}
}
}

LinkedHashSet是Set的另外一个子接口,可以存储一组有序且唯一的元素,这里的有序是指元素的存储顺序和遍历顺序是一致的。
java
import java.util.LinkedHashSet;
public class Test6 {
public static void main(String[] args) {
LinkedHashSet set = new LinkedHashSet();
set.add("Hello");
set.add("World");
set.add("Hello");
set.add("Java");
System.out.println(set.size());
System.out.println(set);
set.remove("World");
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}

TreeSet存储一组有序且唯一的元素,TreeSet的有序和LinkedHashSet的有序不一样。
TreeSet的有序是指集合内部会自动给所有元素按照升序进行排列。
java
import java.util.TreeSet;
public class Test6 {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(5);
treeSet.add(8);
treeSet.add(1);
treeSet.add(3);
treeSet.add(6);
treeSet.add(2);
treeSet.add(3);
System.out.println(treeSet.size());//结果为6,因为元素是唯一的。
System.out.println(treeSet);
}
}

如果需要比较对象,需要comparable接口
java
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add(new A(1));
treeSet.add(new A(5));
treeSet.add(new A(8));
treeSet.add(new A(2));
treeSet.add(new A(4));
treeSet.add(new A(7));
treeSet.add(new A(3));
treeSet.add(new A(1));
// System.out.println(treeSet);
Iterator iterator = treeSet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
class A implements Comparable{
private int num;
public A(int num){
this.num = num;
}
/**
* A.compareTo(B)
* 1表示A大于B
* 0表示A等于B
* -1表示A小于B
* @param o the object to be compared.
* @return
*/
@Override
public int compareTo(Object o) {
A a = (A)o;
if (this.num > a.num){
return 1;
}
if (this.num < a.num){
return -1;
}
return 0;
}
@Override
public String toString() {
return "A{" +
"num=" + num +
'}';
}
}

1.3 Map接口
Map接口是与Collection接口完全独立的另一个体系。
区别在于 Set、List 、Collection只能操作单个元素,Map可以操作一对元素。Map中的元素都是以key-value进行存储的。
|-------------------------------------|---------------------------|
| 方法 | 描述 |
| int size() | 获取集合长度 |
| boolean isEmpty() | 判断集合是否为空 |
| boolean containsKey(Object key) | 判断集合中是否存在key |
| boolean containsValue(Object value) | 判断集合中是否存在value |
| V get(Object key) | 通过key取出对应的value |
| V put(Object key,Object value) | 向集合中添加一组key-value |
| V remove(Object key) | 通过key删除集合元素 |
| void clear() | 清空集合 |
| Set keySet() | 取出所有的key,返回set |
| Collection values() | 取出所有的value,返回Collection |
| Set entrySet() | 将Map转换为Set对象,key-value都取出 |
| int hashCode() | 获取集合的散列码 |
| boolean equals(Object o) | 比较两个集合是否相等 |
1.4 Map接口的实现类
- HashMap:存储一组无序、key不可重复,value可重复的元素
- Hashtable:存储一组无序、key不可重复,value可重复的元素
- TreeMap:存储一组有序、key不可重复,value可以重复的元素,可以按照key来排序
HashMap的常用方法
java
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
hashMap.put("h","Hello");
hashMap.put("w","World");
hashMap.put("j","Java");
hashMap.put("d","Duan");
hashMap.put("y","Ye");
hashMap.put("z","Zi");
hashMap.put("z","Zhang");//key值重复,只显示Zhang
hashMap.put("d","De"); //这里与Duan的key值重复,只能显示一个 De
hashMap.put("f","Fu");
System.out.println(hashMap);
System.out.println(hashMap.size()); //集合长度
System.out.println(hashMap.containsKey("a"));//集合中是否存在key值:a
System.out.println(hashMap.containsValue("Fu"));//集合中是否存在value值:fu
System.out.println(hashMap.get("h"));//通过key:h取出对应的value:Hello
System.out.println(hashMap.entrySet());//取出集合中所有的key-value
Set set = hashMap.keySet(); //取出集合中所有key,并通过集合输出
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
Collection value = hashMap.values(); //集合中所有value值
Iterator iterator1 = value.iterator(); //遍历输出
while(iterator1.hasNext()){
System.out.println(iterator1.next());
}
}
}
Hashtable常用方法,用法同HashMap。
区别是Hashtable是线程安全的,HashMap线程不安全。
二、MyBatis
2.1 补充删改查方法
update方法
java
@Update({"update sys_news set title = #{title},content = #{content},createtime = #{createtime},opername = #{opername} where id = #{id}"})
public int update(News news);
java
InputStream resourceAsStream = Test1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Mapper的代理对象
//改 update
NewsMapper mapper = sqlSession.getMapper(NewsMapper.class);
News news = new News();
news.setTitle("测试2");
news.setCreatetime(new Date());
news.setOpername("admin2");
news.setContent("测试2测试2测试1");
news.setId(1);
int update = mapper.update(news);
System.out.println(update);
sqlSession.commit();//提交到数据库
删除
java
@Delete({"delete from sys_news where id=#{id}"})
public int delete(Integer id);
java
InputStream resourceAsStream = Test1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Mapper的代理对象
//删除 Delete
NewsMapper mapper = sqlSession.getMapper(NewsMapper.class);
int delete = mapper.delete(2);
System.out.println(delete);
sqlSession.commit();
查询
java
@Select({"Select * from sys_news where id = #{id}"})
public News getById(Integer id);
java
InputStream resourceAsStream = Test1.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Mapper的代理对象
//查询
NewsMapper mapper = sqlSession.getMapper(NewsMapper.class);
News news = mapper.getById(1);
System.out.println(news);
java
@Select({"select * from sys_news"})
public List<News> list();
java
//查询
NewsMapper mapper = sqlSession.getMapper(NewsMapper.class);
List<News> list = mapper.list();
for(News news : list){
System.out.println(news);
}
多表联查
原始数据:identity opername
业务逻辑:创建customer对象,将identity opername的值分别赋值给customer对象
-
rent.identity→customer.identity(关联字段,值相同) -
rent.opername→customer.custname
java
package com.myspring.entity;
import lombok.Data;
import java.util.Date;
@Data
public class Rent {
private String rentid;
private Integer price;
private Date begindate;
private Date returndate;
// private String identity;
private String carnumber;
// private String opername;
private Date createtime;
private Customer customer;
}
java
package com.myspring.entity;
import lombok.Data;
@Data
public class Customer {
private String identity;
private String custname;
private String address;
private String phone;
private String career;
}
java
package com.myspring.mapper;
import com.myspring.entity.Rent;
public interface RentMapper {
public Rent getById(String rentid);
}
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.RentMapper">
<resultMap id="rentMap" type="com.myspring.entity.Rent">
<id column="rentid" property="rentid"></id>
<result column="price" property="price"></result>
<result column="begindate" property="begindate"></result>
<result column="returndate" property="returndate"></result>
<result column="carnumber" property="carnumber"></result>
<result column="createtime" property="createtime"></result>
<association property="customer" javaType="com.myspring.entity.Customer">
<result column="identity" property="identity"></result>
<result column="opername" property="custname"></result>
<result column="address" property="address"></result>
<result column="phone" property="phone"></result>
<result column="career" property="career"></result>
</association>
</resultMap>
<!-- <select id="getById" resultType="com.myspring.entity.Rent">-->
<select id="getById" resultMap="rentMap">
select * from rent,customer where rent.identity = customer.identity and rentid=#{rentid}
</select>
</mapper>
java
package com.myspring;
import com.myspring.entity.News;
import com.myspring.entity.Rent;
import com.myspring.mapper.RentMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
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的代理对象
RentMapper mapper = sqlSession.getMapper(RentMapper.class);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");//MM大写,否则会默认输出是00
Rent rent = mapper.getById("R2024001");
System.out.println(simpleDateFormat.format(rent.getCreatetime()));
System.out.println(rent);
System.out.println(rent.getCustomer());
}
}
三、MyBatis延迟加载
延迟加载,又叫惰性加载,懒加载、按需加载,提升程序运行效率的方式。
持久层(访问数据库)原则:Java程序和数据库交互频率越低越好
MyBatis通过延迟加载来减少Java和数据库交互次数。
Class和Student
查询Student,会将对应的Class数据一并查出。
延迟加载的思路:如果只是需要Student中的name,不调用Class中的,那么就只执行一条SQL语句;如果需要知道Class相关字段,就需要执行两条SQL语句。
sql
select * from student where id =1;
select * from class where id =2;
根据具体的需求,动态选择执行SQL的条数。
MySQL 关系型数据库
ORM框架(Object Relationship Mapping)关联关系型数据库和面向对象编程语言
3.1 创建实体类
java
package com.myspring.entity;
import lombok.Data;
import java.util.List;
@Data
public class Class {
private Integer id;
private String name;
private List<Student> students;//一个班级有多个学生
}
java
package com.myspring.entity;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private Class clazz; //关联Class表,一个学生只能属于一个班级
}
3.2 创建Mapper接口及mapper.xml
java
package com.myspring.mapper;
import com.myspring.entity.Class;
public interface ClassMapper {
public Class getById(Integer id);
}
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">
<select id="getById" parameterType="java.lang.Integer" resultType="com.myspring.entity.Class">
select * from class where id = #{id};
</select>
</mapper>
java
package com.myspring.mapper;
import com.myspring.entity.Student;
public interface StudentMapper {
public Student getById(Integer id);
}
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.StudentMapper">
<select id="getById" parameterType="java.lang.Integer" resultType="com.myspring.entity.Student">
select * from student where id = #{id};
</select>
</mapper>
此时我希望,在查询Student字段时,cid对应class的值也能被查出来(不是2,而是对应的"二班"),修改StudentMapper.xml文件
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.StudentMapper">
<!-- <select id="getById" parameterType="java.lang.Integer" resultType="com.myspring.entity.Student">-->
<!-- select * from student where id = #{id};-->
<!-- </select>-->
<resultMap id="studentMap" type="com.myspring.entity.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<association property="clazz" javaType="com.myspring.entity.Class" column="cid" select="com.myspring.mapper.ClassMapper.getById">
</association>
</resultMap>
<select id="getById" parameterType="java.lang.Integer" resultMap="studentMap">
select * from student where id = #{id}
</select>
</mapper>
3.3 config.xml文件
XML
<!--注意:是/不是. 写错了会报错:找不到;文件名后缀也要带上-->
<mapper resource="com/myspring/mapper/StudentMapper.xml"></mapper>
<mapper resource="com/myspring/mapper/ClassMapper.xml"></mapper>
注意:修改成对应的数据库名。

3.4 测试
java
package com.myspring;
import com.myspring.entity.News;
import com.myspring.entity.Rent;
import com.myspring.entity.Student;
import com.myspring.mapper.RentMapper;
import com.myspring.mapper.StudentMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
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的代理对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.getById(1);
System.out.println(student);
}
}
3.5 结果

此时,我们只想获取student表的信息name,不调用class表的。
java
System.out.println(student.getName());

仍然会调用两条SQL语句,浪费。
使用懒加载可以解决该问题。
3.6 config.xml中开启懒加载
XML
<!--懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>

再次运行看结果:只执行了一条SQL语句
