Mybatis(二)--實現CRUD

上篇文章介紹了mybatis入門,在入門案例中使用了查詢所有操作,這篇文章介紹mybatis中對數據庫裏的CRUD操作,在這之前,先導入日誌分析工具log4j

一、日誌分析工具log4j

  1. 導入依賴jar包
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.5</version>
</dependency>
  1. 添加配置文件

    該配置文件只需要添加至resource文件夾下即可,log4j會自動讀取。文件名爲log4j.properties

log4j.rootLogger=DEBUG,A1
log4j.logger.org.apache=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
  1. 結果

在這裏插入圖片描述
配置完成之後控制檯會出現很多的日誌信息

二、CRUD操作

注意:這裏只給出Dao接口類和對應的UserDaoConfig配置文件以及測試類的代碼,對於CRUD操作只需要修改這兩個地方

1. 查詢操作
  1. 查詢所有

com.Dao.userDao

    /**
     * 查詢所有
     */
    List<User> findAll();

UserDaoConfig配置文件

    <select id="findAll" resultType="com.Domain.User">
        select * from user
    </select>

爲避免測試類出現大量的重複代碼,使用如下簡化:

public class Test {
    InputStream in;
    SqlSessionFactoryBuilder builder;
    SqlSessionFactory build;
    SqlSession session;
    UserDao userDao;
    @Before
    public void init() throws IOException {
        in = Resources.getResourceAsStream("MapperConfig.xml");
        builder = new SqlSessionFactoryBuilder();
        build = builder.build(in);
        session = build.openSession();
        userDao = session.getMapper(UserDao.class);
    }

    /**
     * 測試查詢所有
     * @throws IOException
     */
    @org.junit.Test
    public void testFindALll() throws IOException {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
    @After
    public void destory() throws IOException {
        //手動提交事務
        session.commit();
        in.close();
        session.close();
    }

}
  1. 根據id查詢

com.Dao.userDao

    /**
     * 根據id查詢
     * @param userId
     * @return
     */
    User findById(Integer userId);

UserDaoConfig配置文件

    <select id="findById" parameterType="int" resultType="com.Domain.User">
        select * from user where id = #{id}
    </select>
  • select 標籤:書寫查詢sql語句
  • id屬性:用於指定該sql語句對應那個方法
  • parameterType:用於指定傳入參數的類型,這裏處基本數據類型外,其他類要寫全限定類
  • resultType:用於指定結果集的類型。
  • #{}:表示佔位符,與jdbc中的?作用類似

測試代碼

@org.junit.Test
public void testFindById(){
	User user = userDao.findById(42);
	System.out.println(user);
}
2.保存操作
  1. 新增用戶

com.Dao.userDao

/**
     * 新增用戶
     * @param user
     */
    void saveUser(User user);

UserDaoConfig配置文件

    <!-- 增  -->
    <insert id="saveUser" parameterType="com.Domain.User" >
        insert into user (username,birthday,sex,address) values (#{username}, #{birthday}, #{sex}, #{address})
    </insert>

測試代碼

/**
     * 保存用戶
     */
    @org.junit.Test
    public void testSaveUser(){
        User user = new User();
        user.setBirthday(new Date());
        user.setSex("男");
        user.setUsername("zhangsan");
        user.setAddress("西安市");
        System.out.println(user);
        userDao.saveUser(user);
    }
  • insert:書寫insert插入sql語句
  • 注意:這裏必須要手動提交事務,如果不提交事務,mybatis會自動回滾事務,那麼就不能保存。
session.commit();

注意:新增用戶的id返回值。因爲這裏的id是AUTO_INCREMENT是自增長的,如果要返回當前新增的用戶的id值,那麼就要在UserDaoConfig配置文件中insert標籤中加入

    <!---->
    <insert id="saveUser" parameterType="com.Domain.User" >
        <selectKey keyColumn="id" keyProperty="id" resultType="int" >
            select last_insert_id();
        </selectKey>
        insert into user (username,birthday,sex,address) values (#{username}, #{birthday}, #{sex}, #{address})
    </insert>

然後運行
在這裏插入圖片描述

3.刪除操作

com.Dao.userDao

/**
* 刪除用戶
* @param id
* @return int
*/
int deleteUser(int id);

UserDaoConfig配置文件

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

測試代碼

    @org.junit.Test
    public void testDeleteuser(){
        int deleteuser = userDao.deleteUser(42);
        System.out.println(deleteuser);
    }

4.更新操作

com.Dao.userDao

    /**
     * 更新用戶
     */
    int updateUser(User user);

UserDaoConfig配置文件

    <!-- 更新用戶 -->
    <update id="updateUser" parameterType="com.Domain.User" >
        update user set username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address} where id = #{id}
    </update>
5.模糊查詢
  1. #{}的方式

com.Dao.userDao

/**
* 模糊查詢
* @return
*/
List<User> fingByName(String username);

UserDaoConfig配置文件

    <!-- 模糊查詢 -->
    <select id="fingByName" parameterType="String" resultType="com.Domain.User">
        select * from user where username like #{username};
    </select>

測試代碼

@org.junit.Test
public void testFindByName(){
    List<User> users = userDao.fingByName("%王%");
    for (User user : users) 
        System.out.println(user);
    }
}

注意:在sql語句中模糊查詢時要加入%%,但是我們在配置文件內沒有加入,所以要在傳入參數的時候加入,不加入則沒法模糊查詢

