JavaWeb——MyBatis框架之入門總結及案例實戰,常見坑處理:Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0


目錄

1 引導

2 MyBatis框架入門

2.1 MyBatis環境搭建

2.2 MyBatis入門案例實戰

2.2.1 MyBatis讀取數據庫的入門案例實戰

2.2.2 入門案例設計模式分析

2.2.3 MaBatis基於注解的入門案例


1 引導

框架的概念在以前的博文中也有提到,此處簡單說明下,框架實質是軟件開發中的一套解決方案,不同的框架解決的是不同的問題。

1)使用框架的好處:框架封裝了很多細節,開發者可以很簡單的實現某些功能,提高開發效率;

2)框架解決了什么問題?

看下三層架構和SSM框架的對應關系,MyBatis框架是解決的持久層的問題,與數據庫交互,進行增刪改查操作的。

3)持久層技術解決方案有哪些?

  • JDBC技術:Connection、PreparedStatement、ResultSet;
  • Spring的JdbcTemplate:Spring對Jdbc的簡單封裝;
  • Apache的DBUtils,和Spring的JdbcTemplate類似,也是對Jdbc的簡單封裝;

以上都不是框架,JDBC是規范,后兩者都只是工具類,是對規范的實現,沒有系統的解決方案。

以前使用傳統jdbc的步驟很多,操作繁雜,我們要實現一個需求的功能,從數據庫表中查找一個結果,希望沒有這么多繁雜的操作步驟,把焦點放在功能的實現上即可,實現高效率開發,MyBatis框架就是幫我們解決這些問題的。

2 MyBatis框架入門

MyBatis是一個基於Java的持久層框架,封裝了jdbc操作的細節,開發者只需要關注sql語句本身,不需要關注注冊驅動、創建連接、創建statement等過程,它使用了ORM思想實現了結果集封裝。

注:ORM,Object Relational Mapping對象關系映射,就是把數據庫表和實體類的屬性對應起來,讓我們可以操作實體類就可以操作數據庫表。我們需要保證實體類屬性和數據庫表的字段名稱保持一致,有一個好習慣;

2.1 MyBatis環境搭建

下面以一個案例形式一步步看下如何搭建MyBatis環境。

1)准備數據庫,在本地數據庫db4中新建一個user表,插入數據:

  1.  
    CREATE DATABASE db4;
  2.  
    USE db4;
  3.  
    CREATE TABLE USER (
  4.  
    id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  5.  
    username VARCHAR(32) NOT NULL COMMENT '用戶名稱',
  6.  
    birthday DATETIME DEFAULT NULL COMMENT '生日',
  7.  
    sex VARCHAR(1) DEFAULT NULL COMMENT '性別',
  8.  
    address VARCHAR(256) DEFAULT NULL COMMENT '地址'
  9.  
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
  10.  
     
  11.  
    INSERT INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES (1,'老王','2018-02-27 17:47:08','男','北京'),(2,'李四','2018-03-02 15:09:37','女','上海'),(3,'王五','2018-03-04 11:34:34','女','南京');

2)新建Maven工程,不使用模板,此處不展開了,需要回顧的可以看上一篇博文

3)配置pom.xml文件,導入相關的jar包坐標:

  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.  
    <modelVersion>4.0.0</modelVersion>
  6.  
     
  7.  
    <groupId>com.winter</groupId>
  8.  
    <artifactId>19.mybatis</artifactId>
  9.  
    <version>1.0-SNAPSHOT</version>
  10.  
     
  11.  
    <packaging>jar</packaging>
  12.  
     
  13.  
    <dependencies>
  14.  
    <dependency>
  15.  
    <groupId>org.mybatis</groupId>
  16.  
    <artifactId>mybatis</artifactId>
  17.  
    <version>3.4.5</version>
  18.  
    </dependency>
  19.  
     
  20.  
    <dependency>
  21.  
    <groupId>mysql</groupId>
  22.  
    <artifactId>mysql-connector-java</artifactId>
  23.  
    <version>5.1.6</version>
  24.  
    </dependency>
  25.  
     
  26.  
    <dependency>
  27.  
    <groupId>log4j</groupId>
  28.  
    <artifactId>log4j</artifactId>
  29.  
    <version>1.2.12</version>
  30.  
    </dependency>
  31.  
     
  32.  
    <dependency>
  33.  
    <groupId>junit</groupId>
  34.  
    <artifactId>junit</artifactId>
  35.  
    <version>4.10</version>
  36.  
    <scope>test</scope>
  37.  
    </dependency>
  38.  
    </dependencies>
  39.  
    </project>

