当前位置:Gxlcms > 数据库问题 > MyBatis系列目录--4. MyBatis别名、字段冲突、动态sql、日志、xml其他组件等若干优化

MyBatis系列目录--4. MyBatis别名、字段冲突、动态sql、日志、xml其他组件等若干优化

时间:2021-07-01 10:21:17 帮助过:2人阅读

  •    
  • <dependency>  
  •     <groupId>ch.qos.logback</groupId>  
  •     <artifactId>logback-core</artifactId>  
  •     <version>${logback.version}</version>  
  • </dependency>  
  • <dependency>  
  •     <groupId>ch.qos.logback</groupId>  
  •     <artifactId>logback-classic</artifactId>  
  •     <version>${logback.version}</version>  
  • </dependency>  
  • <logback.version>1.0.13</logback.version>
     
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>${logback.version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>

     

       配置(logback.xml):默认debug,也可以分开logger去实现(org.apache.ibatis, java.sql)

    Xml代码 技术分享 技术分享
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <configuration scan="true" scanPeriod="5 seconds">  
    3.     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
    4.         <encoder>  
    5.             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>  
    6.         </encoder>  
    7.     </appender>  
    8.     <root level="DEBUG">  
    9.         <appender-ref ref="STDOUT"/>  
    10.     </root>  
    11. </configuration>  
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="5 seconds">
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <root level="DEBUG">
            <appender-ref ref="STDOUT"/>
        </root>
    </configuration>

    二、实体别名

    【java框架源码下载】

    在xml配置中的resultType和parameterType都需要写全路径类名,这样不太方便,mybatis提供了别名机制解决这个问题。

     

    1. 在mybatis-base.xml中添加如下(注意要添加到配置的最前头)

    Xml代码 技术分享 技术分享
    1. <typeAliases>  
    2.     <typeAlias type="com.sohu.tv.bean.Player" alias="Player"/>  
    3. </typeAliases>  
    <typeAliases>
        <typeAlias type="com.sohu.tv.bean.Player" alias="Player"/>
    </typeAliases>

     

    playerMapper.xml在使用resultType和parameterType直接写别名就可以了

    Xml代码 技术分享 技术分享
    1. <mapper namespace="com.sohu.tv.mapper.playerMapper">  
    2.     <select id="getPlayer" parameterType="int" resultType="Player">  
    3.         select id,name,age from players where id=#{id}  
    4.     </select>  
    5. </mapper>  
    <mapper namespace="com.sohu.tv.mapper.playerMapper">
        <select id="getPlayer" parameterType="int" resultType="Player">
            select id,name,age from players where id=#{id}
        </select>
    </mapper>

     

     

    2. 如果想使得一个package下所有实体类都用简单类名作为别名,可以使用如下配置:

    Xml代码 技术分享 技术分享
    1. <typeAliases>  
    2.     <!--  
    3.     <typeAlias type="com.sohu.tv.bean.Player" alias="Player"/> 
    4.     -->  
    5.     <package name="com.sohu.tv.bean"/>  
    6. </typeAliases>  
    <typeAliases>
        <!-- 
        <typeAlias type="com.sohu.tv.bean.Player" alias="Player"/>
        -->
        <package name="com.sohu.tv.bean"/>
    </typeAliases>

    三、字段冲突:

    1. 产生冲突

    (1).  建表

     

    Java代码 技术分享 技术分享
    1. CREATE TABLE club(  
    2. id INT PRIMARY KEY AUTO_INCREMENT,  
    3. name varchar(20) not null comment ‘俱乐部名称‘,   
    4. info varchar(255) not null comment ‘俱乐部简介‘,  
    5. create_date date comment ‘创建日期‘,  
    6. rank smallint comment ‘排名‘  
    7. )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=‘俱乐部表‘;  
    8. INSERT INTO club(name, info, create_date, rank) VALUES(‘AC‘, ‘AC米兰‘, ‘1899-12-26‘, 5);  
    9. INSERT INTO club(name, info, create_date, rank) VALUES(‘Real Madrid‘, ‘皇家马德里‘, ‘1902-03-06‘, 1);  
    10. INSERT INTO club(name, info, create_date, rank) VALUES(‘Inter‘, ‘国际米兰‘, ‘1908-03-09‘, 7);  
    CREATE TABLE club(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name varchar(20) not null comment ‘俱乐部名称‘, 
    info varchar(255) not null comment ‘俱乐部简介‘,
    create_date date comment ‘创建日期‘,
    rank smallint comment ‘排名‘
    )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT=‘俱乐部表‘;
    INSERT INTO club(name, info, create_date, rank) VALUES(‘AC‘, ‘AC米兰‘, ‘1899-12-26‘, 5);
    INSERT INTO club(name, info, create_date, rank) VALUES(‘Real Madrid‘, ‘皇家马德里‘, ‘1902-03-06‘, 1);
    INSERT INTO club(name, info, create_date, rank) VALUES(‘Inter‘, ‘国际米兰‘, ‘1908-03-09‘, 7);

     

    (2). 实体类
    Java代码 技术分享 技术分享
    1. package com.sohu.tv.bean;  
    2. import java.util.Date;  
    3. /** 
    4.  * 俱乐部 
    5.  *  
    6.  * @author leifu 
    7.  * @Date 2015年7月28日 
    8.  * @Time 下午1:43:53 
    9.  */  
    10. public class Club {  
    11.     /** 
    12.      * 俱乐部id 
    13.      */  
    14.     private int id;  
    15.     /** 
    16.      * 俱乐部名 
    17.      */  
    18.     private String clubName;  
    19.     /** 
    20.      * 俱乐部描述 
    21.      */  
    22.     private String clubInfo;  
    23.     /** 
    24.      * 创建日期 
    25.      */  
    26.     private Date createDate;  
    27.        
    28.     /** 
    29.      * 排名 
    30.      */  
    31.     private int rank;  
    32.     public int getId() {  
    33.         return id;  
    34.     }  
    35.     public void setId(int id) {  
    36.         this.id = id;  
    37.     }  
    38.     public String getClubName() {  
    39.         return clubName;  
    40.     }  
    41.     public void setClubName(String clubName) {  
    42.         this.clubName = clubName;  
    43.     }  
    44.     public String getClubInfo() {  
    45.         return clubInfo;  
    46.     }  
    47.     public void setClubInfo(String clubInfo) {  
    48.         this.clubInfo = clubInfo;  
    49.     }  
    50.     public Date getCreateDate() {  
    51.         return createDate;  
    52.     }  
    53.     public void setCreateDate(Date createDate) {  
    54.         this.createDate = createDate;  
    55.     }  
    56.     public int getRank() {  
    57.         return rank;  
    58.     }  
    59.     public void setRank(int rank) {  
    60.         this.rank = rank;  
    61.     }  
    62.     @Override  
    63.     public String toString() {  
    64.         return "Club [id=" + id + ", clubName=" + clubName + ", clubInfo=" + clubInfo + ", createDate=" + createDate  
    65.                 + ", rank=" + rank + "]";  
    66.     }  
    67.    
    68. }  
    package com.sohu.tv.bean;
    import java.util.Date;
    /**
     * 俱乐部
     * 
     * @author leifu
     * @Date 2015年7月28日
     * @Time 下午1:43:53
     */
    public class Club {
        /**
         * 俱乐部id
         */
        private int id;
        /**
         * 俱乐部名
         */
        private String clubName;
        /**
         * 俱乐部描述
         */
        private String clubInfo;
        /**
         * 创建日期
         */
        private Date createDate;
         
        /**
         * 排名
         */
        private int rank;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getClubName() {
            return clubName;
        }
        public void setClubName(String clubName) {
            this.clubName = clubName;
        }
        public String getClubInfo() {
            return clubInfo;
        }
        public void setClubInfo(String clubInfo) {
            this.clubInfo = clubInfo;
        }
        public Date getCreateDate() {
            return createDate;
        }
        public void setCreateDate(Date createDate) {
            this.createDate = createDate;
        }
        public int getRank() {
            return rank;
        }
        public void setRank(int rank) {
            this.rank = rank;
        }
        @Override
        public String toString() {
            return "Club [id=" + id + ", clubName=" + clubName + ", clubInfo=" + clubInfo + ", createDate=" + createDate
                    + ", rank=" + rank + "]";
        }
     
    }

     

    (3) Dao

    Java代码 技术分享 技术分享
    1. package com.sohu.tv.mapper;  
    2. import java.util.List;  
    3.    
    4. import com.sohu.tv.bean.Club;  
    5. /** 
    6.  * 俱乐部Dao 
    7.  * @author leifu 
    8.  * @Date 2015年8月3日 
    9.  * @Time 下午2:30:58 
    10.  */  
    11. public interface ClubDao {  
    12.     /** 
    13.      * 获取所有俱乐部信息 
    14.      * @return 
    15.      */  
    16.     public List<Club> getAllClubs();  
    17. }  
    package com.sohu.tv.mapper;
    import java.util.List;
     
    import com.sohu.tv.bean.Club;
    /**
     * 俱乐部Dao
     * @author leifu
     * @Date 2015年8月3日
     * @Time 下午2:30:58
     */
    public interface ClubDao {
        /**
         * 获取所有俱乐部信息
         * @return
         */
        public List<Club> getAllClubs();
    }

     

    (4). 添加clubMapper.xml配置
    Xml代码 技术分享 技术分享
    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
    3. <mapper namespace="com.sohu.tv.mapper.ClubDao">  
    4.     <select id="getAllClubs" resultType="Club">  
    5.         select id,name,info,create_date,rank from club  
    6.     </select>  
    7. </mapper>  
    <?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">
    <mapper namespace="com.sohu.tv.mapper.ClubDao">
        <select id="getAllClubs" resultType="Club">
            select id,name,info,create_date,rank from club
        </select>
    </mapper>
    (5). 添加clubMapper.xml到总配置文件中
    Xml代码 技术分享 技术分享
    1. <mappers>  
    2.     <mapper resource="mapper/clubMapper.xml" />  
    3. </mappers>  
    <mappers>
        <mapper resource="mapper/clubMapper.xml" />
    </mappers>

     

    (6). 单元测试:
    Java代码 技术分享 技术分享
    1. package com.sohu.tv.test.mapper;  
    2. import java.util.List;  
    3. import org.apache.ibatis.session.SqlSession;  
    4. import org.junit.After;  
    5. import org.junit.Before;  
    6. import org.junit.Test;  
    7. import com.sohu.tv.bean.Club;  
    8. import com.sohu.tv.mapper.ClubDao;  
    9. /** 
    10.  * 俱乐部dao测试 
    11.  *  
    12.  * @author leifu 
    13.  * @Date 2015年8月3日 
    14.  * @Time 下午2:33:04 
    15.  */  
    16. public class ClubMapperXmlTest extends BaseTest {  
    17.     private SqlSession sqlSession;  
    18.     @Before  
    19.     public void before() {  
    20.         sqlSession = sessionFactory.openSession(true);  
    21.     }  
    22.     @After  
    23.     public void after() {  
    24.         sqlSession.close();  
    25.     }  
    26.     @Test  
    27.     public void testGetAllClubs() {  
    28.         ClubDao clubDao = sqlSession.getMapper(ClubDao.class);  
    29.         List<Club> clubList = clubDao.getAllClubs();  
    30.         if (clubList != null && !clubList.isEmpty()) {  
    31.             System.out.println("clubList size: " + clubList.size());  
    32.             for (Club club : clubList) {  
    33.                 System.out.println(club);  
    34.             }  
    35.         }  
    36.     }  
    37. }  
    package com.sohu.tv.test.mapper;
    import java.util.List;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import com.sohu.tv.bean.Club;
    import com.sohu.tv.mapper.ClubDao;
    /**
     * 俱乐部dao测试
     * 
     * @author leifu
     * @Date 2015年8月3日
     * @Time 下午2:33:04
     */
    public class ClubMapperXmlTest extends BaseTest {
        private SqlSession sqlSession;
        @Before
        public void before() {
            sqlSession = sessionFactory.openSession(true);
        }
        @After
        public void after() {
            sqlSession.close();
        }
        @Test
        public void testGetAllClubs() {
            ClubDao clubDao = sqlSession.getMapper(ClubDao.class);
            List<Club> clubList = clubDao.getAllClubs();
            if (clubList != null && !clubList.isEmpty()) {
                System.out.println("clubList size: " + clubList.size());
                for (Club club : clubList) {
                    System.out.println(club);
                }
            }
        }
    }

     

    产生错误:

    clubList size: 3 Club [id=1, clubName=null, clubInfo=null, createDate=null, rank=5] Club [id=2, clubName=null, clubInfo=null, createDate=null, rank=1] Club [id=3, clubName=null, clubInfo=null, createDate=null, rank=7]

     

     

    2. 冲突解决的三种方法:

    1.  mysql语句使用别名
    Xml代码 技术分享 技术分享
    1. <mapper namespace="com.sohu.tv.mapper.clubMapper">  
    2.     <select id="selectAllClubs" resultType="com.sohu.tv.bean.Club">  
    3.         select id,name as clubName,info as clubInfo,create_date as createDate,rank from club  
    4.     </select>  
    5. </mapper>  
    <mapper namespace="com.sohu.tv.mapper.clubMapper">
        <select id="selectAllClubs" resultType="com.sohu.tv.bean.Club">
            select id,name as clubName,info as clubInfo,create_date as createDate,rank from club
        </select>
    </mapper>

      

    2. 使用resultMap做转换
    Xml代码 技术分享 技术分享
    1. <select id="getAllClubs" resultType="Club" resultMap="clubResultMap">  
    2.     select id,name,info,create_date,rank from club  
    3. </select>  
    4.    
    5. <resultMap type="Club" id="clubResultMap">  
    6.     <id property="id" column="id"/>  
    7.     <result property="clubName" column="name"/>  
    8.     <result property="clubInfo" column="info"/>  
    9.     <result property="createDate" column="create_date"/>  
    10.     <result property="rank" column="rank"/>  
    11. </resultMap>  
    <select id="getAllClubs" resultType="Club" resultMap="clubResultMap">
        select id,name,info,create_date,rank from club
    </select>
     
    <resultMap type="Club" id="clubResultMap">
        <id property="id" column="id"/>
        <result property="clubName" column="name"/>
        <result property="clubInfo" column="info"/>
        <result property="createDate" column="create_date"/>
        <result property="rank" column="rank"/>
    </resultMap>

     

    3. 基于约定

    以上两种在生产环境都不建议使用,应该按照一个约定实现(例如数据库字段用_隔开,实体类使用驼峰式)

    Xml代码 技术分享 技术分享
    1. <!--数据库的字段名到pojo类的属性名的自动映射-->  
    2. <settings>  
    3.     <setting name="useColumnLabel" value="true"/>  
    4.     <setting name="mapUnderscoreToCamelCase" value="true"/>  
    5. </settings>  
    <!--数据库的字段名到pojo类的属性名的自动映射-->
    <settings>
        <setting name="useColumnLabel" value="true"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    例如: create_date 对应 createDate

    四、动态sql

    1. sql标签:

     

        作用:省去每个sql语句都写一大串字段

     

    Xml代码 技术分享 技术分享
    1. <sql id="clubColumns">  
    2.         id,name,info,create_date,rank  
    3.     </sql>  
    4.     <select id="getAllClubs" resultType="Club">  
    5.         select <include refid="clubColumns"/> from club  
    6.     </select>  
    <sql id="clubColumns">
            id,name,info,create_date,rank
        </sql>
        <select id="getAllClubs" resultType="Club">
            select <include refid="clubColumns"/> from club
        </select>

     

     

    2. where标签

    作用: sql中的where语句

    (1) ClubDao添加如下方法:

     

     

    Java代码 技术分享 技术分享
    1. /** 
    2.  * 根据名称查询 
    3.  * @param name 
    4.  * @return 
    5.  */  
    6. public Club getByName(String name);  
    /**
     * 根据名称查询
     * @param name
     * @return
     */
    public Club getByName(String name);

     

    (2) clubMapper.xml

     

     

    Xml代码 技术分享 技术分享
    1. <select id="getByName" parameterType="string" resultType="Club">  
    2.     select <include refid="clubColumns"/> from club  
    3.     <where>  
    4.         name = #{name}  
    5.     </where>  
    6. </select>  
    <select id="getByName" parameterType="string" resultType="Club">
        select <include refid="clubColumns"/> from club
        <where>
            name = #{name}
        </where>
    </select>

     

    (3) 单元测试:

     

    Java代码 技术分享 技术分享
    1. @Test  
    2. public void testGetByName() {  
    3.     ClubDao clubDao = sqlSession.getMapper(ClubDao.class);  
    4.     Club club = clubDao.getByName("AC");  
    5.     System.out.println(club);  
    6. }  
    @Test
    public void testGetByName() {
        ClubDao clubDao = sqlSession.getMapper(ClubDao.class);
        Club club = clubDao.getByName("AC");
        System.out.println(club);
    }

     

    3. set(更新字段), choose(判断), where标签综合使用:

       (1)ClubDao添加如下接口

     

     

    Java代码 技术分享 技术分享
    1. import org.apache.ibatis.annotations.Param;  
    2. /** 
    3.  * 更新俱乐部排名 
    4.  * @param id 
    5.  * @param rank 
    6.  */  
    7. public void updateRank(@Param("id") int id, @Param("rank") int rank);  
    import org.apache.ibatis.annotations.Param;
    /**
     * 更新俱乐部排名
     * @param id
     * @param rank
     */
    public void updateRank(@Param("id") int id, @Param("rank") int rank);
    (2) clubMapper.xml添加对应的sql语句

     

    Xml代码 技术分享 技术分享
    1. <update id="updateRank" parameterType="Club">  
    2.     update club  
    3.     <set>  
    4.         <choose>  
    5.             <when test="rank > 0">rank=#{rank}</when>  
    6.             <otherwise>rank=0</otherwise>  
    7.         </choose>  
    8.     </set>  
    9.     <where>  
    10.         id = #{id}  
    11.     </where>  
    12. </update>  
    <update id="updateRank" parameterType="Club">
        update club
        <set>
            <choose>
                <when test="rank > 0">rank=#{rank}</when>
                <otherwise>rank=0</otherwise>
            </choose>
        </set>
        <where>
            id = #{id}
        </where>
    </update>
    (3) 单元测试:

     

    Java代码 技术分享 技术分享
    1. @Test  
    2. public void testUpdateRank() {  
    3.     ClubDao clubDao = sqlSession.getMapper(ClubDao.class);  
    4.     clubDao.updateRank(1, 1000);  
    5. }  
    @Test
    public void testUpdateRank() {
        ClubDao clubDao = sqlSession.getMapper(ClubDao.class);
        clubDao.updateRank(1, 1000);
    }

    4. foreach语句

    示例:

    (1) ClubDao添加如下接口

     

    Java代码 技术分享 技术分享
    1. /** 
    2.  * 根据id列表获取俱乐部信息 
    3.  * @param ids 
    4.  * @return 
    5.  */  
    6. public List<Club> getByIds(@Param("ids") List<Integer> ids);  
    /**
     * 根据id列表获取俱乐部信息
     * @param ids
     * @return
     */
    public List<Club> getByIds(@Param("ids") List<Integer> ids);
    (2) clubMapper.xml添加对应的sql语句

     

    Xml代码 技术分享 技术分享
    1. <select id="getByIds" parameterType="list" resultType="Club">  
    2.     select <include refid="clubColumns"/> from club  
    3.     <where>  
    4.         <foreach collection="ids" item="id" open="AND (" close=")" separator="or">  
    5.             id=#{id}  
    6.         </foreach>  
    7.     </where>  
    8. </select>  
    <select id="getByIds" parameterType="list" resultType="Club">
        select <include refid="clubColumns"/> from club
        <where>
            <foreach collection="ids" item="id" open="AND (" close=")" separator="or">
                id=#{id}
            </foreach>
        </where>
    </select>

     

    (3)单元测试
    Java代码 技术分享 技术分享
    1. @Test  
    2. public void testGetByIds() {  
    3.     ClubDao clubDao = sqlSession.getMapper(ClubDao.class);  
    4.     List<Integer> ids = new ArrayList<Integer>();  
    5.     ids.add(1);  
    6.     ids.add(2);  
    7.        
    8.     printClubList(clubDao.getByIds(ids));  
    9. }  
    10.    
    11.  private void printClubList(List<Club> clubList) {  
    12.     if (clubList != null && !clubList.isEmpty()) {  
    13.         System.out.println("clubList size: " + clubList.size());  
    14.         for (Club club : clubList) {  
    15.             System.out.println(club);  
    16.         }  
    17.     }          
    18. }  
    @Test
    public void testGetByIds() {
        ClubDao clubDao = sqlSession.getMapper(ClubDao.class);
        List<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
         
        printClubList(clubDao.getByIds(ids));
    }
     
     private void printClubList(List<Club> clubList) {
        if (clubList != null && !clubList.isEmpty()) {
            System.out.println("clubList size: " + clubList.size());
            for (Club club : clubList) {
                System.out.println(club);
            }
        }        
    }

    五、properties:

    数据库配置可以单独写到一个配置文件中,例如db.properties

    Xml代码 技术分享 技术分享
    1. football.driver=com.mysql.jdbc.Driver  
    2. football.url=jdbc:mysql://localhost:3306/football  
    3. football.username=root  
    4. football.password=xxxx  
    football.driver=com.mysql.jdbc.Driver
    football.url=jdbc:mysql://localhost:3306/football
    football.username=root
    football.password=xxxx

     

    mybatis全局

    人气教程排行