MyBatis【使用篇】

1.MyBatis簡述

mybatis是一個(gè)優(yōu)秀的基于 java 的持久層框架,它內(nèi)部封裝了 jdbc拇砰,使開發(fā)者只需要關(guān)注 sql語句本身, 而不需要花費(fèi)精力去處理加載驅(qū)動雏门、創(chuàng)建連接柳畔、創(chuàng)建 statement 等繁雜的過程馍管。**

mybatis通過xml 或注解的方式將要執(zhí)行的各種statement配置起來,并通過java對象和statement 中 sql 的動態(tài)參數(shù)進(jìn)行映射生成最終執(zhí)行的 sql 語句薪韩,最后由 mybatis 框架執(zhí)行 sql 并將結(jié)果映射為 java 對象并 返回确沸。

采用 ORM 思想解決了實(shí)體和數(shù)據(jù)庫映射的問題,對 jdbc進(jìn)行了封裝俘陷,屏蔽了 jdbc api 底層訪問細(xì)節(jié)罗捎,使我 們不用與 jdbc api 打交道,就可以完成對數(shù)據(jù)庫的持久化操作拉盾。

2.MyBatis入門之配置文件實(shí)現(xiàn)

2.1.pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yuan</groupId>
    <artifactId>note_mybaties_01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <!--        mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--        單元測試-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <!--            數(shù)據(jù)庫-->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <!--            日志-->
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    </dependencies>

</project>

2.2.編寫實(shí)體類

路徑com/yuan/doman/User.java

package com.yuan.doman;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
    private Integer id;
    /**
     * 用戶姓名
     */
    private String  username;
    /**
     * 用戶生日
     */
    private Date    birthday;
    /**
     * 用戶性別
     */
    private String  sex;
    /**
     * 用戶地址
     */
    private String  address;

    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 + '\'' +
                '}';
    }
}

2.3.編寫持久層接口

路徑:com/yuan/dao/UserDao.java

package com.yuan.dao;

import com.yuan.doman.User;

import java.util.List;

/**
 * 桨菜,用戶的持久層接口
 */
public interface UserDao {

    List<User> findAll();


}

2.4.編寫映射文件

路徑:resources/yuan/dao/UserDao.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">
    <!--findAll方法-->
    <select id="findAll" resultType="com.yuan.doman.User">
        SELECT * FROM USER
    </select>
</mapper>

2.5.編寫配置文件

路徑:resources/SqlMapConfig .xml

<?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>
    <!--環(huán)境配置-->
        <!--默認(rèn)環(huán)境-->
    <environments default="mysql">
        <!--mysql環(huán)境-->
        <environment id="mysql">
            <!--JDBC事務(wù)-->
            <transactionManager type="JDBC"></transactionManager>
            <!--POOLED連接池-->
            <dataSource type="POOLED">
            <!--四大參數(shù)-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///數(shù)據(jù)庫名"/>
                <property name="username" value="數(shù)據(jù)庫賬戶"/>
                <property name="password" value="數(shù)據(jù)庫密碼"/>
            </dataSource>
        </environment>
    </environments>

<mappers>
    <mapper resource="com/yuan/dao/UserDao.xml"/>
</mappers>
</configuration>

2.6.注意事項(xiàng)

第一個(gè):創(chuàng)建UserDao.xml 和 UserDao.java時(shí)名稱是為了和我們之前的知識保持一致。
在Mybatis中它把持久層的操作接口名稱和映射文件也叫做:Mapper
所以:UserDao 和 UserMapper是一樣的
第二個(gè):在idea中創(chuàng)建目錄的時(shí)候盾剩,它和包是不一樣的
包在創(chuàng)建時(shí):com.yuan.dao它是三級結(jié)構(gòu)
目錄在創(chuàng)建時(shí):com.yuan.dao是一級目錄
第三個(gè):mybatis的映射配置文件位置必須和dao接口的包結(jié)構(gòu)相同
第四個(gè):映射配置文件的mapper標(biāo)簽namespace屬性的取值必須是dao接口的全限定類名
第五個(gè):映射配置文件的操作配置(select)雷激,id屬性的取值必須是dao接口的方法名
第六個(gè):當(dāng)我們遵從了第三,四告私,五點(diǎn)之后屎暇,我們在開發(fā)中就無須再寫dao的實(shí)現(xiàn)類。