  1. ${}的方式

UserDaoConfig配置文件

    <select id="fingByName" parameterType="String" resultType="com.Domain.User">
        select * from user where username like '%${value}%';
    </select>

測試代碼裏就不用%%了,這中方法明顯是使用拼接字符串的方式。並且需要注意的是${}裏面的值只能寫value寫其他內容則會報錯

6.聚合函數

com.Dao.userDao

int findtotal();

UserDaoConfig配置文件

    <select id="findtotal" resultType="int">
        select count(id) from user;
    </select>

測試代碼

@org.junit.Test
public void testFindTatal(){
    int count = userDao.findtotal();
    System.out.println(count);
}

三、#{}與${}

#{}表示一個佔位符號

​ 通過#{}可以實現 preparedStatement 向佔位符中設置值,自動進行 java 類型和 jdbc 類型轉換,#{}可以有效防止 sql 注入。 #{}可以接收簡單類型值或 pojo 屬性值。 如果 parameterType 傳輸單個簡單類型值,#{}括號中可以是 value或其它名稱。

${}表示拼接 sql 串

​ 通過${}可以將 parameterType 傳入的內容拼接在 sql 中且不進行 jdbc 類型轉換, pojoparameterType{}可以接收簡單類型值或 pojo 屬性值,如果 parameterType 傳輸單個簡單類型值,{}括號中只能是 value。

不使用resultType的方式

​ 前面講的CRUD的操作傳入的參數都是使用了resultType這個標籤來實現的,其實也可以不使用這個標籤,例如:

com.Dao.userDao

/**
* 不使用resultType的方式
*/
User findById2(@Param("id") int id);

UserDaoConfig配置文件

	<select id="findById2" resultType="com.Domain.User">
        select * from user where id =  #{param1};
    </select>

可以使用@Param的方式來實現

四、mybatis的sql配置文件

1.parameterType

parameterType在Dao的配置文件中充當傳入參數的作用,它的格式爲:

  • 實體類:全限定類名(沒有設置別名的情況下)
  • 基本數據類型和String類:包名,類名,直接寫類型名稱

基本數據類型和String類型,可以不用寫全限定類名的原因是,mybatis已經將基本數據類型和String類設置了別名,所以只需要使用別名就可以。當然,mybatis還支持自定義別名,設置方法如下:在主配置文件下,配置typeAliases標籤,這個後面說明。

2.resultType

​ resultType屬性可以指定結果集類型,支持的結果集類型和parameterType一樣,當然也有定義別名。需要注意的是如果結果集是實體類,那麼實體類的屬性要和數據庫中的表的列名要一致。

3.resultMap

​ 使用resultType必須要求數據庫表中的列名和實體類的屬性值要一致,如果不一致則會封裝不到數據,當然在數據庫的層面上提供了一個解決辦法,就是在sql語句中設置別名,不過這個方法有點麻煩。對於每條sql語句都要設置別名。

​ mybatis爲我們提供了一個解決辦法(這裏還要注意:mysql在windows下是不區分大小寫的)。就是使用resultMap封裝結果集。

實體類的屬性(getter和setter方法去掉get(set)後將首字母小寫):

public class User {
    private Integer userid;
    private String userName;
    private String userSex;
    private Date userBirthday;
    private String userAddress;

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserSex() {
        return userSex;
    }

    public void setUserSex(String userSex) {
        this.userSex = userSex;
    }

    public Date getUserBirthday() {
        return userBirthday;
    }

