亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MyBatis完成CRUD?詳細細節(jié)內(nèi)容剖析

 更新時間:2024年05月31日 10:11:47   作者:Rainbow-Sea  
這篇文章主要介紹了MyBatis完成CRUD?詳細細節(jié)內(nèi)容剖析,本文通過圖文示例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧

1. MyBatis完成CRUD 詳細細節(jié)內(nèi)容

2. MyBatis工具類SqlSessionUtil的封裝

我們可以先將 SqlSession 對象的獲取,封裝成一個工具類來使用,方便一些。關(guān)于 SqlSession 對象的獲取的詳細內(nèi)容,大家可以移步至:?????? 初始MyBatis ,詳細步驟運行第一個MyBatis程序,同時對應(yīng)步驟MyBatis底層剖析

一般我們的工具類,的構(gòu)造方法都是私有化的,防止 new 對象。

工具類中所以的方法都是靜態(tài)的,直接用 類名.方法名 的方式直接調(diào)用

獲取到SqlSessionFactory 對象

SQlsessionFactory對象,一個SqlSessionFactory對應(yīng)一個 environment, 一個environment通常是一個數(shù)據(jù)庫。所以,我們定義一個靜態(tài)代碼塊,執(zhí)行加載一次即可。

package com.rainbowsea.mybatis.utils;
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 java.io.IOException;
public class SqlSessionUtil {
    // 工具類的構(gòu)造方法一般都是私有話化的
    // 工具類中所有的方法都是靜態(tài)的,直接類名即可調(diào)用,不需要 new 對象
    // 為了防止new對象,構(gòu)造方法私有化。
    private SqlSessionUtil() {
    }
    private static SqlSessionFactory sessionFactory = null;
    // 靜態(tài)代碼塊,類加載時執(zhí)行
    // SqlSessionUtil 工具類在進行第一次加載的時候,解析mybatis-config.xml 文件,創(chuàng)建SqlSessionFactory對象。
    static {
        // 獲取到  SqlSessionFactoryBuilder 對象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 獲取到SqlSessionFactory 對象
        // SQlsessionFactory對象,一個SqlSessionFactory對應(yīng)一個 environment, 一個environment通常是一個數(shù)據(jù)庫
        try {
            sessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 獲取會話對象
     * @return SqlSession
     */
    public static SqlSession openSession() {
        // 獲取到 SqlSession 對象
        SqlSession sqlSession = sessionFactory.openSession();
        return sqlSession;
    }
}

3. 準備工作

首先我們準備操作,實驗的數(shù)據(jù)庫,數(shù)據(jù)表。數(shù)據(jù)內(nèi)容

在項目/模塊當中導(dǎo)入相關(guān)的 jar 依賴,在pom.xml 配置相關(guān) jar依賴的。

我們需要的依賴有:

  • mybatis依賴
  • mysql驅(qū)動依賴
  • junit依賴
  • logback依賴

<?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.rainbowsea</groupId>
    <artifactId>mybatis-002-crud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
    <dependencies>
<!--              mybatis依賴 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>
<!--    mysql驅(qū)動器-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
<!--        引入 junit4 依賴-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!--        引入 logback的依賴,這個日志框架實現(xiàn)了slf4j 規(guī)范-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.11</version>
        </dependency>
    </dependencies>
</project>

其次就是:

  • mybatis-config.xml放在類的根路徑下
  • CarMapper.xml放在類的根路徑下
  • logback.xml放在類的根路徑下
  • 提供com.powernode.mybatis.utils.SqlSessionUtil工具類
  • 創(chuàng)建測試用例:com.powernode.mybatis.CarMapperTest

上述內(nèi)容,為什么放在類的根路徑下(resources) 就是為了提高項目的可移植性。詳細內(nèi)容,大家可以移步至:?????? 初始MyBatis ,詳細步驟運行第一個MyBatis程序,同時對應(yīng)步驟MyBatis底層剖析

mybatis-config.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>
    <!--    開啟mybatis 對標準日志的實現(xiàn)-->
    <!--    如果導(dǎo)入的第三方框架的日志,沒有下面這個 settings 也是可以的-->
    <!--    <settings>-->
    <!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
    <!--    </settings>-->
    <environments default="development">
        <environment id="development">
            <!--            MANAGED 沒有用第三框架管理的話,都是會被提交的,沒有事務(wù)上的管理了。-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="MySQL123"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--sql映射文件創(chuàng)建好之后,需要將該文件路徑配置到這里-->
        <!--        執(zhí)行XxxMapper.xml 文件的路徑-->
        <!--        resource 屬性自動會從類的根路徑下開始查找資源-->
        <!--        <mapper resource="CarMapper.xml"/>-->
        <!--        <mapper resource="com/CarMapper2.xml"/>-->
        <!--        url屬性: 從絕對路徑當中加載資源。-->
        <!--        語法格式:file:///絕對路徑-->
        <!--        <mapper url="file:///e:/CarMapper.xml"></mapper>-->
        <mapper resource="CarMapper.xml"></mapper>
    </mappers>
</configuration>

同時需要配置 MyBatis 的核心配置文件,告訴 MyBatis 要使用哪個 XxxMapper .xml SQL 語句的映射文件。

CarMapper.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">
<!--namespace先隨意寫一個-->
<mapper namespace="rainbowsea">
</mapper>

logback.xml放在類的根路徑下

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!-- 控制臺輸出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日志消息,%n是換行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    <!--mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    <!-- 日志輸出級別,logback日志級別包括五個:TRACE < DEBUG < INFO < WARN < ERROR -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

分析以下SQL映射文件中SQL語句存在的問題

<?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">
<!--namespace先隨便寫-->
<mapper namespace="car">
    <insert id="insertCar">
        insert into t_car(car_num,brand,guide_price,produce_time,car_type) values('103', '奔馳E300L', 50.3, '2022-01-01', '燃油車')
    </insert>
</mapper>

這樣寫的問題是:

值,顯然是寫死到配置文件當中了

這個實際開發(fā)中是不存在的
一定是前端 form 表單提交過來數(shù)據(jù),然后將值傳給 sql 語句

SQL語句中的值不應(yīng)該寫死,值應(yīng)該是用戶提供的。之前的JDBC代碼是這樣寫的:

// JDBC中使用 ? 作為占位符。那么MyBatis中會使用什么作為占位符呢?
String sql = "insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(?,?,?,?,?)";
// ......
// 給 ? 傳值。那么MyBatis中應(yīng)該怎么傳值呢?
ps.setString(1,"103");
ps.setString(2,"奔馳E300L");
ps.setDouble(3,50.3);
ps.setString(4,"2022-01-01");
ps.setString(5,"燃油車");

在JDBC當中占位符采用的是?,在mybatis當中是什么呢?

和?等效的寫法是: #{}

在mybatis當中不能使用 ? 占位符,必須使用 #{ } 來代替JDBC當中的 ?

#{ } 和JDBC當中的 ? 是等效的。

在MyBatis 中,的Java程序中,將數(shù)據(jù)放到Map集合中

在sql語句中使用 #{map集合的key} 來完成傳值,#{} 等同于JDBC中的 ? ,#{}就是占位符

我們在 XxxMapper.xml SQL 映射文件當中,使用上 #{ } 重新編寫 對于的 insert SQL 語句

這里的 id 是作為主鍵的,自增的,可以省略不寫。

<?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">
<!--namespace先隨意寫一個-->
<mapper namespace="rainbowsea">
<!--	insert語句,id是這個條SQL語句的唯一標識,這個id就代表了這條SQL語句 -->
	<insert id="insertCar">
		insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
		values (null,#{k1},#{k2},#{k3},#{k4},#{k5})
<!--  map.get("fdsd") 找,結(jié)果找不到 = null-->
	</insert>
</mapper>

在MyBatis 中的Java程序中使用 map 可以給SQL語句的占位符傳值。

Map<String,Object> map = new HashMap<>();

map.put("k1","111");
map.put("k2","比亞迪漢");
map.put("k3",10.0);
map.put("k4","2020-11-11");
map.put("k5","電車");

添加/插入,執(zhí)行 sqlSession.insert("Id", car); 方法

這里執(zhí)行 **insert( ) ** 插入操作,則是用:sqlSession.insert(String var1, Object var2); 兩個參數(shù)的方法,執(zhí)行 insert() 插入操作,返回影響的記錄條數(shù)。

// 執(zhí)行sql語句
// insert方法的參數(shù):
// 第一個參數(shù):sqlId;從CarMapper.xml 文件中復(fù)制,的對于是insert SQL 語句的 id 信息
// 第二個參數(shù): 封裝數(shù)據(jù)的對象,這里為 Map 集合
int count = sqlSession.insert("insertCar", map);

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values (null,#{fdsd},#{k2},#{k3},#{k4},#{k5})
注意:#{這里寫什么?寫map集合的key,如果key不存在,獲取的是null}

運行測試:

在以上sql語句中,可以看到#{k1} #{k2} #{k3} #{k4} #{k5}的可讀性太差,為了增強可讀性,我們可以將Java程序做如下修改:

對應(yīng)的 CarMapper.xml SQL映射文件也是要一一對應(yīng)修改。

運行測試:

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values (null,#{fdsd},#{k2},#{k3},#{k4},#{k5})
注意:#{這里寫什么?寫map集合的key,如果key不存在,獲取的是null}。如下:我們測試

使用Map集合可以傳參,那使用pojo(簡單普通的java對象)可以完成傳參。

java 程序中使用POJO類給SQL語句的占位符傳值。

這里我們定義一個 名為 Car.java 的類,該類要與t_car 數(shù)據(jù)表的屬性,像映射,對應(yīng)上的。不可以隨便定義的。

同時我們將屬性定義為包裝類,防止當我們數(shù)據(jù)表當中取出,獲取到的數(shù)據(jù)是為 null 的時候,包裝類可以賦值上,而簡單類型 int 是無法賦值為 Null 的

同時一定要提供對應(yīng)的 set 和 get 方法,不然 ,MyBatis 無法通過反射機制獲取到相應(yīng)所需要的信息的。

package com.rainbowsea.mybatis.pojo;
public class Car {
    //數(shù)據(jù)表當中的字段應(yīng)該和pojo類的屬性一一對應(yīng)
    // 建議使用包裝類,這樣可以防止 null 的問題:int = null; 不行,Int = null 可以
    private Long id;
    private String carNum;
    private String brand;
    private Double guiderPrice;
    private String produceTime;
    private String carType;
    public Car() {
    }
    public Car(Long id, String carNum, String brand, Double guiderPrice, String produceTime, String carType) {
        this.id = id;
        this.carNum = carNum;
        this.brand = brand;
        this.guiderPrice = guiderPrice;
        this.produceTime = produceTime;
        this.carType = carType;
    }
    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", carNum='" + carNum + '\'' +
                ", brand='" + brand + '\'' +
                ", guiderPrice=" + guiderPrice +
                ", produceTime='" + produceTime + '\'' +
                ", carType='" + carType + '\'' +
                '}';
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getCarNum() {
        return carNum;
    }
/*    public String getXyz() {
        return carNum;
    }*/
    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public Double getGuiderPrice() {
        return guiderPrice;
    }
    public void setGuiderPrice(Double guiderPrice) {
        this.guiderPrice = guiderPrice;
    }
    public String getProduceTime() {
        return produceTime;
    }
    public void setProduceTime(String produceTime) {
        this.produceTime = produceTime;
    }
    public String getCarType() {
        return carType;
    }
    public void setCarType(String carType) {
        this.carType = carType;
    }
}

java 程序中使用POJO類給SQL語句的占位符傳值:

// 封裝數(shù)據(jù)

Car car = new Car(null, "333", "比亞迪泰", 30.0, "2020-11-11", "新能源");

注意:占位符#{ }, 大括號里面寫:pojo類的屬性名

insert into t_car(id,car_num,bread,guider_prive,produce_time,car_type)

values(null,#{xyz},#{brand},#{guiderPrice},#{produceTime},#{carType})

運行測試:

 public void testInsertCarByPOJO() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 封裝數(shù)據(jù)
        Car car = new Car(null, "333", "比亞迪泰", 30.0, "2020-11-11", "新能源");
        // 執(zhí)行SQL
        int count = sqlSession.insert("insertCar", car); // ORM       // 對應(yīng)XxxMapper.xml 上的id
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

如果我們在 XxxMapper.xml(這里是CarMapper.xml) 的SQL映射文件中 的 <insert> 標簽 中的 #{ } 占位符,寫的不是對應(yīng)pojo(這里是 Car) 類上的屬性值時,會出現(xiàn)什么問題,是報錯,還是賦值為 Null呢?

運行測試:

報錯信息:

There is no getter for property named 'xyz' in 'class com.rainbowsea.mybatis.pojo.Car'

mybatis 去找,Car類中的getXyz()方法去了,沒找到,報錯了。

怎么解決的?

我們在pojo(這里是 Car) 類當中加入一個 getXyz( ) 方法,方法的返回值和 原來的getCarNum( )的返回值,一樣就是,方法名不同而已:就是方法名不同,返回的值還是:carNum

再運行測試;

通過這個測試,得出一個結(jié)論:

嚴格意義上來說,如果使用POJO對象傳遞值的話,#{}這個大括號中i給你到底寫什么?

寫的是對應(yīng)的屬性的 get方法的方法名去掉 get,然后將剩下的單詞字母小寫,然后放進去。

例如:getUsername() ---> #{username}

例如: getEmail() ---> #{email}

也就是說MyBatis在底層,傳值的時候,先要獲取值,怎么獲取的?
調(diào)用了pojo對象的get方法,例如:car.getCarNum(); car.getCarType(), car.getBreand() 方法

經(jīng)過測試得出結(jié)論:

如果采用map集合傳參,#{} 里寫的是map集合的key,如果key不存在不會報錯,數(shù)據(jù)庫表中會插入NULL。

如果采用POJO傳參,#{} 里寫的是get方法的方法名去掉get之后將剩下的單詞首字母變小寫(例如:getAge對應(yīng)的是#{age},getUserName對應(yīng)的是#{userName}),如果這樣的get方法不存在會報錯。

注意:其實傳參數(shù)的時候有一個屬性 parameterType,這個屬性用來指定傳參的數(shù)據(jù)類型,不過這個屬性是可以省略的

3.2 delete 刪除記錄

需求:根據(jù) id 刪除數(shù)據(jù),將 id = 44 的數(shù)據(jù)刪除。

編寫XxxMapper.xml SQL 映射的文件, 刪除用 <delete> 標簽

<!--注意: 如果占位符只有一個,那么#{}的大括號里可以隨意,但是最好見名知意--><delete id="deleteById">delete from t_car where id = #{id}</delete>

注意:當占位符只有一個的時候,#{} 里面的內(nèi)容可以隨便寫。

只有一個占位符的時候,傳一個值,MyBatis 可以自動載入,但是 #{} 不可以空著,要寫上值

運行測試:

Java程序執(zhí)行,刪除操作,用sqlSession.delete("Id", 值) 方法,刪除記錄

@Test
    public void testDeleteById() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 執(zhí)行SQL語句
        sqlSession.delete("deleteById",44); // 如果只要一個值的時候,就不需要對應(yīng)上的的 Object 類型了
        sqlSession.commit(); // 提交
        sqlSession.close(); // 關(guān)閉
    }

3.3 update 修改記錄

需求: 根據(jù) id 修改某條記錄

需求:修改 id=46 的Car信息,car_num為999,brand為凱美瑞,guide_price為30.00,produce_time為2020-011-11,car_type為燃油車。

編寫XxxMapper.xml SQL 映射的文件,修改用 <update> 標簽

<update id="updateById">
		update t_car set car_num = #{carNum}, brand=#{brand}, guide_price=#{guiderPrice},produce_time=#{produceTime},
		                 car_type=#{carType} where id =#{id}
	</update>

運行測試:

Java程序執(zhí)行,修改/更新數(shù)據(jù)操作,用sqlSession.update("Id", 值) 方法,修改記錄

   public void testUpdateById() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        Car car = new Car(46L, "999", "凱美瑞", 30.3, "1999-11-10", "燃油車");
        // 執(zhí)行SQL語句
        int count = sqlSession.update("updateById", car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

當然了,如果使用 map傳數(shù)據(jù)也是可以的。

3.4 select 查詢記錄

3.4.5 select 查詢一條記錄

select語句和其它語句不同的是:查詢會有一個結(jié)果集。

需求:根據(jù)id 查詢對應(yīng)的一條記錄,這里我們查詢 id = 1 的記錄信息。

在XxxMapper.xml 文件當中編寫,對應(yīng)的查詢語句,查詢用 <select> 標簽。

運行測試:

因為查詢,沒有修改的操作,是不需要事務(wù)操作的,所以我們不同提交數(shù)據(jù),給數(shù)據(jù)庫。

這里我們查詢的是一條記錄,用 sqlSession.selectOne("id") 方法,返回一個 映射對象。

報錯信息:Error querying database. Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'rainbowsea.selectById'. It's likely that neither a Result Type nor a Result Map was specified.

以上的異常大致的意思是:對于一個查詢語句來說,你需要指定它的“結(jié)果類型”或者“結(jié)果映射”。

所以說,你想讓mybatis查詢之后返回一個Java對象的話,至少你要告訴mybatis返回一個什么類型的Java對象,可以在<select>標簽中添加 resultType 屬性,所賦值的對象是:全限定類名 ,用來指定查詢要轉(zhuǎn)換的類型:

需要特別注意的是:
select 標簽中給的resultType屬性,這個屬性用來告訴mybatis,查詢結(jié)果封裝什么類型的Java對象
resultType通常寫的是:全限定類名

<select id="selectById" resultType="com.rainbowsea.mybatis.pojo.Car">
		select id,car_num as carNum, brand, guide_price as guiderPrice,
		produce_time as produceTime,
		car_type as carType
		from t_car
		where id= #{id}
	</select>

我們再次運行:

運行后之前的異常不再出現(xiàn)了,這說明添加了resultType屬性之后,解決了之前的異常,可以看出resultType是不能省略的。

仔細觀察控制臺的日志信息,不難看出,結(jié)果查詢出了一條。并且每個字段都查詢的到值了:

但是奇怪的是返回的Car對象,只有 id 和 brand 兩個屬性有值,其它屬性的值都是 null,

這是為什么呢?我們來觀察一下查詢結(jié)果列名和Car類的屬性名是否能一一對應(yīng):

通過觀察發(fā)現(xiàn):只有 id 和 brand 是一致的,其他字段名和屬性名對應(yīng)不上,這就是導(dǎo)致null的原因了?我們可以在sql語句中使用 as 關(guān)鍵字來給查詢結(jié)果列名起別名的方式,讓它們兩者保持一致的關(guān)系。

<select id="selectById" resultType="com.rainbowsea.mybatis.pojo.Car">
		select id,car_num as carNum, brand, guide_price as guiderPrice,
		produce_time as produceTime,
		car_type as carType
		from t_car
		where id= #{id}
	</select>

3.4.6 select 查詢多條記錄

需求:查詢所有的Car信息。

編寫對應(yīng)的SQL語句,在 XxxMapper.xml SQl語句映射文件當中。

同樣我們需要使用上 as 關(guān)鍵字,定義別名,使其Java程序和數(shù)據(jù)庫的字段名兩者之間的字段保持一致。

<select id="selectAll" resultType="com.rainbowsea.mybatis.pojo.Car">
		select
		       id,car_num as carNum, brand, guide_price as guiderPrice,
			   produce_time as produceTime,
			   car_type as carType
		from
		       t_car
	</select>

Java代碼如下:

這里,因為我們查詢的是多條記錄,用 sqlSession.selectList("id") 方法,返回一個 List 集合,存儲著我們的查詢結(jié)果集

如果是返回的是鍵值對 的話,我們還可以用 sqlSession.selectMap("id") 方法 返回的是一個 Map 集合

運行結(jié)果:

   <select id="selectAll" resultType="com.rainbowsea.mybatis.pojo.Car">
      select
             id,car_num as carNum, brand, guide_price as guiderPrice,
            produce_time as produceTime,
            car_type as carType
      from
             t_car
   </select>
  List<Car> cars = sqlSession.selectList("selectAll");
注意: resultType 還是指定封裝的結(jié)果集的類型,不是指定List類型,是指定List集合中元素的類型
selectList 方法,mybatis通過這個方法就可以得知你需要一個List集合,它會自動給你返回一個List集合

4. 關(guān)于SQL Mapper 的 namespace 的使用方式

在SQL Mapper配置文件中 標簽的 namespace 屬性可以翻譯為命名空間,這個命名空間主要是為了防止sqlId沖突的。

我們在創(chuàng)建一個 UserMapper.xml 的SQL 語句的映射文件,同樣將其 namespace = "rainbowsa" 這個值,同時兩個配置文件當中都有同一個:select 查詢語句,同時 id 都為 selectAll 。運行看看,存在什么問題?

<?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">
<!--namespace先隨意寫一個-->
<mapper namespace="rainbowsea">
	<select id="selectAll" resultType="com.rainbowsea.mybatis.pojo.Car">
		select
			id,car_num as carNum, brand, guide_price as guiderPrice,
			produce_time as produceTime,
			car_type as carType
		from
			t_car
	</select>
</mapper>

將它們都配置到:將CarMapper.xml 和 UserMapper.xml 都配置到mybatis-config.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>
    <!--    開啟mybatis 對標準日志的實現(xiàn)-->
    <!--    如果導(dǎo)入的第三方框架的日志,沒有下面這個 settings 也是可以的-->
    <!--    <settings>-->
    <!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
    <!--    </settings>-->
    <environments default="development">
        <environment id="development">
            <!--            MANAGED 沒有用第三框架管理的話,都是會被提交的,沒有事務(wù)上的管理了。-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="MySQL123"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--sql映射文件創(chuàng)建好之后,需要將該文件路徑配置到這里-->
        <!--        執(zhí)行XxxMapper.xml 文件的路徑-->
        <!--        resource 屬性自動會從類的根路徑下開始查找資源-->
        <!--        <mapper resource="CarMapper.xml"/>-->
        <!--        <mapper resource="com/CarMapper2.xml"/>-->
        <!--        url屬性: 從絕對路徑當中加載資源。-->
        <!--        語法格式:file:///絕對路徑-->
        <!--        <mapper url="file:///e:/CarMapper.xml"></mapper>-->
        <mapper resource="CarMapper.xml"></mapper>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>
</configuration>

編寫Java代碼如下:

 public void testNamespace() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 執(zhí)行SQL語句
        // 正確的完整寫法:namespace.id
        List<Car> cars = sqlSession.selectList("selectAll");
        // 遍歷
        cars.forEach(car -> {
            System.out.println(car);
        });
        //sqlSession.commit();  查詢不用提交,沒有事務(wù)問題
        sqlSession.close();
    }

運行報錯:

Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'UserMapper.xml'. Cause: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for rainbowsea.selectAll. please check CarMapper.xml and UserMapper.xml
【翻譯】selectCarAll在Mapped Statements集合中不明確(請嘗試使用包含名稱空間的全名,或重命名其中一個條目)
【大致意思是】selectCarAll重名了,你要么在selectCarAll前添加一個名稱空間,要有你改個其它名字。

這里我們修改一下 UserMapper.xml 文件當中的 namespace = "rainbowsea2" 命名空間的值。

同時編寫Java程序的時候,使用上 namespace="rainbowsea2"的命名空間。

查詢成功:

@Test
    public void testNamespace() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 執(zhí)行SQL語句
        // 正確的完整寫法:namespace.id
        List<Car> cars = sqlSession.selectList("rainbowsea2.selectAll");
        // 遍歷
        cars.forEach(car -> {
            System.out.println(car);
        });
        //sqlSession.commit();  查詢不用提交,沒有事務(wù)問題
        sqlSession.close();
    }

實際上,本質(zhì)上,mybatis中的 sqlId 的完整寫法: namespace.id ,注意,之后都這么寫了,這是完整正確的寫法。

5. 總結(jié):

在sql語句中使用 #{map集合的key} 來完成傳值,#{} 等同于JDBC中的 ? ,#{}就是占位符。

在mybatis當中不能使用 ? 占位符,必須使用 #{ } 來代替JDBC當中的 ?

#{ } 和JDBC當中的 ? 是等效的。

{ } 不可以空著,就算是只有一個傳值,也不可以空著,隨便寫,都不可以空著。

pojo 對象的數(shù)據(jù)表 ORM 映射的 類對象,一定要提供對應(yīng)的 set 和 get 方法,不然 ,MyBatis 無法通過反射機制獲取到相應(yīng)所需要的信息的。 注意:占位符#{ }, 大括號里面寫:pojo類的屬性名

如果采用POJO傳參,#{} 里寫的是get方法的方法名去掉get之后將剩下的單詞首字母變小寫(例如:getAge對應(yīng)的是#{age},getUserName對應(yīng)的是#{userName}),如果這樣的get方法不存在會報錯。

注意:其實傳參數(shù)的時候有一個屬性 parameterType,這個屬性用來指定傳參的數(shù)據(jù)類型,不過這個屬性是可以省略的

添加/插入,執(zhí)行 sqlSession.insert("Id", car); 方法

Java程序執(zhí)行,刪除操作,用sqlSession.delete("Id", 值) 方法,刪除記錄,只有一個占位符的時候,傳一個值,MyBatis 可以自動載入,但是 #{} 不可以空著,要寫上值

Java程序執(zhí)行,修改/更新數(shù)據(jù)操作,用sqlSession.update("Id", 值) 方法,修改記錄

因為查詢,沒有修改的操作,是不需要事務(wù)操作的,所以我們不同提交數(shù)據(jù),給數(shù)據(jù)庫。

這里我們查詢的是一條記錄,用 sqlSession.selectOne("id") 方法,返回一個 映射對象。

你想讓mybatis查詢之后返回一個Java對象的話,至少你要告訴mybatis返回一個什么類型的Java對象,可以在<select>標簽中添加 resultType 屬性,所賦值的對象是:全限定類名 ,用來指定查詢要轉(zhuǎn)換的類型:

select 查詢時,需要 pojo的類當中的映射的類對象中的屬性名要與 對應(yīng)數(shù)據(jù)表中的字段名一致,才能賦值成功,不然為 Null。可以使用 as 關(guān)鍵字,定義別名的方式,解決。后面有更好的解決方式。

我們查詢的是多條記錄,用 sqlSession.selectList("id") 方法,返回一個 List 集合,存儲著我們的查詢結(jié)果集。

如果是返回的是鍵值對 的話,我們還可以用 sqlSession.selectMap("id") 方法 返回的是一個 Map 集合

實際上,本質(zhì)上,mybatis中的 sqlId 的完整寫法: namespace.id ,注意,之后都這么寫了,這是完整正確的寫法。

在Java程序當中的寫法: // 執(zhí)行SQL語句 List<Car> cars = sqlSession.selectList("rainbowsea2.selectAll");實際上,本質(zhì)上,mybatis中的sqlId的完整寫法: namespace.id ,注意,之后都這么寫了,這是完整正確的寫法。

6. 最后:

到此這篇關(guān)于MyBatis完成CRUD 詳細細節(jié)內(nèi)容的文章就介紹到這了,更多相關(guān)MyBatis完成CRUD內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺述int與string類型轉(zhuǎn)換的兩種方法

    淺述int與string類型轉(zhuǎn)換的兩種方法

    這篇文章主要介紹了Java中int與string類型轉(zhuǎn)換的兩種方法的相關(guān)資料,需要的朋友可以參考下
    2016-05-05
  • Spring Cloud Alibaba Nacos 入門詳解

    Spring Cloud Alibaba Nacos 入門詳解

    這篇文章主要介紹了Spring Cloud Alibaba Nacos入門詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • SpringBoot日志注解與緩存優(yōu)化詳解

    SpringBoot日志注解與緩存優(yōu)化詳解

    這篇文章主要給大家介紹了關(guān)于SpringBoot日志注解與緩存優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-10-10
  • 使用Javacsv.jar的jar包操作csv文件的方法

    使用Javacsv.jar的jar包操作csv文件的方法

    使用javacsv的jar包很方便的可以操作csv文件。下面通過本教程給大家介紹使用javacsv.jar操作csv文件的方法,感興趣的朋友一起看下吧
    2016-08-08
  • 一文簡介Java中BlockingQueue阻塞隊列

    一文簡介Java中BlockingQueue阻塞隊列

    本文主要介紹了一文簡介Java中BlockingQueue阻塞隊列,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解

    Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解

    這篇文章主要為大家介紹了Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • 關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案

    關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案

    這篇文章主要介紹了關(guān)于Spring多數(shù)據(jù)源TransactionManager沖突的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • JAVA中實現(xiàn)原生的 socket 通信機制原理

    JAVA中實現(xiàn)原生的 socket 通信機制原理

    本篇文章主要介紹了JAVA中實現(xiàn)原生的 socket 通信機制原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Spring SmartLifecycle:如何精準控制Bean的生命周期

    Spring SmartLifecycle:如何精準控制Bean的生命周期

    這篇文章主要介紹了Spring SmartLifecycle:如何精準控制Bean的生命周期問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Java后端實現(xiàn)生成驗證碼圖片的示例代碼

    Java后端實現(xiàn)生成驗證碼圖片的示例代碼

    驗證碼是一種用于驗證用戶身份或確保用戶操作安全的技術(shù)手段,通常以圖形、聲音或文字的形式出現(xiàn),本文主要介紹了如何通過java實現(xiàn)生成驗證碼圖片,需要的可以參考下
    2023-12-12

最新評論