2.7.測試

package com.yuan.test;

import com.yuan.dao.UserDao;
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;

public class UserDaoTest {
    InputStream is = null;
    SqlSessionFactory factory = null;
    SqlSession session = null;

    @Before
    public void init() throws IOException {
        //讀取配置文件
        is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)SQLSession對象
        session = factory.openSession();
    }
    
    @After
    public void close() throws IOException {
        session.commit();
        session.close();
        is.close();
    }

    @Test
    public void findAllTest(){
        UserDao userDao = session.getMapper(UserDao.class);
        System.out.println(userDao.findAll());
    }

}

3.MyBatis入門之注解實(shí)現(xiàn)

3.1.pom.xml

與2.1相同

3.2.編寫實(shí)體類

與2.2相同

3.3.編寫持久層接口

package com.yuan.dao;

import com.yuan.doman.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * 用戶的持久層接口
 */
public interface UserDao {

    @Select("SELECT * FROM USER")
    List<User> findAll();


}

3.4.編寫配置文件

與2.5大致相同【唯一不同】

<mappers>
    <mapper class="com.yuan.dao.UserDao"/>
</mappers>

3.5.測試

與2.7相同

4.小結(jié)1

開發(fā)時(shí)要不要寫持久層實(shí)現(xiàn)類驻粟?

不寫根悼,怎么簡單怎么來凶异,怎么快怎么來,怎么好維護(hù)怎么來

開發(fā)時(shí)用注解還是用xml文件挤巡?

老項(xiàng)目一般用xml剩彬,最近項(xiàng)目都是注解開發(fā),同一個(gè)Dao接口不能既用注解又用xml

項(xiàng)目中如何獲取路徑

一般使用兩種方法

1.使用類加載器矿卑,它只能讀取類路徑的配置文件

2.使用servletContext的getRealPath()方法

案例分析 .png

5.基于配置文件的增刪改查

5.1.持久層接口

package com.yuan.dao;

import com.yuan.doman.User;

import java.util.List;

/**
 * 用戶的持久層接口
 */
public interface UserDao {

    /**
     * 全查User
     *
     * @return
     */
    List<User> findAll();

    /**
     * 查詢UserId
     *
     * @param uid
     */
    User findById(Integer uid);

    /**
     * 查詢UserName
     *
     * @param username
     */
    List<User> findLikeName(String username);

    /**
     * 查詢User總數(shù)
     *
     * @return int
     */
    Integer findTotalId();

    /**
     * 新增User
     *
     * @param user
     */
    void save(User user);

    /**
     * 修改User
     *
     * @param user
     */
    void update(User user);

    /**
     * 刪除User
     *
     * @param uid
     */
    void delete(Integer uid);


}

5.2.映射文件

