50、Mybatis框架

框架:軟件開發中的一套解決方案,不一樣的框架解決不一樣的問題。java

框架的好處:框架封裝了不少的細節,使開發者可使用極簡的方式實現功能,提升開發的效率mysql

 

三層架構:程序員

一、表現層:用於展現數據sql

二、業務層:用於處理業務需求數據庫

三、持久層:用於和數據庫交互緩存

 

持久層技術解決方案:tomcat

一、JDBC技術:Connection;PreparedStatement;ResultSet,三個對象服務器

二、Spring的JdbcTemplate:對jdbc的簡單封裝session

三、Apache的DBUtils:對jdbc的簡單封裝mybatis

缺點:操做繁瑣

 

Mybatis概述:Mybatis是一個優秀的基於java的持久層框架,它內部封裝了jdbc,使開發者只須要關注sql語句自己,而不須要花費精力去處理加載驅動,建立鏈接,建立statement等繁雜的過程。

 

Mybatis的入門:

一、mybatis的環境搭建:

            一、建立maven工程並導入jar包

若是使用maven建立工程,能夠導入下面座標:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>x.x.x</version>
</dependency>

            二、建立實體類和dao接口

            三、建立Mybatis的主配置文件

<?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的主配置文件-->
<configuration>
    <!-- 配置環境-->
    <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/eesy"/>
                <property name="username" value="root"/>
                <property name="password" value="111111"/>

            </dataSource>

        </environment>
    </environments>

    <!--指定映射配置文件的位置,映射配置文件指的是每一個dao獨立的配置文件-->
    <mappers>
        <mapper resource="lianbang/wu/IUserDao.xml"/>
    </mappers>
</configuration>

            四、建立映射配置文件

<?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 ="lianbang.wu.dao.IUserDao">
    <!--配置查詢全部-->
    <select id="findAll">
        select * from user;
    </select>
</mapper>

注意:映射配置文件和對應的接口包結構要相同;

使用步驟:

public class MybatisTest {
    public static void main(String[] args) throws IOException {
        //一、讀取配置文件
        InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
        //二、建立sqlSessionFactory工廠
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //三、使用工廠生產sqlSession對象
        SqlSession session = factory.openSession();
        //四、使用sqlSession建立dao接口的代理對象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //五、使用代理對象執行方法
        List<User> users = userDao.findAll();
        for (User user : users){
            System.out.println(user);
        }
        //六、釋放資源
        session.close();
        in.close();

    }
}

 

Mybatis基於註解的使用:

刪除映射xml文件,直接在dao接口的方法上使用@Select註解,而且指定SQL語句,同時須要在主配置文件中的mapper配置時,使用class屬性指定dao接口的全限定類名。

<mappers>
    <mapper class="lianbang.wu.dao.IUserDao"/>
</mappers>

注意:當實體類和數據庫列名不一致時,須要在映射文件中進行對象映射

<resultMap id="userResultMap" type="User">
      <id property="id" column="user_id" />
      <result property="username" column="username"/>
      <result property="password" column="password"/>
</resultMap>

 

Mybatis的CURD:

一、保存數據

映射文件:

<!--保存用戶-->
<insert id="saveUser" parameterType="lianbang.wu.domain.User">
    insert  into user (username,address,sex,birthday) value (#{username},#{address},#{sex},#{birthday})
</insert>

測試代碼:

public void testSave() throws IOException {
    User user = new User();
    user.setUsername("mybatis");
    user.setAddress("杭州西湖");
    user.setSex("男");
    user.setBirthday(new Date());

    //一、讀取配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    //二、建立sqlSessionFactory工廠
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    //三、使用工廠生產sqlSession對象
    SqlSession session = factory.openSession();
    //四、使用sqlSession建立dao接口的代理對象
    IUserDao userDao = session.getMapper(IUserDao.class);
    //五、使用代理對象執行方法
    userDao.saveUser(user);
    session.commit();
    //六、釋放資源
    session.close();
    in.close();
}

二、修改數據

映射文件:

<!--更新用戶-->
<update id="updateUser" parameterType="lianbang.wu.domain.User">
    update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id};
</update>

測試代碼:

public void testUpdate() throws IOException {
    User user = new User();
    user.setId(51);
    user.setUsername("mybatis_update");
    user.setAddress("杭州西湖");
    user.setSex("男");
    user.setBirthday(new Date());

    //一、讀取配置文件
    InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
    //二、建立sqlSessionFactory工廠
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    //三、使用工廠生產sqlSession對象
    SqlSession session = factory.openSession();
    //四、使用sqlSession建立dao接口的代理對象
    IUserDao userDao = session.getMapper(IUserDao.class);
    //五、使用代理對象執行方法
    userDao.updateUser(user);
    session.commit();
    //六、釋放資源
    session.close();
    in.close();
}

三、刪除數據

映射文件:

<!--刪除用戶-->
<delete id="deleteUser" parameterType="Integer">
    delete from user where id=#{userid};
</delete>

測試代碼:

public void testDelete() throws IOException {
        Integer uid = 51;
        //一、讀取配置文件
        InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
        //二、建立sqlSessionFactory工廠
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //三、使用工廠生產sqlSession對象
        SqlSession session = factory.openSession();
        //四、使用sqlSession建立dao接口的代理對象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //五、使用代理對象執行方法
        userDao.deleteUser(uid);
        session.commit();
        //六、釋放資源
        session.close();
        in.close();
    }

 

Mybatis中的鏈接池:

Mybatis鏈接池提供了3種方式的配置:

主配置文件SqlMapConfig.xml中的dataSource標籤,type屬性就是表示採用何種鏈接池方式

type屬性的取值:POOLED,採用傳統的javax.sql.DataSource規範中的鏈接池,Mybatis中有針對規範的實現

                        UNPOOLED,採用傳統的獲取鏈接的方式,雖然也實現了實現了javax.sql.DataSource接口,可是並無使用池的思想

                        JNDI,採用服務器提供的JNDI技術實現,來獲取DataSource對象,不一樣的服務器所能拿到的DataSource是不同的

                                  若是不是Web或者Maven的war工程,是不能使用的

                                  使用tomcat服務器,採用的鏈接池就是dbcp鏈接池。

 

mybaits中的事務:

sqlsession的commit和rollback;

session.commit();
session.rollback();

mybaits中的動態sql語句:

if標籤:

<select id="findByCondition" resultType="lianbang.wu.domain.User" parameterType="lianbang.wu.domain.User">
    select * from user  where  1=1
    <if test="userName != null">
         and username = #{userName}
    </if>
</select>

where標籤:

<select id="findByCondition" resultType="lianbang.wu.domain.User" parameterType="lianbang.wu.domain.User">
    select * from user
    <where>
        <if test="userName != null">
            and username = #{userName}
        </if>
    </where>

</select>

foreach標籤:

<select id="findByRange" parameterType="queryvo" resultType="lianbang.wu.domain.User">
    select * from user
    <where>
        <if test="id!=null and ids.size()>0">
            <foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
    </where>
</select>

sql標籤:

<sql id="defauleUser">
    select * from user
</sql>

<select id="findAll" resultType="lianbang.wu.domain.User">
    <include refid="defaule">
        
    </include>i
</select>

trim標籤

set標籤

chose標籤

Mybatis的多表查詢

一對一的查詢:

方法一:新建一個包含兩個對象全部成員變量的實現類,將查詢結果封裝到裏面

方法二:在其中一個對象中,添加另外一個對象到成員變量中。在映射文件中,對變量進行以下映射

<resultMap id="accountUserMap" type="lianbang.wu.domain.Account">
    <id property="id" column="aid"></id>
    <result property="uid" column="uid"></result>
    <result property="money" column="money"></result>

    <association property="user" column="uid" javaType="lianbang.wu.domain.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>
    </association>
</resultMap>

再將查詢結果封裝到對應的對象中。

 

一對多的查詢:

<resultMap id="accountUserMap" type="lianbang.wu.domain.Account">
    <id property="id" column="aid"></id>
    <result property="uid" column="uid"></result>
    <result property="money" column="money"></result>

  

    <collection property="emplist" ofType="lianbang.wu.domain.emp">
        <id column="eid" property="id"></id>
        <result column="ename" property="name"></result>
    </collection>


</resultMap>

多對多查詢:

等同一對多

延遲加載:

概念:在真正使用數據的時才發起查詢,不用的時候不查詢,按需加載(懶加載),一般在一對多查詢或多對多查詢使用

當即加載:

概念:無論用不用,只要一調用方法,立刻發起查詢,一般在一對對或多對多查詢使用

實現步驟:

一、開啓延遲加載:主配置文件中設置

<settings>
    <setting name="lazyLoadingEnable" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

二、設置延遲加載的ResultMap

<resultMap id="accountUserMaplazyLoad" type="lianbang.wu.domain.Account">
    <id property="id" column="aid"></id>
    <result property="uid" column="uid"></result>
    <result property="money" column="money"></result>

  

    <collection property="emplist" ofType="lianbang.wu.domain.emp">
        <id column="eid" property="id"></id>
        <result column="ename" property="name"></result>
    </collection>


</resultMap>

三、延遲加載的mapper文件:

<select id="accountUserMapLazy" resultMap="accountUserMapLazyLoad">
select * from account
</select>

<select id ="findUser" parameterType="id" resultType="User">
select * from user where id = #{value}
</select>

緩存:

概念:存在於內存中的臨時數據

做用:減小和數據庫的交互次數,提升執行效率

適用於:常常查詢而且不常常改變的,數據的正確與否對最終結果影響不大的

不適用於:常常改變的數據,數據的正確與否對最終的結果影響很大的,例如:商品的庫存,銀行的匯率,股市的牌價

mybatis中的一級緩存:它指的是Mybatis中sqlSession對象的緩存,當咱們執行查詢以後,查詢的結果會同時存入到sqlSession爲咱們提供的一塊區域中,該區域的結構是一個Map,當咱們再次查詢一樣的數據,mybatis會先去sqlSession中查詢是否有,有的話直接拿出來用,當sqlSession對象消失,mybatis的一級緩存也就消失了。

注意:當sqlSession執行修改,添加,刪除,commit,close等方法時,就會清空一級緩存。

mybatis中的二級緩存:它指的是mybatis中的sqlSessionFactory對象的緩存。由同一個SqlSessionFactory對象建立的sqlSession共享其緩存。

二級緩存的使用步驟:

第一步:讓mybatis框架支持二級緩存,在主配置文件中配置

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

第二步:讓當前的映射文件支持二級緩存

<cache></cache>

第三步:讓當前的操做支持二級緩存

建立多個session對象。注意被實體類要實現序列化接口。

 

註解開發:

在mybatis中,針對CRUD一共有四種註解:@Select@Insert@Update@Delete

@Select("select * from user")
@Results({
@Result(id = true,column ="id",property = "id"),
@Result(column = "name", property = "name")})
List<User> findAll();

多表查詢

一對一

@Select("select * from user")
@Results({
@Result(id = true,column ="id",property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "deptid",property = "dept",one=@One(select = "lianbang.wu.dao.IDeptDao.selectdetpBydi"))
})
List<User> findAll();

 

一對多:

@Select("select * from user")
@Results({
@Result(id = true,column ="id",property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "deptid",property = "dept",many=@Many(select = "lianbang.wu.dao.IDeptDao.selectdetpBydi"))
})
List<User> findAll();

二級緩存

@CacheNamespace(blocking = true)

 

補充:

#{}:表示一個佔位符,向佔位符輸入參數,mybatis自動進行Java類型和jdbc類型轉換。程序員不須要考慮參數的類型,好比:傳入字符串,mybatis最終拼接好的sql就是參數兩邊加單引號,接受pojo數據,可使用OGNL解析出pojo的屬性中

${}:表示sql拼接,將參數的內容不加任何修飾拼接到sql中,也能夠接收pojo數據,使用OGNL解析出pojo的屬性值,缺點不能防止sql注入

相關文章
相關標籤/搜索