MyBatis整理(idea版-xml配置方式)

MyBatis對比Hibernate

Hibernate:全自動映射,雖然方便,但是缺少靈活性,後期還要深入學hql,麻煩。
MyBatis:半自動映射,sql語句寫在配置文件中,由開發人員人員控制。

Mybatis也是輕量級框架
Mybatis實現sql語句定製化,其他流程還是自動化,是結餘Hibernate和JDBC之間的半自動框架。

mybatis的環境搭建

創建一個maven項目
pom文件的常用依賴

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.42</version>
    </dependency>

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
    </dependency>
</dependencies>

小注意:
選成自己下載的maven
在這裏插入圖片描述
要打勾的地方
在這裏插入圖片描述
數據庫
在這裏插入圖片描述
實體類(省略了get和set方法)

 private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

核心配置文件(必須要)

<?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">
<!-- mybatis的主配置文件 -->

```java
<configuration>
 <!-- 配置properties-->
    <properties resource="jdbcConfig.properties"></properties>
    
     <!--配置參數-->
    <settings>
        <!--開啓Mybatis支持延遲加載-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"></setting>
    </settings>
    
  <typeAliases>
    <!--typeAlias用於配置別名。type屬性指定的是實體類全限定類名。alias屬性指定別名,當指定了別名就再區分大小寫 
    <typeAlias type="home.sise.cn.domain.User" alias="user"></typeAlias>-->
 <!-- 用於指定要配置別名的包,當指定之後,該包下的實體類都會註冊別名,並且類名就是別名,不再區分大小寫-->
    <package name="home.sise.cn.domain"></package>
</typeAliases>

    <!-- 配置環境 -->
    <environments default="mysql">
        <!-- 配置mysql的環境-->
        <environment id="mysql">
            <!-- 配置事務的類型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置數據源(連接池) -->
            <dataSource type="POOLED">
                <!-- 配置連接數據庫的4個基本信息 -->
              <!--   <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_day01"/>
                <property name="username" value="root"/>
                <property name="password" value="3997"/>-->

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

    <!-- 指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件 -->
   <!--<mapper resource="home/sise/cn/dao/IUserDao.xml"></mapper>-->
        <!-- package標籤是用於指定dao接口所在的包,當指定了之後就不需要在寫mapper以及resource或者class-->
        <package name="home.sise.cn.dao"></package>
</configuration>

連接池的屬性有三個

POOLED 使用了連接池(常用)
UNPOOLED 沒有使用連接池,每次請求都會創建一個鏈接
JNDI 需要通過服務器加載,必須是web工程或maven的war工程才能使用

mapper標籤的屬性
resource 用於配置xml方式
class 用於註解方式
package 直接指定dao接口包

typeAlias標籤表示起別名

URI:Uniform Resource Identifier 統一資源標識符。它是在應用中可以唯一定位一個資源的。
URL:Uniform Resource Locator 統一資源定位符。它是可以唯一標識一個資源的位置。
URL用法:
http://localhost:8080/mybatis/ServletTest
協議 主機 端口 URI

在用戶和賬戶的關聯關係中,查詢用戶時,該用戶的賬戶信息應該用的時候再查詢。而查詢賬戶時,該賬戶所屬的用戶信息應該一起查詢出來。

延遲加載:不用的時候不查詢。按需加載
立即加載:只要一調用方法,馬上發起查詢。

一對多,多對多:通常情況下我們都是採用延遲加載。
多對一,一對一:通常情況下我們都是採用立即加載。

配置properties
可以在標籤內部配置連接數據庫的信息。也可以通過屬性引用外部配置文件信息
resource屬性: 常用的

jdbcConfig.properties配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_day01
jdbc.username=root
jdbc.password=3997

mybatis的代理方式(常用)

映射配置文件(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="home.sise.cn.dao.IUserDao">
    <select id="findAll" resultType="home.sise.cn.domain.User">
     select * from user
    </select>
</mapper>

使用代理方式小注意:
1.mybatis的映射配置文件位置必須和dao接口的包結構相同
2.映射配置文件的mapper標籤的namespace屬性的取值要和dao接口的全限定類名相同
3.映射配置文件的select標籤的id屬性要和dao接口的方法名相同
原因
mybatis在創建工廠加載解析xml配置文件時,是通過把映射配置文件中的namespace+id作爲key,把sq語句和返回類型作爲value放入了map集合中。在我們使用時,通過傳入的接口的全限定名+方法名從放入的map集合中找到對應的信息,然後執行相應的操作。

客戶代碼
public class Mybatis_test {

public static void main(String[] args)throws Exception {
     //1.讀取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.創建SqlSessionFactory工廠
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工廠生產SqlSession對象
       // SqlSession session = factory.openSession();
        SqlSession session = factory.openSession(true);
        //4.使用SqlSession創建Dao接口的代理對象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //5.使用代理對象執行方法
        List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        } 
         //提交事務
       // session.commit();
        //6.釋放資源
        session.close();
        in.close();
}}

使用了建造者模式,工廠方法模式,代理模式

SqlSession session = factory.openSession(true);
表示開啓了自動提交事務

mybatis的接口實現方式

接口實現類

public class UserDaoImpl implements IUserDao {

    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory  factory){
        this.factory = factory;
    }


    public List<User> findAll(){
        //1.使用工廠創建SqlSession對象
        SqlSession session = factory.openSession();
        //2.使用session執行查詢所有方法
        List<User> users = session.selectList("home.sise.cn.dao.IUserDao.findAll");
        session.close();
        //3.返回查詢結果
        return users;
    }
}

客戶代碼

public class MybatisTest {

    public static void main(String[] args)throws Exception {
        //1.讀取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.創建SqlSessionFactory工廠
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工廠創建dao對象
        IUserDao userDao = new UserDaoImpl(factory);
        //4.使用代理對象執行方法
        List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        }
        //5.釋放資源
        in.close();
    }
}

mybatis的基本使用

常用增刪改查

映射配置

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

    <!-- 配置 查詢結果的列名和實體類的屬性名的對應關係 -->
    <resultMap id="userMap" type="User">
        <!-- 主鍵字段的對應 -->
        <id property="userId" column="id"></id>
        <!--非主鍵字段的對應-->
        <result property="userName" column="username"></result>
        <result property="userAddress" column="address"></result>
        <result property="userSex" column="sex"></result>
        <result property="userBirthday" column="birthday"></result>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userMap">
        select * from user;
    </select>
    
    <!-- 保存用戶 -->
    <insert id="saveUser" parameterType="user">
        <!-- 配置插入操作後,獲取插入數據的id -->
        <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
    </insert>

    <!-- 更新用戶 -->
    <update id="updateUser" parameterType="USER">
        update user set username=#{userName},address=#{userAddress},sex=#{userAex},birthday=#{userBirthday} where id=#{userId}
    </update>

    <!-- 刪除用戶-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id = #{uid}
    </delete>
    
    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultMap="userMap">
        select * from user where id = #{uid}
    </select>

    <!-- 根據名稱模糊查詢 -->
    <select id="findByName" parameterType="string" resultMap="userMap">
          select * from user where username like #{name}
        <!-- select * from user where username like '%${value}%'-->
   </select>

    <!-- 獲取用戶的總記錄條數 -->
    <select id="findTotal" resultType="int">
        select count(id) from user;
    </select>

    <!-- 根據queryVo的條件查詢用戶 -->
    <select id="findUserByVo" parameterType="home.sise.cn.domain.QueryVo" resultMap="userMap">
        select * from user where username like #{user.username}
    </select>
</mapper>

實體類

public class QueryVo {
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

小注意:
1.parameterType爲參數類型,resultType爲返回值類型
2.因爲在主配置文件中使用了別名,所以type中可以直接使用user,而且不區分大小寫。
3.parameterType如果爲8中基本類型,那麼佔位符#{}中的值可以任意,如果是其他值,則必須對應着實體類來寫
4.當實體類和數據庫的表沒有一一對應時,可以使用在映射文件中給字段起別名或者resultMap
5.resultMap中,column是數據庫字段,property是實體類屬性,type是返回值類型,id是唯一標識。

mybatis映射文件標籤

if,where標籤

 <select id="findUserByCondition" resultMap="userMap" parameterType="user">
        select * from user
        <where>
            <if test="userName != null">
                and username = #{userName}
            </if>
            <if test="userSex != null">
                and sex = #{userSex}
            </if>
            <if test="userAddress !=null">
                and address = #{userAddress}
            </if>
        </where>
    </select>

sql,foreach標籤
foreach屬性:
collection:代表要遍歷的集合元素,類似jstl中的items
open:代表語句的開始部分
close:代表結束部分
item:代表遍歷集合的每個元素,類似jstl中的var
sperator:代表分隔符
相當於sql: select * from user where ids != null and ids.size()>0 and id in (?)

<!-- 瞭解的內容:抽取重複的sql語句-->
    <sql id="defaultUser">
        select * from user
    </sql>

<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
        <include refid="defaultUser"></include>
        <where>
            <if test="ids != null and ids.size()>0">
                <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                    #{uid}
                </foreach>
            </if>
        </where>
    </select>

小注意
如果引用其它 mapper.xml 的 sql 片段,則在引用時需要加上 namespace,如下:
<include refid="namespace.sql 片段”/>

mybatis表之間關聯關係

每個賬戶所屬一個用戶 : 一對一

方式一
<!-- 定義封裝account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一對一的關係映射:配置封裝user的內容
        select屬性指定的內容:查詢用戶的唯一標識:
        column屬性指定的內容:用戶根據id查詢時,所需要的參數的值
        -->
        <association property="user" column="uid" javaType="user" select="home.sise.cn.dao.IUserDao.findById"></association>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select * from account
    </select>
    
     <!-- 根據用戶id查詢賬戶列表 -->
    <select id="findAccountByUid" resultType="account">
        select * from account where uid = #{uid}
    </select>
    
方式二
<!-- 定義封裝account和user的resultMap,其中account用到了別名 -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一對一的關係映射:配置封裝user的內容-->
        <association property="user" column="uid" javaType="user">
            <id property="id" column="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="birthday"></result>
        </association>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select u.*,a.id as aid,a.uid,a.money from account a , user u where u.id = a.uid;
    </select>

resultMap中id標籤是對應表中的主鍵

一個用戶有多個賬戶 :一對多

 <!-- 定義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>
        <!-- 配置user對象中accounts集合的映射 -->
        <collection property="accounts" ofType="account" select="home.sise.cn.dao.IAccountDao.findAccountByUid" column="id"></collection>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user
    </select>

    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultType="user">
        select * from user where id = #{id}
    </select>
    
方式二:
<!-- 定義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>
        <!-- 配置user對象中accounts集合的映射 -->
        <collection property="accounts" ofType="account">
            <id column="id" property="id"></id>
            <result column="uid" property="uid"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user u left outer join account a on u.id = a.uid
    </select>

mybatis的緩存

緩存是什麼?
存在內存中的臨時數據。

爲什麼使用緩存?
減少和數據庫的交互次數,提高了執行效率。

適合用緩存的情況
1.需要經常進行查詢,而且不會經常變動的。
2.數據的正確與否對最終的結果影響不大。

不適合用緩存的情況
1.經常改變的數據
2.數據的正確與否對最終的影響很大。
例如:商品的庫存,銀行的匯率.

默認一級緩存,範圍是在一個session中
當我們執行查詢之後,查詢的結果會同時存入到session爲我們提供一塊區域中。該區域的結構是一個Map。當我們再次查詢同樣的數據,mybatis會先去session中查詢是否有,有的話直接拿出來用。當session對象消失時,mybatis的一級緩存也就消失了。
當調用 session 的修改,添加,刪除,commit(),close()等方法時,就會清空一級緩存。

二級緩存,範圍是在一個sessionFactory中
二級緩存存放的是數據
使用步驟:
第一步:讓Mybatis框架支持二級緩存(在SqlMapConfig.xml中配置)

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

第二步:讓當前的映射文件支持二級緩存(在IUserDao.xml中配置)
第三步:讓當前的操作支持二級緩存(在select標籤中配置)

<mapper namespace="home.sise.cn.dao.IUserDao">
    <!--開啓user支持二級緩存-->
    <cache/>
    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultType="user" useCache="true">
        select * from user where id = #{uid}
    </select>
</mapper>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章