<?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">

    <!--查詢?nèi)縐ser-->
    <select id="findAll" resultType="com.yuan.doman.User">
        SELECT * FROM USER
    </select>

    <!--查詢單個(gè)User-->
    <select id="findById" resultType="com.yuan.doman.User" parameterType="int">

        SELECT * FROM USER WHERE ID = #{id}
    </select>

    <!--Like查詢UserName-->
    <select id="findLikeName" resultType="com.yuan.doman.User" parameterType="string">
        SELECT * FROM USER WHERE USERNAME LIKE #{uname};
    </select>

    <!--查詢User總數(shù)-->
    <select id="findTotalId" resultType="int">
        SELECT count(*) FROM USER
    </select>

    <!--新增User-->
    <insert id="save" parameterType="com.yuan.doman.User">
        <!--拿到返回的ID-->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            SELECT Last_INSERT_ID();
        </selectKey>
                INSERT INTO USER(username,birthday,sex, address) VALUE (#{username},#{birthday},#{sex},#{address});
    </insert>

<!--    更新User根據(jù)ID-->
    <update id="update" parameterType="com.yuan.doman.User">
        UPDATE USER SET USERNAME = #{username} WHERE ID = #{id}
    </update>

    <!--刪除User根據(jù)ID-->
    <update id="delete" parameterType="Integer">
        delete FROM user WHERE ID = #{uid}
    </update>
    
</mapper>

5.3.測試文件

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.Date;

public class UserDaoTest {
    InputStream is = null;
    SqlSessionFactory factory = null;
    SqlSession session = null;

    /**
     * 在Test
     * @throws IOException
     */
    @Before
    public void init() throws IOException {
        //讀取配置文件
        is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)SQLSession對象
        session = factory.openSession();
    }
    
    @After
    public void close() throws IOException {
        session.commit();
        session.close();
        is.close();
    }

    @Test
    public void findAllTest(){
        UserDao userDao = session.getMapper(UserDao.class);
        System.out.println(userDao.findAll());
    }

    @Test
    public void testSave() {
        UserDao userDao = session.getMapper(UserDao.class);
        User user = new User();
        user.setUsername("GiaoWin");
        user.setBirthday(new Date());
        user.setSex("男");
        user.setAddress("張家口");

        System.out.println("保存前 = " + user);
        userDao.save(user);
        System.out.println("保存后 = " + user);
    }


    @Test
    public void testUpdate() {
        UserDao userDao = session.getMapper(UserDao.class);
        User user = new User();
        user.setUsername("AKUMA");
        user.setId(49);
        userDao.update(user);
    }
    @Test
    public void testDelete() {
        UserDao userDao = session.getMapper(UserDao.class);
        userDao.delete(49);
    }

    @Test
    public void testfindById() {
        UserDao userDao = session.getMapper(UserDao.class);
        System.out.println(userDao.findById(46));
    }

    @Test
    public void testfindAll() {
        UserDao userDao = session.getMapper(UserDao.class);
        System.out.println(userDao.findAll());
    }

    @Test
    public void testfindLikeName() {
        UserDao userDao = session.getMapper(UserDao.class);
        userDao.findLikeName("%王%");
    }

    @Test
    public void testfindTotalUser() {
        UserDao userDao = session.getMapper(UserDao.class);
        System.out.println("+++++++++++++++++++++++"+userDao.findTotalId()+"++++++++++++++++++++++++");
    }

}

6.小結(jié)2

#{}h和${}有什么區(qū)別

前者是占位符?喉恋,后者是字符串拼接,會受到SQL注入攻擊

如何拿到保存時(shí)的ID值

    <!--拿到返回的ID-->
    <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
        SELECT Last_INSERT_ID();
    </selectKey>

多個(gè)查詢條件組成一個(gè)對象作為參數(shù)怎么解決母廷?

用一個(gè)包裝類給他們包裝一下轻黑,然后通過NGOL表達(dá)式逐一拿出。

數(shù)據(jù)庫與實(shí)體類中的列名不一致怎么解決琴昆?

1.改正

2.用別名【提升速度】

3.用resultMap【提升開發(fā)速度】

<resultMap id="userMap" type="com.yuan.doman.User">
    <!--    主鍵字段的對應(yīng)    -->
    <id property="Java中的屬性" column="數(shù)據(jù)庫中的列"/>
    <!--    非主鍵字段的對應(yīng)    -->
    <result property="Java中的屬性" column="數(shù)據(jù)庫中的列"/>
</resultMap>
<!--  使用  -->
<select id="findAll" resultMap="userMap">
    SELECT * FROM USER
</select>

SqlMapConfig.xml配置文件常用標(biāo)簽

<!—外部配置文件-->
<propertys>
    <property source="文件路徑"/>
</propertys>

<!--別名映射-->
<typeAliases>
    <!--引入映射包就不用其他的了-->
    <package name="com.yuan.doman " />
    <typeAlias type="com.yuan.doman.User" alias="user"/>
</typeAliases>

如何查看源碼

用Ctrl+Alt+B跟蹤到底層實(shí)現(xiàn)【IDEA工具】

代理Dao的實(shí)現(xiàn)源碼追蹤

/**

- Copyright 2009-2017 the original author or authors.
  *
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
  *
- http://www.apache.org/licenses/LICENSE-2.0
  *
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
  */
  package org.apache.ibatis.binding;

import org.apache.ibatis.annotations.Flush;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ParamNameResolver;
import org.apache.ibatis.reflection.TypeParameterResolver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**

- @author Clinton Begin
- @author Eduardo Macarron
- @author Lasse Voss
  */
  public class MapperMethod {

  private final SqlCommand command;
  private final MethodSignature method;

  public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
    this.command = new SqlCommand(config, mapperInterface, method);
    this.method = new MethodSignature(config, mapperInterface, method);
  }

  public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    switch (command.getType()) {
      case INSERT: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT:
        if (method.returnsVoid() && method.hasResultHandler()) {
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) {
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) {
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) {
          result = executeForCursor(sqlSession, args);
        } else {
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      throw new BindingException("Mapper method '" + command.getName() 
          + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    }
    return result;
  }
}

7.MyBatis連接池

使用了同步代碼快保障了每一個(gè)線程拿到的是不同的連接氓鄙,是一個(gè)線程安全的集合。

主配置文件SqlMapConfig.xml中的dataSource標(biāo)簽业舍,type屬性就是表示采用何種連接池方式抖拦。

? 1.POOLED

? 從池中獲取連接,采用傳統(tǒng)的javax.sql.DataSource規(guī)范中的連接池舷暮,mybatis中有針對規(guī)范的實(shí)現(xiàn)

? 2.UNPOOLE

? 每次new一個(gè)連接态罪,采用傳統(tǒng)的獲取連接的方式,雖然也實(shí)現(xiàn)Javax.sql.DataSource接口下面,但是并沒有使用池的思想向臀。

? 3.JNDI

采用服務(wù)器提供的JNDI技術(shù)實(shí)現(xiàn),來獲取DataSource對象诸狭,不同的服務(wù)器所能拿到DataSource是不一樣券膀。

注意:如果不是web或者maven的war工程,是不能使用的驯遇。

tomcat服務(wù)器,采用連接池就是dbcp連接池芹彬。

8.MyBatis事務(wù)

//生產(chǎn)SQLSession對象 session = factory.openSession(true);
它是通過sqlsession對象的commit方法和rollback方法實(shí)現(xiàn)事務(wù)的提交和回滾

session.commit();
session.close();

9.動態(tài)SQL

<where>

<if>

<foreach>

這是一個(gè)根據(jù)條件查詢的語句,但是條件有可能哦呦有可能沒有就要使用動態(tài)SQL標(biāo)簽了    [ids 是Vo類里的屬性名]
<include><sql id="defUser"> SELECT * FROM USER </sql>
        <select id="findUserIn" resultType="User" parameterType="QueryVo">
    <include refid="defUser"/>
    <where>
        <if test="#{ids!= null and ids.size > 0 }">
            id in
            <foreach collection="ids " open="(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
    </where>
</select>

10.MyBatis表與表之間的關(guān)系

10.1.多對一【包括一對一】(Account==>User)

10.1.1.實(shí)體類

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() 方法
}

10.1.2.映射文件

<?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">
    <!--配置一對多關(guān)系的resultMap-->
    <resultMap id="accountUserMap" type="account">
            <!--id是唯一標(biāo)識-->
            <!--type是對應(yīng)的實(shí)體類-->
        <id column="aid" property="id"/>
        <!--id是主鍵-->
        <!--result是普通列-->
            <!--column是數(shù)據(jù)庫列名-->
            <!--property是屬性名-->
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <!--association對應(yīng)主表關(guān)系-->
            <!--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>

    <!--查詢?nèi)緼ccount-->
    <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>

