我们通常说的关联关系有以下四种,一对多关联,多对一关联,一对一关联,多对多关联。关联关系是有方向的。如果是高并发的场景中,不适合做表的关联。
在多对一和一对多的关联关系中,使用订单表和客户表来描述问题。
接口代码:
//根据客户id查询客户所有信息,并同时查询客户的所有订单信息
Customer getById(Integer id);
xml文件的查询语句:
<mapper namespace="com.lcl.mapper.CustomerMapper">
<resultMap id="customermap" type="customer">
<id property="id" column="cid">id>
<result property="name" column="name">result>
<result property="age" column="age">result>
<collection property="ordersList" ofType="orders">
<id property="id" column="oid">id>
<result property="orderNumber" column="orderNumber">result>
<result property="orderPrice" column="orderPrice">result>
collection>
resultMap>
<select id="getById" parameterType="int" resultMap="customermap">
select c.id cid,name,age,o.id oid,orderNumber,orderPrice,customer_id
from customer c left join orders o on c.id = o.customer_id
where c.id = #{id}
select>
mapper>
测试方法:
public class MyTest {
SqlSession sqlSession;
@Before
public void getSqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
sqlSession = factory.openSession();
}
@After
public void closeSqlSession(){
sqlSession.close();
}
/*
根据客户id查询客户所有信息,并同时查询客户的所有订单信息
Customer getById(Integer id);
实现的是一对多的查询
*/
@Test
public void testCustomerGetById(){
CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class);
Customer customer = customerMapper.getById(3);
System.out.println(customer);
}
}
接口代码:
//根据主键查询订单,同时查询此订单下的客户信息
Orders getById(Integer id);
xml文件的查询语句:
<mapper namespace="com.lcl.mapper.OrdersMapper">
<resultMap id="ordersmap" type="orders">
<id property="id" column="oid">id>
<result property="orderNumber" column="orderNumber">result>
<result property="orderPrice" column="orderPrice">result>
<association property="customer" javaType="customer">
<id property="id" column="cid">id>
<result property="name" column="name">result>
<result property="age" column="age">result>
association>
resultMap>
<select id="getById" resultMap="ordersmap">
select o.id oid,orderNumber,orderPrice,customer_id,c.id cid,name,age
from orders o inner join customer c on customer_id = c.id
where o.id = #{id}
select>
mapper>
测试方法:
public class MyTest {
SqlSession sqlSession;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Before
public void getSqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
sqlSession = factory.openSession();
}
@After
public void closeSqlSession(){
sqlSession.close();
}
/*
根据主键查询订单,同时查询此订单下的客户信息
Orders getById(Integer id);
实现的是多对一的查询
*/
@Test
public void testOrdersGetById(){
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
Orders orders = ordersMapper.getById(11);
System.out.println(orders);
}
}
实体类准备:
主要上以下几种方法
<mapper namespace="com.lcl.mapper.TeacherMapper">
<resultMap id="teachermap" type="teacher">
<id property="tid" column="tid">id>
<result property="tname" column="tname">result>
<result property="tage" column="tage">result>
<association property="classes" javaType="classes">
<id property="cid" column="cid">id>
<result property="cname" column="cname">result>
association>
resultMap>
<select id="findTeacherMessage" resultMap="teachermap">
select tid,tname,tage,cid,cname
from teacher inner join classes on tid = ctid
select>
mapper>
测试代码:
public class MyTest {
SqlSession sqlSession;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Before
public void getSqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
sqlSession = factory.openSession();
}
@After
public void closeSqlSession(){
sqlSession.close();
}
//查询全部图书,并且查询图书所属的全部类型
//List findAll();
//实现的时多对多的查询
@Test
public void testFindAll(){
BooksMapper booksMapper = sqlSession.getMapper(BooksMapper.class);
List<Books> booksList = booksMapper.findAll();
booksList.forEach(books -> System.out.println(books));
}
//查询教师全部信息,并且返回教师所教授知识的位置
//Teacher findTeacherMessage();
//实现一对一的查询
@Test
public void testFindTeacherMessage(){
TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
List<Teacher> teacherList = teacherMapper.findTeacherMessage();
teacherList.forEach(teacher -> System.out.println(teacher));
}
}
实体类创建:
主要上以下几种方法
//查询教师全部信息,并且返回教师所教授知识的位置
List<Teacher> findTeacherMessage();
xml文件中查询语句
<mapper namespace="com.lcl.mapper.TeacherMapper">
<resultMap id="teachermap" type="teacher">
<id property="tid" column="tid">id>
<result property="tname" column="tname">result>
<result property="tage" column="tage">result>
<association property="classes" javaType="classes">
<id property="cid" column="cid">id>
<result property="cname" column="cname">result>
association>
resultMap>
<select id="findTeacherMessage" resultMap="teachermap">
select tid,tname,tage,cid,cname
from teacher inner join classes on tid = ctid
select>
mapper>
测试代码:
public class MyTest {
SqlSession sqlSession;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Before
public void getSqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
sqlSession = factory.openSession();
}
@After
public void closeSqlSession(){
sqlSession.close();
}
//查询教师全部信息,并且返回教师所教授知识的位置
//Teacher findTeacherMessage();
//实现一对一的查询
@Test
public void testFindTeacherMessage(){
TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
List<Teacher> teacherList = teacherMapper.findTeacherMessage();
teacherList.forEach(teacher -> System.out.println(teacher));
}
}
在进行数据库访问时,首先去访问缓存,如果缓存中有要访问的数据,则直接返回客户端,如果没有则去访问数据库,在库中得到数据后,先在缓存放一份,再返回客户端。如下图。
注意:mybaits提供一级缓存和二级缓存。默认开启一级缓存。
第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。如果sqlSession去执行commit操作(执行插入、更新、删除),则清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。如果没有重复第一次查询操作。如下图。
@Test
public void testCacheOne() {
//一级缓存基于SqlSession的
//取出用户ID为7的用户
Users u1 = mapper.getById(7);
System.out.println("第一次访问数据库得到的u=" + u1);
//再取一次,看看有没有访问数据库,就知道开没有开启一级缓存
Users u2 = mapper.getById(7);
System.out.println("第二次访问数据库得到的u=" + u2);
}
@Test
public void testCacheOneClose() {
//一级缓存基于SqlSession的
//取出用户ID为7的用户
Users u1 = mapper.getById(7);
System.out.println("第一次访问数据库得到的u=" + u1);
//关闭session,也会清除缓存
session.close();
//再取一次,看看有没有访问数据库,就知道开没有开启一级缓存
session = factory.openSession();
mapper = session.getMapper(UsersMapper.class);
Users u2 = mapper.getById(7);
System.out.println("第二次访问数据库得到的u=" + u2);
}
@Test
public void testCacheOneCommit() {
//一级缓存基于SqlSession的
//取出用户ID为7的用户
Users u1 = mapper.getById(7);
System.out.println("第一次访问数据库得到的u=" + u1);
//完成数据更新操作
int num = mapper.update(new Users(38, "abc", new Date(), "1", "朝阳"));
session.commit();
System.out.println(num + "==================");
Users u2 = mapper.getById(7);
System.out.println("第二次访问数据库得到的u=" + u2);
ORM(Object Relational Mapping):对象关系映射
MyBatis框架是ORM非常优秀的框架.
ORM含义描述:java语言中以对象的方式操作数据,存到数据库中是以表的方式进行存储,对象中的成员变量与表中的列之间的数据互换称为映射.整个这套操作就是ORM.
持久化的操作:将对象保存到关系型数据库中 ,将关系型数据库中的数据读取出来以对象的形式封装