4)寫一個User實體類,實現Serializable,數據庫表對應

  1.  
    public class User implements Serializable {
  2.  
    private Integer id;
  3.  
    private String username;
  4.  
    private Date birthday;
  5.  
    private String sex;
  6.  
    private String address;
  7.  
     
  8.  
    public Integer getId() {
  9.  
    return id;
  10.  
    }
  11.  
     
  12.  
    public void setId(Integer id) {
  13.  
    this.id = id;
  14.  
    }
  15.  
     
  16.  
    public String getUsername() {
  17.  
    return username;
  18.  
    }
  19.  
     
  20.  
    public void setUsername(String username) {
  21.  
    this.username = username;
  22.  
    }
  23.  
     
  24.  
    public Date getBirthday() {
  25.  
    return birthday;
  26.  
    }
  27.  
     
  28.  
    public void setBirthday(Date birthday) {
  29.  
    this.birthday = birthday;
  30.  
    }
  31.  
     
  32.  
    public String getSex() {
  33.  
    return sex;
  34.  
    }
  35.  
     
  36.  
    public void setSex(String sex) {
  37.  
    this.sex = sex;
  38.  
    }
  39.  
     
  40.  
    public String getAddress() {
  41.  
    return address;
  42.  
    }
  43.  
     
  44.  
    public void setAddress(String address) {
  45.  
    this.address = address;
  46.  
    }
  47.  
     
  48.  
    @Override
  49.  
    public String toString() {
  50.  
    return "User{" +
  51.  
    "id=" + id +
  52.  
    ", username='" + username + '\'' +
  53.  
    ", birthday=" + birthday +
  54.  
    ", sex='" + sex + '\'' +
  55.  
    ", address='" + address + '\'' +
  56.  
    '}';
  57.  
    }
  58.  
    }

5)寫一個User的持久層接口

  1.  
    //User的持久層接口
  2.  
    public interface UserDao {
  3.  
    List<User> findAll();
  4.  
    }

至此,准備工作OK了,下面看下MyBatis的環境。

6)在resources包下新建SqlMapConfig.xml文件作為MyBatis的主配置文件,其中做兩件事:

  • 配置MySQL的環境:事務類型、連接池、四個基本信息(驅動、url、用戶名、密碼);
  • 指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件;
  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <!DOCTYPE configuration
  3.  
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4.  
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5.  
    <!--mybatis的主配置文件 -->
  6.  
    <configuration>
  7.  
    <!--配置環境 -->
  8.  
    <environments default="mysql">
  9.  
    <!--配置mysql環境 -->
  10.  
    <environment id="mysql">
  11.  
    <!--配置事務類型 -->
  12.  
    <transactionManager type="JDBC"></transactionManager>
  13.  
    <!--配置數據源(連接池) -->
  14.  
    <dataSource type="POOLED">
  15.  
    <!--配置連接數據庫的四個基本信息 -->
  16.  
    <property name="driver" value="com.mysql.jdbc.Driver"/>
  17.  
    <property name="url" value="jdbc:mysql://localhost:3306/db4"/>
  18.  
    <property name="username" value="root"/>
  19.  
    <property name="password" value="root"/>
  20.  
    </dataSource>
  21.  
    </environment>
  22.  
    </environments>
  23.  
    <!--指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件 -->
  24.  
    <mappers>
  25.  
    <mapper resource="com/winter/dao/UserDao.xml"></mapper>
  26.  
    </mappers>
  27.  
    </configuration>

7)新建每個dao的獨立配置文件,注意三件事:

  • 在resources包下新建com.winter.dao三級包(mybatis映射配置文件必須和dao接口的包結構相同),命名為UserDao.xml,和SqlMapConfig.xml中指定的名字要一致;
  • mapper標簽下的namespace屬性要是UserDao接口的全限定類名;
  • 操作配置(select標簽中配置sql語句)中id屬性要與UserDao接口中的方法名字一致;
  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <!DOCTYPE mapper
  3.  
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.  
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5.  
     
  6.  
    <mapper namespace="com.winter.dao.UserDao">
  7.  
    <!--配置查詢所有 -->
  8.  
    <select id="findAll">
  9.  
    select * from user
  10.  
    </select>
  11.  
    </mapper>

映射配置文件中的限制很多,這么做的好處是什么呢?我們不需要再寫dao的實現類了!(上述的獨立配置文件還有點小問題,你發現了嗎?沒有的話繼續閱讀下文:))

完成以上后,工程目錄結構如下:

2.2 MyBatis入門案例實戰

2.2.1 MyBatis讀取數據庫的入門案例實戰