10.1.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 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");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)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());
        }
    }

}

10.2.一對多(User==>Account)

10.2.1.實(shí)體類

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() 方法
}

10.2.2.映射文件

<?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>


    <!--查詢?nèi)縐ser-->
    <select id="findAll" resultMap="userAccountMap">
        <include refid="defUser"/>
    </select>

    <!--根據(jù)ID查詢User-->
    <select id="findById" resultMap="userAccountMap" parameterType="int">
        <include refid="defUser"/>
        <where>
            ID = #{id}
        </where>
    </select>


</mapper>

10.2.3.測試

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");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)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);
                }
            }
        }

    }
}

10.3.多對多(User<===>Role)

10.3.1.實(shí)體類

package com.yuan.doman;

import java.util.List;

public class Role {
    private Integer id;
    private String role_name;
    private String role_desc;
    /**
     * 角色對應(yīng)的賬戶結(jié)合
     */
    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() 方法
}

10.3.2.映射文件

<?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>


    <!--查詢?nèi)縐ser-->
    <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>

    <!--根據(jù)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>


    <!--查詢?nèi)縐ser-->
    <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>

    <!--根據(jù)ID查詢User-->
    <select id="findById" resultMap="userRolestMap" parameterType="int">
    </select>


</mapper>

10.3.3.測試

package com.yuan.test;

import com.yuan.dao.RoleDao;
import com.yuan.doman.Role;
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 RoleDaoTest {
    InputStream is = null;
    SqlSessionFactory factory = null;
    SqlSession session = null;
    RoleDao roleDao = null;
    @Before
    public void init() throws IOException {
        //讀取配置文件
        is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)SQLSession對象
        session = factory.openSession();
        roleDao = session.getMapper(RoleDao.class);
    }
    @After
    public void close() throws IOException {
        session.commit();
        session.close();
        is.close();
    }
    @Test
    public void finAll() {

        List<Role> roles = roleDao.findAll();
        for (Role role : roles) {
        System.out.println("-----------------");
            System.out.println("role = " + role);
            if(!(role.getUsers().size()<=0)){
                for (User user : role.getUsers()) {
                    System.out.println("user = " + user);
                }
            }
        }
    }
}
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");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)SQLSession對象
        session = factory.openSession();
        userDao = session.getMapper(UserDao.class);
    }
    @After
    public void close() throws IOException {
        session.commit();
        session.close();
        is.close();
    }
    @Test
    public void finAllAccount() {

        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println("user = " + user);
        }
    }
}

11.MyBatis表與表之間的關(guān)系【注解實(shí)現(xiàn)】

11.1.pom.xml

參考3.1

11.2.編寫實(shí)體類

11.2.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 + '\'' +
                '}';
    }
}

11.2.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;
    /**
     * 所屬用戶【這個(gè)數(shù)據(jù)庫中表沒有】
     */
    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 +
                '}';
    }
}

11.2.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;
    /**
     * 角色權(quán)限
     */
    private String role_desc;
    /**
     * 角色對應(yīng)的賬戶結(jié)合
     */
    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 + '\'' +
                '}';
    }
}

11.3.編寫持久層接口

11.3.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();
    /**
     * 根據(jù) id 查詢一個(gè)用戶
     *
     * @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);

    /**
     * 查詢使用聚合函數(shù)
     *
     * @return
     */
    @Select("select count(*) from user ")
    int findTotal();

    /**
     * 模糊查詢
     *
     * @param name
     * @return
     */
    @Select("select * from user where username like #{username} ")
    List<User> findByName(String name);
}

11.3.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);
}

11.3.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);


}

11.4.編寫配置文件

<?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>
        <!-- 延遲加載的全局開關(guān) 默認(rèn)關(guān)閉 -->
        <setting name="lazyLoadingEnabled" value="true"/>

<!--        <setting name="aggressiveLazyLoading" value="true"/>-->
    </settings>
    <!--別名包-->
    <typeAliases>
        <package name="com.yuan.doman"/>
    </typeAliases>
    <!--配置環(huán)境-->
    <environments default="def">
        <!--配置默認(rèn)環(huán)境-->
        <environment id="def">
            <!--配置JDBC事務(wù)-->
            <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>

