MyBatis框架學習-2

MyBatis框架安排

2. 第二天:

1. MyBatis的增刪改查操作(操作配置文件SqlMapConfig.xml)

  1. 在SqlMapConfig.xml中向數據庫中增加條目

    <!-- 插入數據 -->
    <!-- parameterType="com.liuzeyu.domin.User"參數類型,通過反射爲#{username}...賦值-->
    <insert id="save" parameterType="com.liuzeyu.domin.User">
        <!-- 插入數後返回id,keyProperty="id"對應實體類屬性,keyColumn="id"對應數據庫列名,AFTER:操作最後執行-->
        <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="int">
        <!-- SELECT last_insert_id()  返回剛剛插入的數據id-- >
            SELECT last_insert_id() 
        </selectKey>
        insert into user (username,birthday,sex,address)VALUES (#{username},#{birthday},#{sex},#{address})
    </insert>
    
  2. 在SqlMapConfig.xml中向數據庫中刪除條目

    <!-- 根據id刪除-->
    <delete id="delete" parameterType="int">
        delete from user where id=#{uid}
    </delete>
    
  3. 在SqlMapConfig.xml向數據庫中修改條目

    <!-- 更新數據 -->
    <update id="update" parameterType="com.liuzeyu.domin.User">
        UPDATE user SET username=#{username},birthday=#{birthday},address=#{address},sex=#{sex} where id=#{id}
    </update>
    
  4. 在SqlMapConfig.xml向數據庫中查詢條目

        <!-- 根據id查找一個 -->
        <select id="findById" resultType="com.liuzeyu.domin.User" parameterType="int">
            select * from user where id=#{uid}
        </select>
        <!-- 根據name查找集合 -->
        <select id="findByName" resultType="com.liuzeyu.domin.User" parameterType="string">
              select * from user where username like #{string}
        <!-- select * from user where username like '%${value}%' -->
      </select>
      <!-- 查詢總記錄數-->
        <select id="findTotal" resultType="int">
            SELECT count(*) FROM USER
        </select>
    

測試類:

```
package com.liuzeyu.test;

import com.liuzeyu.dao.IUserDao;
import com.liuzeyu.domin.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 java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class Test {
    private InputStream is = null;
    private IUserDao userDao = null;
    private  SqlSession session = null;
    /**
     * 初始化
     * @throws IOException
     */
    @Before  //測試開始前執行
    public void init() throws IOException {
        //1.解析xml配置文件
        is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.構建工廠
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //3.工廠生產SqlSession對象
        session = factory.openSession();
        //4.創建代理Dao的對象
        userDao = session.getMapper(IUserDao.class);
    }
    @After //測試結束後執行
    public void destory(){
        session.commit();
        //7.釋放資源
        if( session != null){
            session.close();
        }
        if( is != null){
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @org.junit.Test
    public void testSelect() throws IOException {
        //5.使用代理對象執行方法
        List<User> users = userDao.findAll();
        //6.遍歷對象
        for (User user : users) {
            System.out.println(user);
        }
    }
    @org.junit.Test
    public void testSave() throws IOException {
        User user = new User();
        user.setUsername("liuzeyu");
        user.setBirthday(new Date());
        user.setAddress("莆田");
        user.setSex("男");
        System.out.println("保存前:"+user);
        userDao.save(user);
        System.out.println("保存後:"+user);
    }
    @org.junit.Test
    public void testUpdate() throws IOException {
        User user = new User();
        user.setId(48);
        user.setUsername("duyangting");
        user.setBirthday(new Date());
        user.setAddress("廈門");
        user.setSex("女");
        userDao.update(user);
    }
    @org.junit.Test
    public void testDelete() throws IOException {
        userDao.delete(46);
    }
    @org.junit.Test
    public void testFindOne() throws IOException {
        User user = userDao.findById(42);
        System.out.println(user);
    }

    @org.junit.Test
    public void testFindOneByName() throws IOException {
           List<User> users = userDao.findByName("%王%");//使用的是PreparedStatement的查詢方式,Preparing: select * from user where username like ?
//        List<User> users = userDao.findByName("王"); //使用的是拼接字符串的查詢方式,Preparing: select * from user where username like '%王%'
        for (User user : users) {
            System.out.println(user);
        }
    }
    @org.junit.Test
    public void testFindTotal() throws IOException {
        int total = userDao.findTotal();
        System.out.println(total);
    }
}
```

2. 多個對象組成一個查詢條件

  1. 將user 對象使用類QueryStringVo包裝
    /**
     * 將查詢條件封裝到一個類中
     */
    public class QueryStringVo {
        private User user;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }
    
  2. 在SqlMapConfig.xml向數據庫中查詢條件
    </select>
    <!-- 根據queryStringVo查詢-->
    <select id="findByVo" resultType="com.liuzeyu.domin.User" parameterType="com.liuzeyu.vo.QueryStringVo">
        select * from user where username like #{user.username}
        <!-- select * from user where username like '%${value}%' -->
    </select>
  1. 測試函數(結果與模糊查詢一致)

       @org.junit.Test
        public void testFindOneByVo() throws IOException {
            QueryStringVo vo = new QueryStringVo();
            User user = new User();
            user.setUsername("%王%");
            vo.setUser(user);
            List<User> users = userDao.findByVo(vo);//使用的是PreparedStatement的查詢方式,Preparing: select * from user where username like ?
    
            for (User u : users) {
                System.out.println(u);
            }
        }
    

3. OGNL表達式介紹

OGNL :Object Graphic Navigation Lanuage (對象圖導航語言)
它是通過對象取值方法來獲取數據的,在寫法上把類似JavaBean的get方法給刪掉了。

類中的寫法 user.getUsername
OGNL表達式:user.username

例如上面的

<insert id="save" parameterType="com.liuzeyu.domin.User">
    insert into user (username,birthday,sex,address)VALUES (#{username},#{birthday},#{sex},#{address})
</insert>

由於parameterType屬性已經提供了類的路徑,則要獲取values的username需要之需要寫User類的屬性即可#{username},否則需要寫user.username
類似於:

 <!-- 根據queryStringVo查詢-->
 <select id="findByVo" resultType="com.liuzeyu.domin.User" parameterType="com.liuzeyu.vo.QueryStringVo">
     select * from user where username like #{user.username}
     <!-- select * from user where username like '%${value}%' -->
 </select>

4. 數據庫表字段和實體類屬性不一致問題

解決方法有兩個:
方法一:通過對發送的sql語句字段名取別名來處理

 <!-- 打印user表數據 -->
 <select id="findAll" resultType="com.liuzeyu.domin.User">
     <!-- 取別名來和實體類產生關係 -->
     <!--SELECT id as userId,username as userName,address as userAddress,birthday as userBirthday ,sex as userSex from user -->
 </select>

其中userId,userName,userAddress,userBirthday ,userSex 是實體類的屬性。
對應的數據庫列名:id,username,address,birthday,sex
這樣查詢出來的結果的字段名就是userId,userName,userAddress,userBirthday ,userSex ,此時就與實體類一一對應了。

方法二:通過配置文件來實現:

 <!-- 配置查詢的列名和實體類直接的對應關係-->
 <resultMap id="userMap" type="com.liuzeyu.domin.User">
     <!-- 主鍵id對應,property="userId"實體類屬性, column="id"數據庫列字段名-->
     <id property="userId" column="id"/>
     <!-- 非主鍵字段的對應關係-->
     <result property="userName" column="username"/>
     <result property="userAddress" column="address"/>
     <result property="userBirthday" column="birthday"/>
     <result property="userSex" column="sex"/>
 </resultMap>

在操作數據庫的標籤內添加resultMap屬性引用即可,如:

    <!-- 打印user表數據 -->
    <select id="findAll" resultType="com.liuzeyu.domin.User" resultMap="userMap">
         SELECT * from USER
    </select>

方法一比方法二的執行效率更高,但是方法二比方法一開發效率更高,就是說當項目比較大時,使用方法二會提高開發效率。

5. 優化主配置文件

  1. 引用外部連接數據庫的連接信息
    在主配置文件下< configuration >標籤內部添加properties 的resource配置或url配置引用外部配置文件
    <!-- 配置標籤內部的屬性連接數據庫的信息,可以通過引用外部資源文件-->
    <!--1. resource的配置方式-->
	    <!--<properties resource="jdbcConfig.properties">-->
	    <!--</properties>-->
    <!--2. url的配置方式-->
        <!--
        url 與 uri的區別
        url:uniform resource locator 統一資源定位  唯一標識一個資源的位置
            寫法:
            協議://主機:端口/uri
            http://localhost:80/servlet/index
        uri:uniform resource  Identifier 統一資源標識  在應用中唯一定位一個資源
        -->
	    <properties url="file:\\\C:\Users\lzy\IdeaProjects\day02_mybatis_modify\src\main\resources\jdbcConfig.properties">
	
	    </properties>

在這裏插入圖片描述

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=809080

之後再JDBC的連接池裏面以$獲取實際配置文件中的值

<!-- JDBC連接池 -->
<dataSource type="POOLED">
    <property name="driver" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</dataSource>
  1. 爲標籤屬性取別名
    取完別名後,可以再映射配置文件中直接使用
    <!--自定義爲配置文件取別名-->
    <typeAliases>
        <!--<typeAlias type="com.liuzeyu.domin.User" alias="user"/>-->
        <package name="com.liuzeyu.domin"/>
    </typeAliases>

使用typeAlias 標籤去別名和package有一個區別?
typeAlias 指定type對象後,alias是別名,並且再映射配置文件中使用它可以不區分大小寫,如:
在這裏插入圖片描述
package標籤是指定取別名的包,當指定後,該包下所有的實體類都會被指定別名,並且類名就是別名,不再區分大小寫。

  1. 簡化主配置的映射接口配置

        <mappers>
            <!--<mapper resource="com/liuzeyu/dao/IUserDao.xml"></mapper>-->
            <package name="com.liuzeyu.dao"></package>
        </mappers>
    

    上面這種配置有一個好處是,再package標籤下指定dao接口所在的包,就可以不用再寫mapper以及class和resource屬性了,它可以直接找到映射配置文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章