String与基本数据类型 _parameter
自定义类型(对象) 属性名
集合
数组 array
List list
Map _parameter
获取集合中的一条数据
数组 array[索引] 基本数据类型数组
array[索引].属性名 对象数据类型数组
List list[索引]
list[索引].属性名
Map _parameter.key
_parameter.key.属性名
利用foreach标签从集合中取出数据(遍历拼接SQL)
<foreach collection="array" index="i" item="item" separator=",">
</foreach>
如果collection中的数组或List,i表示下标,如果collection是Map,i表示key。item(或item.属性名)表示迭代出来的值
separator 表示 迭代出来的元素之间的分隔符
例如:
1、list集合
<delete id="deleteBatch" parameterType="java.util.List">
delete from MESSAGE where ID in(
<foreach collection="list" item="item" separator=",">
#{item}
</foreach>
)
</delete>
2、map 集合:username 和password对应map中的key
<select id="selectAllUser" parameterType="map" resultType="cn.jpp.entity.UserInfo">
select * from user where username=#{username} and password=#{password}
</select>
操作符
java常用操作符 +、-、*、/、==、!=、||、&&等
特有操作符 and、or、mod、in、not in
2、MyBatis表与表之间的关系
2.1、多对一【包括一对一】(Account==>User)
package com.yuan.doman;
import java.util.Date;
import java.util.List;
public class User {
private Integer id;
/**
* 用户姓名
*/
private String username;
/**
* 用户生日
*/
private Date birthday;
/**
* 用户性别
*/
private String sex;
/**
* 用户地址
*/
private String address;
/**
*角色下的账户集合
* @return
*/
private List<Account> roles;
//Get() Set() 方法
}
映射文件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.yuan.dao.AccountDao">
<!--配置一对多关系的resultMap-->
<resultMap id="accountUserMap" type="account">
<!--id是唯一标识-->
<!--type是对应的实体类-->
<id column="aid" property="id"/>
<!--id是主键-->
<!--result是普通列-->
<!--column是数据库列名-->
<!--property是属性名-->
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!--association对应主表关系-->
<!--property表示外键属性是User-->
<!--column表示用uid字段来获取-->
<!--javaType表示返回的Java类型是什么-->
<association property="user" column="uid" javaType="com.yuan.doman.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<!--查询全部Account-->
<select id="findAll" resultMap="accountUserMap">
SELECT a.id as AID,a.UID,a.MONEY,u.* from account a,user u where u.id = a.UID
</select>
</mapper>
单元测试:
package com.yuan.test;
import com.yuan.dao.AccountDao;
import com.yuan.doman.Account;
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.IOException;
import java.io.InputStream;
import java.util.List;
public class AccountDaoTest {
InputStream is = null;
SqlSessionFactory factory = null;
SqlSession session = null;
AccountDao accountDao = session.getMapper(AccountDao.class);
@Before
public void init() throws IOException {
//读取配置文件
is = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
factory = new SqlSessionFactoryBuilder().build(is);
//生产SQLSession对象
session = factory.openSession();
}
@After
public void close() throws IOException {
session.commit();
session.close();
is.close();
}
@Test
public void finAllAccount() {
List<Account> accountAll = accountDao.findAll();
for (Account account : accountAll) {
System.out.println("---------------");
System.out.println("account = " + account);
System.out.println(account.getUser());
}
}
}
2.2 一对多
实体类:
package com.yuan.doman;
import java.util.Date;
import java.util.List;
public class User {
private Integer id;
/**
* 用户姓名
*/
private String username;
/**
* 用户生日
*/
private Date birthday;
/**
* 用户性别
*/
private String sex;
/**
* 用户地址
*/
private String address;
/**
*角色下的账户集合
* @return
*/
private List<Account> roles;
//Get() Set() 方法
}
映射文件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.yuan.dao.UserDao">
<sql id="defUser">
SELECT u.*,a.ID as aid,A.MONEY
FROM USER u LEFT JOIN ACCOUNT a
ON a.UID = u.id
</sql>
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!--账户定义集合-->
<!--property 集合属性名-->
<!--ofType 集合的泛型-->
<collection property="accounts" ofType="com.yuan.doman.Account">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
</collection>
</resultMap>
<!--查询全部User-->
<select id="findAll" resultMap="userAccountMap">
<include refid="defUser"/>
</select>
<!--根据ID查询User-->
<select id="findById" resultMap="userAccountMap" parameterType="int">
<include refid="defUser"/>
<where>
ID = #{id}
</where>
</select>
</mapper>
单元测试:
package com.yuan.test;
import com.yuan.dao.UserDao;
import com.yuan.doman.Account;
import com.yuan.doman.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.IOException;
import java.io.InputStream;
import java.util.List;
public class UserDaoTest {
InputStream is = null;
SqlSessionFactory factory = null;
SqlSession session = null;
@Before
public void init() throws IOException {
//读取配置文件
is = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
factory = new SqlSessionFactoryBuilder().build(is);
//生产SQLSession对象
session = factory.openSession();
}
@After
public void close() throws IOException {
session.commit();
session.close();
is.close();
}
@Test
public void finAllAccount() {
UserDao userDao = session.getMapper(UserDao.class);
List<User> userAccounts = userDao.findAll();
for (User userAccount : userAccounts) {
System.out.println("------------------------");
System.out.println("userAccount = " + userAccount);
if (!(userAccount.getAccounts().size()<=0)) {
for (Account account : userAccount.getAccounts()) {
System.out.println("account = " + account);
}
}
}
}
}
2.3、多对对
package com.yuan.doman;
import java.util.List;
public class Role {
private Integer id;
private String role_name;
private String role_desc;
/**
* 角色对应的账户结合
*/
private List<User> users;
//Get() Set() 方法
}
package com.yuan.doman;
import java.util.Date;
import java.util.List;
public class User{
private Integer id;
/**
* 用户姓名
*/
private String username;
/**
* 用户生日
*/
private Date birthday;
/**
* 用户性别
*/
private String sex;
/**
* 用户地址
*/
private String address;
/**
*角色下的账户集合
* @return
*/
private List<Role> roles;
//Get() Set() 方法
}
映射文件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.yuan.dao.RoleDao">
<resultMap id="roleUserMap" type="role">
<id property="id" column="rid"></id>
<result property="role_name" column="role_name"/>
<result property="role_desc" column="role_desc"/>
<collection property="users" ofType="user">
<id property="id" column="UID"></id>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
</collection>
</resultMap>
<!--查询全部User-->
<select id="findAll" resultMap="roleUserMap">
SELECT
r.id as rid
,r.ROLE_NAME
,r.ROLE_DESC
,u.id AS UID
,u.username
,u.sex
,u.address
,u.birthday
from role r
LEFT JOIN user_role ur ON r.ID = ur.RID
LEFT JOIN user u ON u.id = ur.UID
</select>
<!--根据ID查询User-->
<select id="findById" resultMap="roleUserMap" parameterType="int">
</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.yuan.dao.UserDao">
<resultMap id="userRolestMap" type="user">
<id property="id" column="uid"></id>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<collection property="roles" ofType="role">
<id property="id" column="rid"></id>
<result property="role_name" column="role_name"/>
<result property="role_desc" column="role_desc"/>
</collection>
</resultMap>
<!--查询全部User-->
<select id="findAll" resultMap="userRolestMap">
SELECT
u.id AS UID
,u.username
,u.sex
,u.address
,u.birthday
,r.id as rid
,r.ROLE_NAME
,r.ROLE_DESC
from user u
LEFT JOIN user_role ur ON u.ID = ur.UID
LEFT JOIN role r ON r.ID = ur.RID
</select>
<!--根据ID查询User-->
<select id="findById" resultMap="userRolestMap" parameterType="int">
</select>
</mapper>
3、 利用注解的方式实现表与表之间的关系
3.1 编写实体类(User.java)
package com.yuan.doman;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
private Integer id;
/**
* 用户姓名
*/
private String username;
/**
* 用户生日
*/
private Date birthday;
/**
* 用户性别
*/
private String sex;
/**
* 用户地址
*/
private String address;
/**
* 用户下的账户信息
*/
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
/**
*用户下的角色集合
* @return
*/
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
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 Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
3.2、实体类(Account.java)
package com.yuan.doman;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
/**
* 用户Id
*/
private Integer uid;
/**
* 账户余额
*/
private Double money;
/**
* 所属用户【这个数据库中表没有】
*/
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
", user=" + user +
'}';
}
}
3.3 实体类(Role.java)
package com.yuan.doman;
import java.io.Serializable;
import java.util.List;
public class Role implements Serializable {
private Integer id;
/**
* 角色名
*/
private String role_name;
/**
* 角色权限
*/
private String role_desc;
/**
* 角色对应的账户结合
*/
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getRole_desc() {
return role_desc;
}
public void setRole_desc(String role_desc) {
this.role_desc = role_desc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", role_name='" + role_name + '\'' +
", role_desc='" + role_desc + '\'' +
'}';
}
}
3.4、编写持久化接口
3.4.1、UserDao.java
package com.yuan.dao;
import com.yuan.doman.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* ,用户的持久层接口
*/
public interface UserDao {
/**
* 查询所有用户
*
* @return
*/
@Select("select * from user")
@Results(
id = "userMap",
value = {
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "sex", property = "sex"),
@Result(column = "address", property = "address"),
@Result(column = "birthday", property = "birthday")
}
)
List<User> findAll();
/**
* 根据 id 查询一个用户
*
* @param userId
* @return
*/
@Select("select * from user where id = #{uid} ")
@ResultMap("userMap")
User findById(Integer userId);
/**
* 保存操作
*
* @param user
* @return
*/
@Insert("insert into user(username,sex,birthday,address)values(#{username},#{sex},#{birthday},#{address} )")
@SelectKey(
keyColumn = "id",
keyProperty = "id",
resultType = Integer.class,
before = false,
statement = {"select last_insert_id()"}
)
int saveUser(User user);
/**
* 更新操作
*
* @param user
* @return
*/
@Update("update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id =#{id} ")
int updateUser(User user);
/**
* 删除用户
*
* @param userId
* @return
*/
@Delete("delete from user where id = #{uid} ")
int deleteUser(Integer userId);
/**
* 查询使用聚合函数
*
* @return
*/
@Select("select count(*) from user ")
int findTotal();
/**
* 模糊查询
*
* @param name
* @return
*/
@Select("select * from user where username like #{username} ")
List<User> findByName(String name);
}
3.4.2 AccountDao.java
package com.yuan.dao;
import com.yuan.doman.Account;
import java.util.List;
public interface AccountDao {
/**
* 查询所有账户
* @return
*/
List<Account> findAll();
/**
* 查询所有账户
* @param aid
* @return
*/
Account findByUid(Integer aid);
}
3.4.3、RoleDao.java
package com.yuan.dao;
import com.yuan.doman.Role;
import com.yuan.doman.User;
import java.util.List;
/**
* ,用户的持久层接口
*/
public interface RoleDao {
/**
* 全查User
*
* @return
*/
List<Role> findAll();
/**
* 查询UserId
*
* @param rid
*/
Role findById(Integer rid);
}
3.5、编写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入外部配置文件-->
<properties resource="jdbc.properties">
</properties>
<settings>
<!-- 延迟加载的全局开关 默认关闭 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- <setting name="aggressiveLazyLoading" value="true"/>-->
</settings>
<!--别名包-->
<typeAliases>
<package name="com.yuan.doman"/>
</typeAliases>
<!--配置环境-->
<environments default="def">
<!--配置默认环境-->
<environment id="def">
<!--配置JDBC事务-->
<transactionManager type="JDBC"></transactionManager>
<!--配置POOLED连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<mappers>
<!--引入映射文件-->
<package name="com.yuan.dao"/>
</mappers>
</configuration>
3.6、测试
package com.yuan.test;
import com.yuan.dao.UserDao;
import com.yuan.doman.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.IOException;
import java.io.InputStream;
import java.util.List;
public class UserDaoTest {
InputStream is = null;
SqlSessionFactory factory = null;
SqlSession session = null;
UserDao userDao = null;
@Before
public void init() throws IOException {
//读取配置文件
is = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂
factory = new SqlSessionFactoryBuilder().build(is);
//生产SQLSession对象
session = factory.openSession();
userDao = session.getMapper(UserDao.class);
}
@After
public void close() throws IOException {
session.commit();
session.close();
is.close();
}
@Test
public void finAllTest() {
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println("user = " + user);
}
}
@Test
public void findByIdTest() {
User user = userDao.findById(61);
System.out.println(user);
}
@Test
public void saveUserTest() {
final User user = new User();
user.setUsername("GiaoWin");
System.out.println(user.getUsername()+"------------");
userDao.saveUser(user);
System.out.println(user.getId()+"------------");
}
@Test
public void updateUserTest() {
final User user = new User();
user.setId(61);
user.setUsername("GiaoWinner");
userDao.updateUser(user);
System.out.println(user.getUsername()+"------------");
}
@Test
public void deleteUserTest() {
System.out.println(userDao.deleteUser(61));
}
@Test
public void findTotalTest() {
System.out.println(userDao.findTotal());
}
@Test
public void findByNameTest() {
List<User> users = userDao.findByName("Giao%");
for (User user : users) {
System.out.println("user = " + user);
}
}
}
3.7、MyBatis表与表之间的关系【注解实现】(多对一)
这里只有接口文件有和测试文件变化
3.7.1、接口(UserDao.java)
package com.yuan.dao;
import com.yuan.doman.User;
import org.apache.ibatis.annotations.*;
@CacheNamespace
public interface UserDao {
/**
* 根据用户Id返回该用户
* @param uid
* @return
*/
@Select("select * from user where id = #{id}")
User findById(Integer uid);
}
package com.yuan.dao;
import com.yuan.doman.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
//开启二级缓存
@CacheNamespace(blocking = true)
public interface UserDao {
/**
* 查询用户及其下属账户
* @return
*/
@Select("select * from user")
@Results(value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "id",property = "accounts",
//配置一对多
many = @Many(select = "com.yuan.dao.AccountDao.findByUid",
//配置延迟加载
fetchType = FetchType.LAZY
))
})
List<User> findAll();
}
3.7.2、AccountDao.java
package com.yuan.dao;
import com.yuan.doman.Account;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface AccountDao {
/**
* 查询账户以及所属用户
* @return
*/
@Select("select * from account")
@Results(value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "uid",property = "user",
one = @One(select = "com.yuan.dao.UserDao.findById",
fetchType = FetchType.EAGER)
)
})
List<Account> findAll();
}
package com.yuan.dao;
import com.yuan.doman.Account;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface AccountDao {
/**
* 根据用户Id查询 账户信息
* @param uid
* @return
*/
@Select("select * from account where uid = #{uid}")
List<Account> findByUid(Integer uid);
}
3.7.3、单元测试
package com.yuan.test;
import com.yuan.dao.AccountDao;
import com.yuan.doman.Account;
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.IOException;
import java.io.InputStream;
import java.util.List;
public class AccountTest {
InputStream in;
SqlSessionFactory factory;
SqlSession session;
AccountDao accountDao;
@Before
public void before() throws IOException {
//读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//生成Session工厂
factory = new SqlSessionFactoryBuilder().build(in);
//生产Session对象
session = factory.openSession();
//获取Dao对象
accountDao = session.getMapper(AccountDao.class);
}
@After
public void after() throws IOException {
session.commit();
session.close();
in.close();
}
/**
* 一对一查询
* @throws IOException
*/
@Test
public void findAccountAllTest() {
List<Account> accountAll = accountDao.findAll();
for (Account account : accountAll) {
System.out.println("account = " + account);
}
}
}
3.8 常用的注解
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
3.9 复杂的注解
@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合 @Results({@Result(),@Result()})或@Results(@Result())
@Resutl 注解
代替了 <id>标签和<result>标签
@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用来多表查询的
sqlmapper fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
使用格式:
@Result(column=" ",property="",one=@One(select=""))
@Many 注解(多对一)
代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:
聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType (一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))
4、MyBatis的延迟加载
4.1、一对一(多对一)延迟加载
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"/>
<result property="uid" column="uid"/>
<result property="money" column="money"/>
<!--
一(多)对一的关系映射:配置封装user的内容
select属性指定的内容:查询用户的唯一标识:
column属性指定的内容:用户根据id查询时,所需要的参数的值
-->
<association
property="users"
column="uid"
javaType="user"
select="com.yuan.dao.UserDao.findById"
/>
</resultMap>
<!--查询全部Account-->
<select id="findAll" resultMap="accountUserMap">
SELECT * FROM ACCOUNT
</select>
4.2、一对多延迟加载
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!--账户定义集合-->
<!--property 集合属性名-->
<!--ofType 集合的泛型-->
<!--column 用不到不写 现在的作用是把用户的ID作为参数传到账户的查询参数(一对多)-->
<!--select 用的时候调用账户配置文件中的查询方法-->
<collection
property="accounts"
column = "id"
select="com.yuan.dao.AccountDao.findByUid"
ofType="account"/>
</resultMap>
<!--查询全部User-->
<select id="findAll" resultMap="userAccountMap">
SELECT * FROM USER
</select>
5、MyBatis的缓存
像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提 高性能。 Mybatis 中缓存分为一级缓存,二级缓存。
5.1、一级缓存
它指的是Mybatis中SqlSession对象的缓存。
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
查询是否有,有的话直接拿出来用。
当SqlSession对象消失时,mybatis的一级缓存也就消失了。
一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。 默认开启哒!
当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存
5.2、二级缓存
它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存(默认开启)的使用步骤:
第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
<!--开启二级缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
添加标签<cache/>【在映射文件中添加了这个标签就完事了】
第三步: 在select标签添加属性useCache="true"
5.3、注意事项
当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这种就可以使用序列化 方式来保存对象。
小结:
延迟加载的含义:
在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载. 好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速 度要快。
延迟加载的坏处:
因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗 时间,所以可能造成用户等待时间变长,造成用户体验下降。
注解方式如何开启二级缓存
第一步:配置文件开启二级缓存
第二步:在接口文件接口名上添加注解@CacheNamespace(blocking = true)