11.5.測試

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");
        //創(chuàng)建會話工廠
        factory = new SqlSessionFactoryBuilder().build(is);
        //生產(chǎn)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);
       }
   }
}

11.6多對一

這里只有接口文件有和測試文件變化

11.6.1.接口

UserDao.java

package com.yuan.dao;

import com.yuan.doman.User;
import org.apache.ibatis.annotations.*;

@CacheNamespace
public interface UserDao  {
    /**
     * 根據(jù)用戶Id返回該用戶
     * @param uid
     * @return
     */
    @Select("select * from user where id = #{id}")
    User findById(Integer uid);

}

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();

}

11.6.2.測試

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);
        //生產(chǎn)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);
        }
    }
}

11.7.多對一

11.7.1.接口

UserDao.java

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();

}

AccountDao.java

package com.yuan.dao;

import com.yuan.doman.Account;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface AccountDao {

    /**
     * 根據(jù)用戶Id查詢 賬戶信息
     * @param uid
     * @return
     */
    @Select("select * from account where uid = #{uid}")
    List<Account> findByUid(Integer uid);
}

11.7.2.測試

package com.yuan.test;

import com.yuan.dao.AccountDao;
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 UserTest {

    InputStream in;
    SqlSessionFactory factory;
    SqlSession session;
    UserDao userDao;


    @Before
    public void before() throws IOException {
        //讀取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //生成Session工廠
        factory = new SqlSessionFactoryBuilder().build(in);
        //生產(chǎn)Session對象
        session = factory.openSession();
        //獲取Dao對象
        userDao = session.getMapper(UserDao.class);

    }


    @After
    public void after() throws IOException {
        session.commit();
        session.close();
        in.close();
    }

    /**
     * 一對多查詢
     */
    @Test
    public void findUserAllTest() {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println("user = " + user);
            List<Account> accounts = user.getAccounts();
            System.out.println("accounts = " + accounts);
        }
    }

}

11.7常用注解

@Insert:實(shí)現(xiàn)新增 
@Update:實(shí)現(xiàn)更新 
@Delete:實(shí)現(xiàn)刪除 
@Select:實(shí)現(xiàn)查詢 
@Result:實(shí)現(xiàn)結(jié)果集封裝
@Results:可以與@Result 一起使用,封裝多個(gè)結(jié)果集 
@ResultMap:實(shí)現(xiàn)引用@Results 定義的封裝 
@One:實(shí)現(xiàn)一對一結(jié)果集封裝 
@Many:實(shí)現(xiàn)一對多結(jié)果集封裝 
@SelectProvider: 實(shí)現(xiàn)動態(tài) SQL 映射 
@CacheNamespace:實(shí)現(xiàn)注解二級緩存的使用

11.6復(fù)雜注解

@Results 注解 
代替的是標(biāo)簽<resultMap>  
該注解中可以使用單個(gè)@Result 注解陡叠,也可以使用@Result 集合 @Results({@Result()玩郊,@Result()})或@Results(@Result()) 

@Resutl 注解 
代替了 <id>標(biāo)簽和<result>標(biāo)簽  
@Result 中 屬性介紹:
    id 是否是主鍵字段  
    column 數(shù)據(jù)庫的列名  
    property 需要裝配的屬性名
    one  需要使用的@One 注解(@Result(one=@One)()))
    many  需要使用的@Many 注解(@Result(many=@many)())) 

@One 注解(一對一)
代替了<assocation>標(biāo)簽,是多表查詢的關(guān)鍵枉阵,在注解中用來指定子查詢返回單一對象译红。
@One 注解屬性介紹:
    select  指定用來多表查詢的
    sqlmapper  fetchType 會覆蓋全局的配置參數(shù) lazyLoadingEnabled。
使用格式:
    @Result(column=" ",property="",one=@One(select="")) 