在上一節環境搭建的基礎上,我們看下如何使用MyBatis,使用的步驟是怎樣的,可以總結為如下幾個步驟:

  • 1)讀取配置文件;
  • 2)創建SqlSessionFactory工廠;
  • 3)使用工廠生產SqlSession對象;
  • 4)使用SqlSession創建Dao接口的代理對象;
  • 5)使用代理對象執行方法;
  • 6)釋放資源。

在src.test.java.com.winter.test包下新建一個測試類MyBatisTest.java:

  1.  
    public class MyBatisTest {
  2.  
    //MyBatis入門案例
  3.  
    @Test
  4.  
    public void test() throws Exception{
  5.  
    //1、讀取配置文件
  6.  
    InputStream in = Resources.getResourceAsStream( "SqlMapConfig.xml");
  7.  
    //2、創建SqlSessionFactory工廠
  8.  
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  9.  
    SqlSessionFactory factory = builder.build(in);
  10.  
    //3、使用工廠生產SqlSession對象
  11.  
    SqlSession session = factory.openSession();
  12.  
    //4、使用SqlSession創建Dao接口的代理對象
  13.  
    UserDao userDao = session.getMapper(UserDao.class);
  14.  
    // 5、使用代理對象執行方法
  15.  
    List<User> users = userDao.findAll();
  16.  
    for (User user : users) {
  17.  
    System.out.println(user);
  18.  
    }
  19.  
    //6、釋放資源
  20.  
    session.close();
  21.  
    in.close();
  22.  
    }
  23.  
    }

【運行測試】:發現如下異常問題出現:

### Error querying database.  Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.winter.dao.UserDao.findAll'.  It's likely that neither a Result Type nor a Result Map was specified.

我們在UserDao.xml里面寫了sql查詢語句,但是MyBatis不知道查詢結果要封裝到哪里去,所以要在UserDao.xml中對應提供另一個指定的對象類型,修正后的UserDao.xml如下:

  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <!DOCTYPE mapper
  3.  
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.  
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5.  
     
  6.  
    <mapper namespace="com.winter.dao.UserDao">
  7.  
    <!--配置查詢所有 -->
  8.  
    <select id="findAll" resultType="com.winter.domain.User">
  9.  
    select * from user
  10.  
    </select>
  11.  
    </mapper>

再次運行測試OK:

【小插曲——調試問題】:開始MyBatisTest中使用public static void main(String[] args)方法測試,但是運行時始終報錯:

Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:exec (default-cli) on project 19.mybatis: Command execution failed.

網上查找各種解決方法,如項目的java版本配置和JDK要一致等等,最后都沒解決,懷疑是Maven支持的JDK版本問題,我的是14.0.1,最后通過junit解決,@Test注解運行就可以了。

2.2.2 入門案例設計模式分析

基於上述案例,分析下設計模式。

1)讀取配置文件

不建議使用絕對路徑,或相對路徑,不夠靈活,實際項目中多使用以下兩種:

  • 使用類加載器,它只能讀取類路徑的配置文件;
  • 使用ServletContext對象的getRealPath();

2)創建SqlSessionFactory工廠

MyBatis使用了構建者模式,把對象的創建細節隱藏,使用者直接調用方法即可獲取對象。像我們自己蓋廠房一樣,不是事事親為,我們找個包工隊,告訴需求,給錢即可:

  • SqlSessionFactoryBuilder類似於包工隊;
  • in類似於我們給的錢;

3)創建SqlSession對象

使用了工廠模式,降低了類之間的依賴關系

4)創建dao接口的代理對象

使用了代理模式,不修改源碼的基礎上對已有方法增強;

2.2.3 MaBatis基於注解的入門案例

以上基於xml的實現方式是不是感覺有些麻煩,映射配置文件有很多要對應的關系,下面來看下比較簡單的方式,使用注解,相比於xml,主要改變在於:

  • 移除UserDao.xml,在dao接口的方法上使用@Select注解,並且指定SQL語句;
  • 在SqlMapConfig.xml中的mapper配置時,使用class屬性指定dao接口的全限定類名。

【UserDao接口】:

  1.  
    public interface UserDao {
  2.  
    @Select("select * from user")
  3.  
    List<User> findAll();
  4.  
    }

【SqlMapConfig.xml中mapper配置】:

  1.  
    <!--指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件
  2.  
    若使用注解配置,應該使用class屬性指定被注解的dao全限定類名
  3.  
    -->
  4.  
    <mappers>
  5.  
    <mapper class="com.winter.dao.UserDao"></mapper>
  6.  
    </mappers>

【注意】:實際MyBatis也是支持寫dao實現類的,但是實際開發中追求的理念就是越簡單越好,無論是xml還是注解形式,一般都是不寫dao實現類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM