mybatis中多對多的步驟 示例:用戶和角色,一個用戶可以有多個角色,一個角色可以賦予多個用戶 步驟: 1. 建立兩張表:用戶表,角色表,讓用戶表和角色表具有多對多的關係,需要使用中間表,中間表中包含兩張表的主鍵,在中間表中是外鍵 2. 建立兩個實體類:用戶實體類和角色實體類,讓用戶和角色的實體類 ...
mybatis中多對多的步驟
示例:用戶和角色,一個用戶可以有多個角色,一個角色可以賦予多個用戶
步驟:
- 建立兩張表:用戶表,角色表,讓用戶表和角色表具有多對多的關係,需要使用中間表,中間表中包含兩張表的主鍵,在中間表中是外鍵
- 建立兩個實體類:用戶實體類和角色實體類,讓用戶和角色的實體類能體現出來多對多的關係,各自包含對方一個集合引用
- 建立兩個配置文件,用戶的配置文件,角色的配置文件
- 實現配置:當我們查詢用戶時,可以同時得到用戶所包含的角色信息,當我們查詢角色時,可以同時得到角色的所賦予的用戶信息
資料庫表的創立
實體類的建立
用戶實體類
package com.itheima.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
角色實體類
package com.itheima.domain;
import java.io.Serializable;
public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"roleId=" + roleId +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
映射文件配置
用戶映射文件
<?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.itheima.dao.IUserDao">
<!--定義User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</resultMap>
<!-- 查詢所有 -->
<select id="findAll" resultMap="userAccountMap">
SELECT * FROM USER u LEFT OUTER JOIN account a ON u.id=a.uid;
</select>
<!-- 根據id查詢用戶 -->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
</mapper>
角色映射文件
<?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.itheima.dao.IRoleDao">
<!--定義role表的ResultMap-->
<resultMap id="roleMap" type="role">
<id property="roleId" column="id"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</resultMap>
<!--查詢所有-->
<select id="findAll" resultMap="roleMap">
select * from role;
</select>
</mapper>
測試類
package com.itheima.test;
import com.itheima.dao.IRoleDao;
import com.itheima.dao.IUserDao;
import com.itheima.domain.Role;
import com.itheima.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
/**
* @author 黑馬程式員
* @Company http://www.ithiema.com
*
* 測試mybatis的crud操作
*/
public class RoleTest {
private InputStream in;
private SqlSession sqlSession;
private IRoleDao roleDao;
@Before//用於在測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置文件,生成位元組輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.獲取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.獲取SqlSession對象
sqlSession = factory.openSession(true);
//4.獲取dao的代理對象
roleDao = sqlSession.getMapper(IRoleDao.class);
}
@After//用於在測試方法執行之後執行
public void destroy()throws Exception{
//提交事務
// sqlSession.commit();
//6.釋放資源
sqlSession.close();
in.close();
}
@Test
//查詢所有賬戶,同時包含用戶名稱和地址
public void testFindAllAccountUser(){
List<Role> roles = roleDao.findAll();
for(Role role:roles){
System.out.println(role);
}
}
}
單表操作成功
實現配置:當我們查詢角色時,可以同時得到角色的所賦予的用戶信息
首先實體類需要添加一個屬性
private List<User> users;
SQL語句的寫法
SELECT u.*,r.id AS rid ,r.role_name,role_desc FROM role r
LEFT OUTER JOIN user_role ur ON r.id=ur.rid
LEFT OUTER JOIN USER u ON u.id = ur.uid;
有了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.itheima.dao.IUserDao">
<!--定義User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</resultMap>
<!-- 查詢所有 -->
<select id="findAll" resultMap="userAccountMap">
SELECT * FROM USER u LEFT OUTER JOIN account a ON u.id=a.uid;
</select>
<!-- 根據id查詢用戶 -->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
</mapper>
實現配置:當我們查詢用戶時,可以同時得到用戶所包含的角色信息,
SQL語句寫法
SELECT u.*,r.id AS rid ,r.role_name,role_desc FROM USER u
LEFT OUTER JOIN user_role ur ON u.id=ur.uid
LEFT OUTER JOIN role r ON r.id = ur.rid;
略
JNDI
JNDI(Java Naming and Directory Interface Java命名和目錄介面)是SUN公司提供的一種標準的Java命名系統介面。目的是模仿windows系統中的註冊表
Mybatis中的延遲載入
問題:在一對多中,當我們有一個用戶,他有100個賬戶。在查詢用戶的時候,要不要把關聯的賬戶查出來?在查詢賬戶的時候,要不要把關聯的用戶查出來?
在查詢用戶時,用戶下的賬戶信息應該是,什麼時候使用,什麼時候載入。
在查詢賬戶時,賬戶的所屬用戶信息應該是隨著賬戶查詢是一起查詢出來。
什麼是延遲載入:在真正使用數據時才發起查詢,不用的時候不查詢,按需載入(懶載入)0.
什麼是立即載入:不管用不用,只要一調用方法,馬上發起查詢。
在對應的四種表關係中:一對多,多對多通常採用延遲載入,多對一,一對一:通常採用立即載入。
Mybatis中的緩存
什麼是緩存:存在於記憶體中的 臨時數據
一級緩存:指定是Mybatis中SqlSession對象的緩存,當我們執行查詢後,查詢的結果會同時存入到SqlSession為我們提供一塊區域中,該區域的結構是一個map。當我們再次查詢同樣的數據,mybatis會先去sqlsession中查詢是否有,有的話直接拿出來用,當SqlSession對象消失是,mybatis一級緩存也就消失了
二級緩存:它指的是Mybatis中SqlSessionFactory對象的 緩存,由同一個SqlSessionFactory對象創建的SqlSession共用其緩存
二級 緩存的使用步驟:
第一步:讓Mybatis框架支持二級緩存(SqlMapConfig.xml中配置)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
第二步:讓當前的映射文件支持二級緩存(在IUserDao.xml中配置)
<!--開啟user支持二級緩存-->
<cache/>
第三步:讓當前的操作支持二級緩存(select標簽中配置)
<!-- 根據id查詢用戶 -->
<select id="findById" parameterType="INT" resultType="user" useCache="true">
select * from user where id = #{uid}
</select>
test類
public void testFirstLevelCache(){
SqlSession sqlSession1 = factory.openSession();
IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
User user1 = dao1.findById(41);
System.out.println(user1);
sqlSession1.close();//一級緩存消失
SqlSession sqlSession2 = factory.openSession();
IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
User user2 = dao2.findById(41);
System.out.println(user2);
sqlSession2.close();
System.out.println(user1 == user2);
}
mybatis使用註解開發
package com.itheima.dao;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
//在mybatis中,有CRUD一共四個註解
//@Select @Insert @Update @Delete
public interface IUserDao {
//查詢所有
@Select("select * from user")
List<User> findAll();
}