@Many 注解(多對一)
    代替了<Collection>標(biāo)簽,是是多表查詢的關(guān)鍵兴溜,在注解中用來指定子查詢返回對象集合侦厚。
    注意:
        聚集元素用來處理“一對多”的關(guān)系耻陕。需要指定映射的 Java 實(shí)體類的屬性,屬性的 javaType (一般為 ArrayList)但是注解中可以不定義刨沦;
    使用格式:
        @Result(property="",column="",many=@Many(select=""))

12.MyBatis的延遲加載

1.一對一(多對一)延遲加載

<resultMap id="accountUserMap" type="account">
    <id property="id" column="id"/>
    <result property="uid" column="uid"/>
    <result property="money" column="money"/>
<!--
一(多)對一的關(guān)系映射:配置封裝user的內(nèi)容
select屬性指定的內(nèi)容:查詢用戶的唯一標(biāo)識:
column屬性指定的內(nèi)容:用戶根據(jù)id查詢時(shí)诗宣,所需要的參數(shù)的值
-->
<association
        property="users"
        column="uid"
        javaType="user"
        select="com.yuan.dao.UserDao.findById"
/>

</resultMap>

<!--查詢?nèi)緼ccount-->
<select id="findAll" resultMap="accountUserMap">
    SELECT * FROM ACCOUNT
</select>

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 用不到不寫 現(xiàn)在的作用是把用戶的ID作為參數(shù)傳到賬戶的查詢參數(shù)(一對多)-->
    <!--select 用的時(shí)候調(diào)用賬戶配置文件中的查詢方法-->
    <collection
            property="accounts"
            column = "id"
            select="com.yuan.dao.AccountDao.findByUid"
            ofType="account"/>
</resultMap>

<!--查詢?nèi)縐ser-->
<select id="findAll" resultMap="userAccountMap">
    SELECT * FROM USER
</select>

13.MyBatis的緩存

像大多數(shù)的持久化框架一樣,Mybatis 也提供了緩存策略想诅,通過緩存策略來減少數(shù)據(jù)庫的查詢次數(shù)召庞,從而提 高性能。 Mybatis 中緩存分為一級緩存来破,二級緩存裁眯。

MyBatis的緩存

13.1.一級緩存

它指的是Mybatis中SqlSession對象的緩存。

當(dāng)我們執(zhí)行查詢之后讳癌,查詢的結(jié)果會同時(shí)存入到SqlSession為我們提供一塊區(qū)域中。

該區(qū)域的結(jié)構(gòu)是一個(gè)Map存皂。當(dāng)我們再次查詢同樣的數(shù)據(jù)晌坤,mybatis會先去sqlsession中

查詢是否有,有的話直接拿出來用旦袋。

當(dāng)SqlSession對象消失時(shí)骤菠,mybatis的一級緩存也就消失了。

一級緩存是 SqlSession 級別的緩存疤孕,只要 SqlSession 沒有 flush 或 close商乎,它就存在。 默認(rèn)開啟噠祭阀!

當(dāng)調(diào)用 SqlSession 的修改鹉戚,添加,刪除专控,commit()抹凳,close()等方法時(shí),就會清空一級緩存伦腐。

13.2.二級緩存

它指的是Mybatis中SqlSessionFactory對象的緩存赢底。由同一個(gè)SqlSessionFactory對象創(chuàng)建的SqlSession共享其緩存。
二級緩存(默認(rèn)開啟)的使用步驟:
第一步:讓Mybatis框架支持二級緩存(在SqlMapConfig.xml中配置)

<!--開啟二級緩存-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

第二步:讓當(dāng)前的映射文件支持二級緩存(在IUserDao.xml中配置)
添加標(biāo)簽<cache/>【在映射文件中添加了這個(gè)標(biāo)簽就完事了】

第三步: 在select標(biāo)簽添加屬性useCache="true"

image.png

13.3.注意事項(xiàng)

