mybatis小例子2

奧楚蔑洛夫發表於2020-09-30

實現一對一,一對多查詢

三個重點:1.resultmap 2.動態Sql 3.關聯查詢

建立工程,配置環境

  • 使用的工具是idea和MySQL,還有資料庫的圖形介面工具sqlyog,maven環境已經搭好前提下
  1. idea建立工程 maven.xxx.quickstart,新增模組maven.xxx.webapp,在對應pom.xml檔案(小的)下<build></build> 標籤和內容可以刪除,因為maven已經自帶了編譯的功能不需要這個。
  2. 配置環境,在對應pom.xml的<dependencies></dependencies>標籤中新增依賴
<!-- MySql -->
   <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>5.1.32</version>
   </dependency>
   <!-- Mybatis -->
   <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.4.5</version>
   </dependency>
   <!--日誌包-->
   <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
     <version>1.7.25</version>
   </dependency>
   <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.17</version>
   </dependency>

訪問資料庫的四大資訊

在資原始檔夾下建一個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>
    <typeAliases>
        <package name="com.wzx.bean"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">

            <transactionManager type="JDBC"/>

            <dataSource type="POOLED">
                <!--    四大資訊 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/(這裡寫資料庫名)?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
<!--   一個mapper標籤可以指定一個對映檔案-->
    <mappers>

        <mapper resource="這裡寫要對映的子檔案類似com/yzf/dao/UserDao.xml""/>
    </mappers>
</configuration>

SqlSession

是mybatis的核心,獲取session物件對資料庫訪問,動態資原始檔下建立對應類,也是訪問資料庫要的準備

public class MySessionUtils {

        private static SqlSessionFactory sessionFactory;
        //static 靜態程式碼,在類載入的時候執行一次,且只執行一次
        static{
//  》1 建立SqlSessionFactoryBuilder物件
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 》2 建立SqlSessionFactory物件
            InputStream inputStream = MySessionUtils.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
            sessionFactory = sqlSessionFactoryBuilder.build(inputStream);//載入核心配置檔案 參1 輸入流
//        》3 載入SqlMapConfig.xml配置檔案
        }
        public static SqlSession getSession() {
//        》4 建立SqlSession物件
            SqlSession sqlSession = sessionFactory.openSession();
            return sqlSession;
        }
    }

資原始檔新增字尾.properties屬性檔案

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

重點1.resultMap

resultMap標籤對映關係和resultMap使用,在不改表不改類的情況下,欄位名不一樣的時候可以賦值。如果庫裡資料名和類名一樣就可以不寫<id colunmn="x" property="x"><result column="X" property="x"/>只要在type做好對映就好了。還有<association property="xx" javaType="xx"></association>標籤可以自定義型別(重點3有例子),表連線查詢能用到,property表示類名,javaType表示類的型別

<resultMap id="OrderMap" type="com.yzf.domain.Order">
        <!--        主鍵部份-->
        <id column="oid" property="oid"/>
        <!--        非主鍵部分-->
        <result column="(表名)" property="(類名)"/>
        <!--查詢欄位名與類的變數名一樣的可以不寫  -->
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
    </resultMap>
    <select id="findAll" resultMap="OrderMap">
        select * from tab_order
    </select>

測試使用。建立介面Dao類,測試裡用getSession獲取session,然後getMapper(xxx.class)(自動寫方法實現sql語句),然後新增對應的方法名,新增xml檔案,就是上面那部分程式碼修改一下。在最大的xml配置檔案新增小的就行了。

重點2.動態Sql

有if標籤,where和foreach等,最常用來高階搜尋
例如select * from xx where xx like “xx” and xx = “xx”
有兩個條件,如果想自由搜尋就適合用標籤

 <select id="findByUser" resultType="com.yzf.domain.User">
        <where>
                <if test="username != null and username != '' ">
                and username like #{username}
                </if>
                <if test="address != null and address != '' ">
                and address = #{address}
                </if>
        </where>
    </select>

foreach標籤,查詢多個值的時候使用

<select id="findId" parameterType="list" resultType="com.yzf.domain.User">
       select * from userlist
       <where>
           <foreach collection="list" item="id" open="uid in(" close=")" separator=",">
           #{id}
           </foreach>
       </where>
   </select>

collection裡的名字要對應介面的變數名,如果名字不一樣可以在介面裡新增@Param註解List<User> findId(@Param("ooo") List<Integer> list);item是遍歷列表,集合元素賦值給item和python的迴圈差不多#{id}裡面的id和item一樣代表取每一個的值。open表示開始 close表示結束,separator代表分隔符。

重點3.關聯查詢,一對一

關係假設的是訂單與使用者關係,一個訂單對應一個客戶。(內連線inner join 左外連線 left outer join 右外連線right outer join 子查詢select 巢狀 select)連線方便檢視

  • 使用resultType方法返回值時,測試類裡寫下面的,對應介面寫List<UserOrder> findAllUserOrder();
SqlSession session = MySessionUtils.getSession();
        OrderDao orderDao = session.getMapper(OrderDao.class);
        List<UserOrder> order = orderDao.findAllUserOrder();
        System.out.println(order);
        session.close();

對應的xml裡寫,要新建一個javaBean類儲存資料,因為兩個表連線了,資料數量對不上,用resultType必須有一個類對應全部的屬性。

<select id="findAllUserOrder" resultType="com.yzf.domain.UserOrder">
        select * from tab_order o left join userlist u on o.user_id = u.uid
    </select>
  • 使用resultMap時,結合上面,在order類上面新增成員變數user,private User user,測試裡寫
   SqlSession session = MySessionUtils.getSession();

        OrderDao orderDao = session.getMapper(OrderDao.class);

        List<Order> list = orderDao.findAllUserOrder2();

        System.out.println(list);
        session.close();

這裡寫在OrderDao.xml,記得新增autoMapping=true,resultMap標籤的type要設定好還有association中的property和javaType,查詢方法一般一個個寫不用*號,不寫星號類似(select u.username from userlist u left join tab_order on u.id = o.id)userlist和tab_order是表名

<resultMap id="UserOrderMap" type="com.yzf.domain.Order" autoMapping="true" >
        <id property="oid" column="oid"></id>
       <association autoMapping="true" property="user" javaType="com.yzf.domain.User">

       </association>
    </resultMap>
    <select id="findAllUserOrder2" resultMap="UserOrderMap">
        select * from tab_order o left join userlist u on o.user_id = u.uid
    </select>

一對多查詢

資料庫select * from userlist u left join tab_order o on u.uid=o.user_id。在bean類User中定義List後面要用collection對應它private List<Order> orders;這是集合型別

  <resultMap id="UsersMap" type="com.yzf.domain.User" autoMapping="true">
           <id property="uid" column="uid"></id>
          <collection  property="orders" ofType="com.yzf.domain.Order" autoMapping="true">

          </collection>
       </resultMap>
       <select id="findAllUsers" resultMap="UsersMap">
           select * from userlist u left join tab_order o on u.uid=o.user_id
       </select>
  • 其中 < collection property=“order” javaType=“com.yzf.domain.Order”>中collection表示集合,property指定變數是定義那個變數名,ofType指裡面的元素型別,記得是ofType

相關文章