    public void setUserBirthday(Date userBirthday) {
        this.userBirthday = userBirthday;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    @Override
    public String toString() {
        return "User{" +
                "userid=" + userid +
                ", userName='" + userName + '\'' +
                ", userSex='" + userSex + '\'' +
                ", userBirthday=" + userBirthday +
                ", userAddress='" + userAddress + '\'' +
                '}';
    }
}

現在查詢所有肯定是查詢不到的、
在這裏插入圖片描述
但是還是有部分數據被查詢到了,這是因爲mysql在windows下不區分大小寫的原因。接下來就是要配置dao配置文件

userDaoConfig.xml

 <resultMap id="userMap" type="com.Domain.User">
        <id column="id" property="userid"></id>
        <result column="username" property="userName"></result>
        <result column="sex" property="userSex"></result>
        <result column="address" property="userAddress"></result>
        <result column="birthday" property="userBirthday"></result>
    </resultMap>

    <!--配置查詢所有-->
    <select id="findAll" resultMap="userMap">
        select id, username, sex as usersex, birthday from user
    </select>
  • type屬性:指定實體類的全限定類名
  • id屬性:唯一標識,在sql語句的標籤內使用
  • id標籤:主鍵字段
  • result標籤:非主鍵字段
  • column屬性:數據庫列名
  • property屬性:實體類屬性名稱

指定好resultMap的配置之後,要在sql語句標籤中使用resultMap屬性,值爲設置的id,這樣就可以解決數據庫列名和實體類屬性值不一樣的問題了。

4.sql標籤

使用sql標籤,可以將一些常用的sql語句封裝好,要用的時候直接引用即可

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


    <!--配置查詢所有-->
    <select id="findAll" resultType="com.Domain.User">
        <include refid="default"></include>
    </select>

五、主配置文件詳解

主配置文件中的常見標籤以及順序

configuration
    properties(屬性)
        --property
    -settings(全局配置參數)
        --setting
    -typeAliases(類型別名)
        --typeAliase
        --package
    -environments(環境集合屬性對象)
        --environment(環境子屬性對象)
            ---transactionManager(事務管理)
            ---dataSource(數據源)
    -mappers(映射器)
        --mapper
        --package

這裏需要特別注意的是這些個配置文件的順序,是不能顛倒的,xml的約束是很嚴格的。

1.properties

這個標籤主要是改造dataSource的,在沒使用這個標籤之前,我們是這樣配置的

<dataSource type="POOLED">
	<!-- 配置連接數據庫的4個基本信息 -->
	<property name="driver" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://localhost:3306/user?characterEncoding=UTF-8"/>
	<property name="username" value="root"/>
	<property name="password" value="213213"/>
</dataSource>

在這裏寫顯得比較冗餘,這裏可以使用一個properties標籤,將這些信息寫入配置文件,其中的resource屬性可以用來指定配置文件的路徑。

主配置文件MapperConfig.xml

  <properties resource="db.properties"></properties>        

db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user?characterEncoding=UTF-8
username=root
password=213213

配置好了properties標籤之後,在dataSource數據源中就可以直接通過${key},這裏的key指的是在配置文件內使用的key。

<!-- 配置數據源(連接池) -->
            <dataSource type="POOLED">
                <!-- 配置連接數據庫的4個基本信息 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>

需要注意的是,db.properties需要寫在類路徑下,當然這個maven工程就要在resource目錄下了。

properties的屬性:

  • resource:用於指定 properties 配置文件的位置,要求配置文件必須在類路徑下
  • url:指定資源的url,不常用

當然,如果不想重新建一個配置文件,也可以在properties標籤下有一個子標籤propertie,在子標籤中有2個屬性,name和value,這兩個屬性的用處很顯然,name就是key,對應着配置文件中key,value。

    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/user?characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="213213"/>
    </properties>
2.typeAliases

這個標籤在前面已經提到過,這個標籤是用來設置別名的,在resulttype或者是resulyMap中要寫全限定類名,如果每個配置都要這麼書寫則會很麻煩,於是mybatis給我們提供了這麼一個標籤,去寫別名

  • typeAlias :單個定義別名
    • alias:別名名稱
    • type:要設置別名的類
  • package:批量別名定義,掃描整個包下的類,別名爲類名(首字母大寫或小寫都可以)
    <typeAliases>
        <typeAlias type="com.Domain.User" alias="user"></typeAlias>
        <package name="com.Domain"/>
    </typeAliases>
3.mappers

這個標籤是用來配置dao配置文件的映射標籤,其中有個子標籤mapper指定其resource屬性或者class屬性

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