當(dāng)我們在使用二級緩存時(shí)柏蘑,所緩存的類一定要實(shí)現(xiàn) java.io.Serializable 接口幸冻,這種就可以使用序列化 方式來保存對象。

小結(jié)3

什么是延遲加載

就是在需要用到數(shù)據(jù)時(shí)才進(jìn)行加載咳焚,不需要用到數(shù)據(jù)時(shí)就不加載數(shù)據(jù)洽损。延遲加載也稱懶加載. 好處:先從單表查詢,需要時(shí)再從關(guān)聯(lián)表去關(guān)聯(lián)查詢革半,大大提高數(shù)據(jù)庫性能趁啸,因?yàn)椴樵儐伪硪汝P(guān)聯(lián)查詢多張表速 度要快强缘。

延遲加載的壞處

因?yàn)橹挥挟?dāng)需要用到數(shù)據(jù)時(shí)不傅,才會進(jìn)行數(shù)據(jù)庫查詢旅掂,這樣在大批量數(shù)據(jù)查詢時(shí),因?yàn)椴樵児ぷ饕惨?時(shí)間访娶,所以可能造成用戶等待時(shí)間變長商虐,造成用戶體驗(yàn)下降。

注解方式如何開啟二級緩存

第一步:配置文件開啟二級緩存

第二步:在接口文件接口名上添加注解@CacheNamespace(blocking = true)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末崖疤,一起剝皮案震驚了整個(gè)濱河市秘车,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌劫哼,老刑警劉巖叮趴,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異权烧,居然都是意外死亡眯亦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門般码,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妻率,“玉大人,你說我怎么就攤上這事板祝」玻” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵券时,是天一觀的道長孤里。 經(jīng)常有香客問我,道長橘洞,這世上最難降的妖魔是什么扭粱? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮震檩,結(jié)果婚禮上琢蛤,老公的妹妹穿的比我還像新娘。我一直安慰自己抛虏,他們只是感情好博其,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迂猴,像睡著了一般慕淡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沸毁,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天峰髓,我揣著相機(jī)與錄音傻寂,去河邊找鬼。 笑死携兵,一個(gè)胖子當(dāng)著我的面吹牛疾掰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播徐紧,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼静檬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了并级?” 一聲冷哼從身側(cè)響起拂檩,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蠢棱,失蹤者是張志新(化名)和其女友劉穎槽奕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體覆致,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡愈涩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年望抽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钠署。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荒椭,靈堂內(nèi)的尸體忽然破棺而出谐鼎,到底是詐尸還是另有隱情,我是刑警寧澤趣惠,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布狸棍,位于F島的核電站,受9級特大地震影響味悄,放射性物質(zhì)發(fā)生泄漏草戈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一侍瑟、第九天 我趴在偏房一處隱蔽的房頂上張望唐片。 院中可真熱鬧,春花似錦涨颜、人聲如沸费韭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽星持。三九已至,卻和暖如春弹灭,著一層夾襖步出監(jiān)牢的瞬間督暂,已是汗流浹背揪垄。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逻翁,地道東北人饥努。 一個(gè)月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像卢未,于是被迫代替她去往敵國和親肪凛。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis 辽社? MyBatis 是支持定制化 SQL伟墙、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,532評論 0 4
  • Mybatis介紹 MyBatis 本是apache的一個(gè)開源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由apache...
    day_Sunny閱讀 2,670評論 0 6
  • Mybatis簡介 MyBatis 是一個(gè)可以自定義SQL、存儲過程和高級映射的持久層框架滴铅。MyBatis 摒除了...
    cuzz_閱讀 978評論 1 2
  • 什么是mybatis MyBatis 是支持定制化 SQL戳葵、存儲過程以及高級映射的優(yōu)秀的持久層框架。MyBatis...
    seadragonnj閱讀 2,334評論 0 7
  • MyBatis是一個(gè)可以自定義SQL汉匙、存儲過程和高級映射的持久層框架拱烁。MyBatis 摒除了大部分的JDBC代碼、...
    七寸知架構(gòu)閱讀 6,715評論 6 56