Mybatis多表联合查询与优化




这篇文章我打算来简单的谈谈 mybatis 的多表联合查询。起初是觉得挺简单的,没必要拿出来写,毕竟 mybatis 这东西现在是个开发的都会用,而且网上的文章也是一搜罗一大堆,根本就用不着我来重复。但是吧,就我前几天在做一个多表联合查询的时候,竟然出了很多意想不到的问题,而且这些问题的出现,并不是对 mybatis 不了解,而是在用的过程中会或多或少的忽略一些东西,导致提示各种错误。


背景


老规矩,开始之前,还是要先说说这件事的背景。也就是最近几天,公司要做一个后台的管理平台,由于之前的一些限制,这次要做成单独的项目进行部署,因此就要重新考虑很多东西。索性这几天有时间,就做了一个小 Demo ,实现 mybatis 的多表联合查询的,由于之前用的是 Hibernate 做的联合查询,众所周知,Hibernate 是全自动的数据库持久层框架,它可以通过实体来映射数据库,通过设置一对多、多对一、一对一、多对多的关联来实现联合查询。


正文


下面就来说一下 mybatis 是通过什么来实现多表联合查询的。首先看一下表关系,如图:



这里,我已经搭好了开发的环境,用到的是 SpringMVC + Spring + MyBatis,当然,为了简单期间,你可以不用搭前端的框架,只使用 Spring + MyBatis 就可以,外加 junit 测试即可。环境我就不带大家搭了,这里只说涉及到联合查询的操作。

设计好表之后,我用到了 mybatis 的自动生成工具 mybatis generator 生成的实体类、mapper 接口、以及 mapper xml 文件。由于是测试多表联合查询,因此需要自己稍加改动。

下面是 User 和 Role 的实体类代码:

User

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.domain;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. public class User implements Serializable {  
  7.     private String id;  
  8.   
  9.     private String username;  
  10.   
  11.     private String password;  
  12.   
  13.     private List<Role> roles;  
  14.   
  15.     private static final long serialVersionUID = 1L;  
  16.   
  17.     public String getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(String id) {  
  22.         this.id = id == null ? null : id.trim();  
  23.     }  
  24.   
  25.     public String getUsername() {  
  26.         return username;  
  27.     }  
  28.   
  29.     public void setUsername(String username) {  
  30.         this.username = username == null ? null : username.trim();  
  31.     }  
  32.   
  33.     public String getPassword() {  
  34.         return password;  
  35.     }  
  36.   
  37.     public void setPassword(String password) {  
  38.         this.password = password == null ? null : password.trim();  
  39.     }  
  40.   
  41.     public List<Role> getRoles() {  
  42.         return roles;  
  43.     }  
  44.   
  45.     public void setRoles(List<Role> roles) {  
  46.         this.roles = roles;  
  47.     }  
  48.   
  49.     @Override  
  50.     public boolean equals(Object that) {  
  51.         if (this == that) {  
  52.             return true;  
  53.         }  
  54.         if (that == null) {  
  55.             return false;  
  56.         }  
  57.         if (getClass() != that.getClass()) {  
  58.             return false;  
  59.         }  
  60.         User other = (User) that;  
  61.         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))  
  62.             && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))  
  63.             && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));  
  64.     }  
  65.   
  66.     @Override  
  67.     public int hashCode() {  
  68.         final int prime = 31;  
  69.         int result = 1;  
  70.         result = prime  result + ((getId() == null) ? 0 : getId().hashCode());  
  71.         result = prime  result + ((getUsername() == null) ? 0 : getUsername().hashCode());  
  72.         result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());  
  73.         return result;  
  74.     }  
  75. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.domain;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. public class User implements Serializable {
  5. private String id;
  6. private String username;
  7. private String password;
  8. private List<Role> roles;
  9. private static final long serialVersionUID = 1L;
  10. public String getId() {
  11. return id;
  12. }
  13. public void setId(String id) {
  14. this.id = id == null ? null : id.trim();
  15. }
  16. public String getUsername() {
  17. return username;
  18. }
  19. public void setUsername(String username) {
  20. this.username = username == null ? null : username.trim();
  21. }
  22. public String getPassword() {
  23. return password;
  24. }
  25. public void setPassword(String password) {
  26. this.password = password == null ? null : password.trim();
  27. }
  28. public List<Role> getRoles() {
  29. return roles;
  30. }
  31. public void setRoles(List<Role> roles) {
  32. this.roles = roles;
  33. }
  34. @Override
  35. public boolean equals(Object that) {
  36. if ( this == that) {
  37. return true;
  38. }
  39. if (that == null) {
  40. return false;
  41. }
  42. if (getClass() != that.getClass()) {
  43. return false;
  44. }
  45. User other = (User) that;
  46. return ( this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  47. && ( this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
  48. && ( this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));
  49. }
  50. @Override
  51. public int hashCode() {
  52. final int prime = 31;
  53. int result = 1;
  54. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  55. result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
  56. result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
  57. return result;
  58. }
  59. }</span>

Role
[java] view plain copy

print?



  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.domain;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Role implements Serializable {  
  6.     private String id;  
  7.   
  8.     private String name;  
  9.   
  10.     private String jsms;  
  11.   
  12.     private String bz;  
  13.   
  14.     private Integer jlzt;  
  15.   
  16.     private String glbm;  
  17.   
  18.     private String userid;  
  19.   
  20.     private static final long serialVersionUID = 1L;  
  21.   
  22.     public String getId() {  
  23.         return id;  
  24.     }  
  25.   
  26.     public void setId(String id) {  
  27.         this.id = id == null ? null : id.trim();  
  28.     }  
  29.   
  30.     public String getName() {  
  31.         return name;  
  32.     }  
  33.   
  34.     public void setName(String name) {  
  35.         this.name = name == null ? null : name.trim();  
  36.     }  
  37.   
  38.     public String getJsms() {  
  39.         return jsms;  
  40.     }  
  41.   
  42.     public void setJsms(String jsms) {  
  43.         this.jsms = jsms == null ? null : jsms.trim();  
  44.     }  
  45.   
  46.     public String getBz() {  
  47.         return bz;  
  48.     }  
  49.   
  50.     public void setBz(String bz) {  
  51.         this.bz = bz == null ? null : bz.trim();  
  52.     }  
  53.   
  54.     public Integer getJlzt() {  
  55.         return jlzt;  
  56.     }  
  57.   
  58.     public void setJlzt(Integer jlzt) {  
  59.         this.jlzt = jlzt;  
  60.     }  
  61.   
  62.     public String getGlbm() {  
  63.         return glbm;  
  64.     }  
  65.   
  66.     public void setGlbm(String glbm) {  
  67.         this.glbm = glbm == null ? null : glbm.trim();  
  68.     }  
  69.   
  70.     public String getUserid() {  
  71.         return userid;  
  72.     }  
  73.   
  74.     public void setUserid(String userid) {  
  75.         this.userid = userid == null ? null : userid.trim();  
  76.     }  
  77.   
  78.     @Override  
  79.     public boolean equals(Object that) {  
  80.         if (this == that) {  
  81.             return true;  
  82.         }  
  83.         if (that == null) {  
  84.             return false;  
  85.         }  
  86.         if (getClass() != that.getClass()) {  
  87.             return false;  
  88.         }  
  89.         Role other = (Role) that;  
  90.         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))  
  91.             && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))  
  92.             && (this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))  
  93.             && (this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))  
  94.             && (this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))  
  95.             && (this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))  
  96.             && (this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));  
  97.     }  
  98.   
  99.     @Override  
  100.     public int hashCode() {  
  101.         final int prime = 31;  
  102.         int result = 1;  
  103.         result = prime  result + ((getId() == null) ? 0 : getId().hashCode());  
  104.         result = prime  result + ((getName() == null) ? 0 : getName().hashCode());  
  105.         result = prime  result + ((getJsms() == null) ? 0 : getJsms().hashCode());  
  106.         result = prime  result + ((getBz() == null) ? 0 : getBz().hashCode());  
  107.         result = prime  result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());  
  108.         result = prime  result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());  
  109.         result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());  
  110.         return result;  
  111.     }  
  112. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.domain;
  2. import java.io.Serializable;
  3. public class Role implements Serializable {
  4. private String id;
  5. private String name;
  6. private String jsms;
  7. private String bz;
  8. private Integer jlzt;
  9. private String glbm;
  10. private String userid;
  11. private static final long serialVersionUID = 1L;
  12. public String getId() {
  13. return id;
  14. }
  15. public void setId(String id) {
  16. this.id = id == null ? null : id.trim();
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name == null ? null : name.trim();
  23. }
  24. public String getJsms() {
  25. return jsms;
  26. }
  27. public void setJsms(String jsms) {
  28. this.jsms = jsms == null ? null : jsms.trim();
  29. }
  30. public String getBz() {
  31. return bz;
  32. }
  33. public void setBz(String bz) {
  34. this.bz = bz == null ? null : bz.trim();
  35. }
  36. public Integer getJlzt() {
  37. return jlzt;
  38. }
  39. public void setJlzt(Integer jlzt) {
  40. this.jlzt = jlzt;
  41. }
  42. public String getGlbm() {
  43. return glbm;
  44. }
  45. public void setGlbm(String glbm) {
  46. this.glbm = glbm == null ? null : glbm.trim();
  47. }
  48. public String getUserid() {
  49. return userid;
  50. }
  51. public void setUserid(String userid) {
  52. this.userid = userid == null ? null : userid.trim();
  53. }
  54. @Override
  55. public boolean equals(Object that) {
  56. if ( this == that) {
  57. return true;
  58. }
  59. if (that == null) {
  60. return false;
  61. }
  62. if (getClass() != that.getClass()) {
  63. return false;
  64. }
  65. Role other = (Role) that;
  66. return ( this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  67. && ( this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
  68. && ( this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))
  69. && ( this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))
  70. && ( this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))
  71. && ( this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))
  72. && ( this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));
  73. }
  74. @Override
  75. public int hashCode() {
  76. final int prime = 31;
  77. int result = 1;
  78. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  79. result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
  80. result = prime * result + ((getJsms() == null) ? 0 : getJsms().hashCode());
  81. result = prime * result + ((getBz() == null) ? 0 : getBz().hashCode());
  82. result = prime * result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());
  83. result = prime * result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());
  84. result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());
  85. return result;
  86. }
  87. }</span>

首先讲一下业务,这里用到的 User 、Role 的对应关系是,一个用户有多个角色,也就是 User : Role 是 1 : n 的关系。因此,在 User 的实体中加入一个 Role 的属性,对应一对多的关系。

然后就是 mapper 接口和 xml 文件了:

mapper接口

UserMapper

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.mapper;  
  2.   
  3. import com.sica.domain.User;  
  4.   
  5. import java.util.List;  
  6.   
  7. public interface UserMapper {  
  8.     int deleteByPrimaryKey(String id);  
  9.   
  10.     int insert(User record);  
  11.   
  12.     int insertSelective(User record);  
  13.   
  14.     User selectByPrimaryKey(String id);  
  15.   
  16.     int updateByPrimaryKeySelective(User record);  
  17.   
  18.     int updateByPrimaryKey(User record);  
  19.   
  20.     List<User> queryForList();  
  21. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.mapper;
  2. import com.sica.domain.User;
  3. import java.util.List;
  4. public interface UserMapper {
  5. int deleteByPrimaryKey(String id);
  6. int insert(User record);
  7. int insertSelective(User record);
  8. User selectByPrimaryKey(String id);
  9. int updateByPrimaryKeySelective(User record);
  10. int updateByPrimaryKey(User record);
  11. List<User> queryForList();
  12. }</span>

mapper xml文件

UserMapper

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”><?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.sica.mapper.UserMapper”>  
  4.     <resultMap id=“BaseResultMap” type=“com.sica.domain.User”>  
  5.         <id column=“id” property=“id” jdbcType=“VARCHAR”/>  
  6.         <result column=“username” property=“username” jdbcType=“VARCHAR”/>  
  7.         <result column=“password” property=“password” jdbcType=“VARCHAR”/>  
  8.     </resultMap>  
  9.   
  10.     <resultMap id=“queryForListMap” type=“com.sica.domain.User”>  
  11.         <id column=“id” property=“id” jdbcType=“VARCHAR”/>  
  12.         <result column=“username” property=“username” jdbcType=“VARCHAR”/>  
  13.         <result column=“password” property=“password” jdbcType=“VARCHAR”/>  
  14.         <collection property=“roles” javaType=“java.util.List” ofType=“com.sica.domain.Role”>  
  15.             <id column=“r_id” property=“id” jdbcType=“VARCHAR” />  
  16.             <result column=“r_name” property=“name” jdbcType=“VARCHAR” />  
  17.             <result column=“r_jsms” property=“jsms” jdbcType=“VARCHAR” />  
  18.             <result column=“r_bz” property=“bz” jdbcType=“VARCHAR” />  
  19.             <result column=“r_jlzt” property=“jlzt” jdbcType=“INTEGER” />  
  20.             <result column=“r_glbm” property=“glbm” jdbcType=“VARCHAR” />  
  21.         </collection>  
  22.     </resultMap>  
  23.     <select id=“queryForList” resultMap=“queryForListMap”>  
  24.         SELECT  
  25.           u.id,  
  26.           u.username,  
  27.           u.password,  
  28.           r.id r_id,  
  29.           r.name r_name,  
  30.           r.jsms r_jsms,  
  31.           r.bz r_bz,  
  32.           r.jlzt r_jlzt,  
  33.           r.glbm r_glbm  
  34.         FROM  
  35.           user u  
  36.         LEFT JOIN  
  37.           role r  
  38.         ON  
  39.           u.id = r.userid  
  40.     </select>  
  41.     <sql id=“Base_Column_List”>  
  42.       id, username, password  
  43.     </sql>  
  44.     <select id=“selectByPrimaryKey” resultMap=“BaseResultMap” parameterType=“java.lang.String”>  
  45.         select  
  46.         <include refid=“Base_Column_List”/>  
  47.         from user  
  48.         where id = #{id,jdbcType=VARCHAR}  
  49.     </select>  
  50.     <delete id=“deleteByPrimaryKey” parameterType=“java.lang.String”>  
  51.     delete from user  
  52.     where id = #{id,jdbcType=VARCHAR}  
  53.     </delete>  
  54.     <insert id=“insert” parameterType=“com.sica.domain.User”>  
  55.     insert into user (id, username, password  
  56.       )  
  57.     values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}  
  58.       )  
  59.     </insert>  
  60.     <insert id=“insertSelective” parameterType=“com.sica.domain.User”>  
  61.         insert into user  
  62.         <trim prefix=“(“ suffix=“)” suffixOverrides=“,”>  
  63.             <if test=“id != null”>  
  64.                 id,  
  65.             </if>  
  66.             <if test=“username != null”>  
  67.                 username,  
  68.             </if>  
  69.             <if test=“password != null”>  
  70.                 password,  
  71.             </if>  
  72.         </trim>  
  73.         <trim prefix=“values (“ suffix=“)” suffixOverrides=“,”>  
  74.             <if test=“id != null”>  
  75.                 #{id,jdbcType=VARCHAR},  
  76.             </if>  
  77.             <if test=“username != null”>  
  78.                 #{username,jdbcType=VARCHAR},  
  79.             </if>  
  80.             <if test=“password != null”>  
  81.                 #{password,jdbcType=VARCHAR},  
  82.             </if>  
  83.         </trim>  
  84.     </insert>  
  85.     <update id=“updateByPrimaryKeySelective” parameterType=“com.sica.domain.User”>  
  86.         update user  
  87.         <set>  
  88.             <if test=“username != null”>  
  89.                 username = #{username,jdbcType=VARCHAR},  
  90.             </if>  
  91.             <if test=“password != null”>  
  92.                 password = #{password,jdbcType=VARCHAR},  
  93.             </if>  
  94.         </set>  
  95.         where id = #{id,jdbcType=VARCHAR}  
  96.     </update>  
  97.     <update id=“updateByPrimaryKey” parameterType=“com.sica.domain.User”>  
  98.     update user  
  99.     set username = #{username,jdbcType=VARCHAR},  
  100.       password = #{password,jdbcType=VARCHAR}  
  101.     where id = #{id,jdbcType=VARCHAR}  
  102.   </update>  
  103. </mapper></span>  


         
         
  1. <span style="font-family:Comic Sans MS;font-size:12px;"> <?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.sica.mapper.UserMapper">
  4. <resultMap id="BaseResultMap" type="com.sica.domain.User">
  5. <id column="id" property="id" jdbcType="VARCHAR"/>
  6. <result column="username" property="username" jdbcType="VARCHAR"/>
  7. <result column="password" property="password" jdbcType="VARCHAR"/>
  8. </resultMap>
  9. <resultMap id="queryForListMap" type="com.sica.domain.User">
  10. <id column="id" property="id" jdbcType="VARCHAR"/>
  11. <result column="username" property="username" jdbcType="VARCHAR"/>
  12. <result column="password" property="password" jdbcType="VARCHAR"/>
  13. <collection property="roles" javaType="java.util.List" ofType="com.sica.domain.Role">
  14. <id column="r_id" property="id" jdbcType="VARCHAR" />
  15. <result column="r_name" property="name" jdbcType="VARCHAR" />
  16. <result column="r_jsms" property="jsms" jdbcType="VARCHAR" />
  17. <result column="r_bz" property="bz" jdbcType="VARCHAR" />
  18. <result column="r_jlzt" property="jlzt" jdbcType="INTEGER" />
  19. <result column="r_glbm" property="glbm" jdbcType="VARCHAR" />
  20. </collection>
  21. </resultMap>
  22. <select id="queryForList" resultMap="queryForListMap">
  23. SELECT
  24. u.id,
  25. u.username,
  26. u.password,
  27. r.id r_id,
  28. r.name r_name,
  29. r.jsms r_jsms,
  30. r.bz r_bz,
  31. r.jlzt r_jlzt,
  32. r.glbm r_glbm
  33. FROM
  34. user u
  35. LEFT JOIN
  36. role r
  37. ON
  38. u.id = r.userid
  39. </select>
  40. <sql id="Base_Column_List">
  41. id, username, password
  42. </sql>
  43. <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String">
  44. select
  45. <include refid="Base_Column_List"/>
  46. from user
  47. where id = #{id,jdbcType=VARCHAR}
  48. </select>
  49. <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
  50. delete from user
  51. where id = #{id,jdbcType=VARCHAR}
  52. </delete>
  53. <insert id="insert" parameterType="com.sica.domain.User">
  54. insert into user (id, username, password
  55. )
  56. values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
  57. )
  58. </insert>
  59. <insert id="insertSelective" parameterType="com.sica.domain.User">
  60. insert into user
  61. <trim prefix="(" suffix=")" suffixOverrides=",">
  62. <if test="id != null">
  63. id,
  64. </if>
  65. <if test="username != null">
  66. username,
  67. </if>
  68. <if test="password != null">
  69. password,
  70. </if>
  71. </trim>
  72. <trim prefix="values (" suffix=")" suffixOverrides=",">
  73. <if test="id != null">
  74. #{id,jdbcType=VARCHAR},
  75. </if>
  76. <if test="username != null">
  77. #{username,jdbcType=VARCHAR},
  78. </if>
  79. <if test="password != null">
  80. #{password,jdbcType=VARCHAR},
  81. </if>
  82. </trim>
  83. </insert>
  84. <update id="updateByPrimaryKeySelective" parameterType="com.sica.domain.User">
  85. update user
  86. <set>
  87. <if test="username != null">
  88. username = #{username,jdbcType=VARCHAR},
  89. </if>
  90. <if test="password != null">
  91. password = #{password,jdbcType=VARCHAR},
  92. </if>
  93. </set>
  94. where id = #{id,jdbcType=VARCHAR}
  95. </update>
  96. <update id="updateByPrimaryKey" parameterType="com.sica.domain.User">
  97. update user
  98. set username = #{username,jdbcType=VARCHAR},
  99. password = #{password,jdbcType=VARCHAR}
  100. where id = #{id,jdbcType=VARCHAR}
  101. </update>
  102. </mapper> </span>

之后,我扩展了一个 Dao 接口,当然,你也可以直接使用 mapper 接口,都是一样的。

Dao 接口

IUserDao

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.dao;  
  2.   
  3. import com.sica.mapper.UserMapper;  
  4.   
  5. /* 
  6.   Created by IntelliJ IDEA. 
  7.   Package: com.sica.dao 
  8.   Name: IUserDao 
  9.   User: xiang.li 
  10.   Date: 2015/5/22 
  11.   Time: 15:25 
  12.   Desc: To change this template use File | Settings | File Templates. 
  13.  */  
  14. public interface IUserDao extends UserMapper {  
  15.   
  16. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.dao;
  2. import com.sica.mapper.UserMapper;
  3. /*
  4. Created by IntelliJ IDEA.
  5. * Package: com.sica.dao
  6. * Name: IUserDao
  7. * User: xiang.li
  8. * Date: 2015/5/22
  9. * Time: 15:25
  10. * Desc: To change this template use File | Settings | File Templates.
  11. */
  12. public interface IUserDao extends UserMapper {
  13. }</span>

下面就是 service 和实现层的代码了。

IUserService

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.service;  
  2.   
  3. import com.sica.domain.User;  
  4.   
  5. import java.util.List;  
  6.   
  7. / 
  8.   Created by xiang.li on 2015/1/31. 
  9.  /  
  10. public interface IUserService {  
  11.   
  12.     / 
  13.       根据Id查询用户对象 
  14.       @param id 编号 
  15.       @return 用户对象 
  16.      /  
  17.     User getUserById(String id);  
  18.   
  19.     /* 
  20.       根据用户名查询用户对象 
  21.       @return  List 
  22.      /  
  23.     List<User> queryUserList();  
  24. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.service;
  2. import com.sica.domain.User;
  3. import java.util.List;
  4. /
  5. * Created by xiang.li on 2015/1/31.
  6. /
  7. public interface IUserService {
  8. /
  9. 根据Id查询用户对象
  10. * @param id 编号
  11. * @return 用户对象
  12. /
  13. User getUserById(String id);
  14. /*
  15. * 根据用户名查询用户对象
  16. * @return List
  17. */
  18. List<User> queryUserList();
  19. }</span>

UserServiceImpl

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.service.impl;  
  2.   
  3. import com.sica.dao.IUserDao;  
  4. import com.sica.domain.User;  
  5. import com.sica.service.IUserService;  
  6. import org.springframework.stereotype.Service;  
  7.   
  8. import javax.annotation.Resource;  
  9. import java.util.List;  
  10.   
  11. /* 
  12.   Created by xiang.li on 2015/1/31. 
  13.  */  
  14. @Service(“userService”)  
  15. public class UserServiceImpl implements IUserService {  
  16.   
  17.     @Resource  
  18.     public IUserDao userDao;  
  19.   
  20.     @Override  
  21.     public User getUserById(String id) {  
  22.         return this.userDao.selectByPrimaryKey(id);  
  23.     }  
  24.   
  25.     @Override  
  26.     public List<User> queryUserList() {  
  27.         return userDao.queryForList();  
  28.     }  
  29.   
  30. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.service.impl;
  2. import com.sica.dao.IUserDao;
  3. import com.sica.domain.User;
  4. import com.sica.service.IUserService;
  5. import org.springframework.stereotype.Service;
  6. import javax.annotation.Resource;
  7. import java.util.List;
  8. /*
  9. Created by xiang.li on 2015/1/31.
  10. */
  11. @Service( "userService")
  12. public class UserServiceImpl implements IUserService {
  13. @Resource
  14. public IUserDao userDao;
  15. @Override
  16. public User getUserById(String id) {
  17. return this.userDao.selectByPrimaryKey(id);
  18. }
  19. @Override
  20. public List<User> queryUserList() {
  21. return userDao.queryForList();
  22. }
  23. }</span>

当然,还有所谓的 applicationContext.xml 配置,不过,我这里叫 spring-mybatis.xml。


  1. <span style=“font-family:Comic Sans MS;font-size:12px;”><?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=http://www.springframework.org/schema/beans  
  3.        xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance  
  4.        xmlns:p=http://www.springframework.org/schema/p  
  5.        xmlns:context=http://www.springframework.org/schema/context  
  6.        xmlns:mvc=http://www.springframework.org/schema/mvc  
  7.        xsi:schemaLocation=”http://www.springframework.org/schema/beans  
  8.        http://www.springframework.org/schema/beans/spring-beans.xsd &nbsp;
  9.         http://www.springframework.org/schema/context &nbsp;
  10.         http://www.springframework.org/schema/context/spring-context.xsd &nbsp;
  11.         http://www.springframework.org/schema/mvc &nbsp;
  12.         http://www.springframework.org/schema/mvc/spring-mvc.xsd>  
  13.   
  14.     <!– 自动扫描 –>  
  15.     <context:component-scan base-package=“com.sica”/>  
  16.     <!– 引入配置文件 –>  
  17.     <bean id=“propertyConfigurer” class=“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”  
  18.           p:location=“classpath:jdbc.properties”  
  19.           />  
  20.   
  21.     <!– 配置数据库连接池 –>  
  22.     <!– 初始化连接大小 –>  
  23.     <!– 连接池最大数量 –>  
  24.     <!– 连接池最大空闲 –>  
  25.     <!– 连接池最小空闲 –>  
  26.     <!– 获取连接最大等待时间 –>  
  27.     <bean id=“dataSource” class=“org.apache.commons.dbcp.BasicDataSource” destroy-method=“close”  
  28.           p:driverClassName= {jdbc.driver}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:url</span><span>=</span><span class="attribute-value">" {jdbc.url}”  
  29.           p:username= {jdbc.username}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:password</span><span>=</span><span class="attribute-value">" {jdbc.password}”  
  30.           p:initialSize= {jdbc.initialSize}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:maxActive</span><span>=</span><span class="attribute-value">" {jdbc.maxActive}”  
  31.           p:maxIdle= {jdbc.maxIdle}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:minIdle</span><span>=</span><span class="attribute-value">" {jdbc.minIdle}”  
  32.           p:maxWait=“${jdbc.maxWait}”  
  33.           />  
  34.   
  35.     <!– spring和MyBatis完美整合,不需要mybatis的配置映射文件 –>  
  36.     <bean id=“sqlSessionFactory” class=“org.mybatis.spring.SqlSessionFactoryBean” lazy-init=“default”  
  37.           p:dataSource-ref=“dataSource”  
  38.           p:mapperLocations=“classpath:com/sica/mapping/*.xml”  
  39.           />  
  40.   
  41.     <!– DAO接口所在包名,Spring会自动查找其下的类 –>  
  42.     <bean class=“org.mybatis.spring.mapper.MapperScannerConfigurer”  
  43.           p:basePackage=“com.sica.dao”  
  44.           p:sqlSessionFactoryBeanName=“sqlSessionFactory”  
  45.           />  
  46.   
  47.     <!– (事务管理)transaction manager, use JtaTransactionManager for global tx –>  
  48.     <bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”  
  49.           p:dataSource-ref=“dataSource”  
  50.           />  
  51. </beans></span>  


         
         
  1. <span style="font-family:Comic Sans MS;font-size:12px;"> <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- 自动扫描 -->
  3. <context:component-scan base-package="com.sica"/>
  4. <!-- 引入配置文件 -->
  5. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  6. p:location= "classpath:jdbc.properties"
  7. />
  8. <!-- 配置数据库连接池 -->
  9. <!-- 初始化连接大小 -->
  10. <!-- 连接池最大数量 -->
  11. <!-- 连接池最大空闲 -->
  12. <!-- 连接池最小空闲 -->
  13. <!-- 获取连接最大等待时间 -->
  14. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
  15. p:driverClassName= "${jdbc.driver}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:url</span>=<span class="hljs-string">"${jdbc.url}"
  16. p:username= "${jdbc.username}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="31"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:password</span>=<span class="hljs-string">"${jdbc.password}"
  17. p:initialSize= "${jdbc.initialSize}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:maxActive</span>=<span class="hljs-string">"${jdbc.maxActive}"
  18. p:maxIdle= "${jdbc.maxIdle}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:minIdle</span>=<span class="hljs-string">"${jdbc.minIdle}"
  19. p:maxWait= "${jdbc.maxWait}"
  20. />
  21. <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
  22. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" lazy-init="default"
  23. p:dataSource-ref= "dataSource"
  24. p:mapperLocations= "classpath:com/sica/mapping/*.xml"
  25. />
  26. <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  27. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
  28. p:basePackage= "com.sica.dao"
  29. p:sqlSessionFactoryBeanName= "sqlSessionFactory"
  30. />
  31. <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
  32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  33. p:dataSource-ref= "dataSource"
  34. />
  35. </beans> </span>

最后,我用到的是 junit 进行的测试,测试代码如下。

GetUserTest

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.user;  
  2.   
  3. import com.alibaba.fastjson.JSON;  
  4. import com.sica.domain.User;  
  5. import com.sica.service.IUserService;  
  6. import org.junit.Test;  
  7. import org.junit.runner.RunWith;  
  8. import org.slf4j.Logger;  
  9. import org.slf4j.LoggerFactory;  
  10. import org.springframework.test.context.ContextConfiguration;  
  11. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  12.   
  13. import javax.annotation.Resource;  
  14. import java.util.List;  
  15.   
  16. / 
  17.   Created by xiang.li on 2015/2/1. 
  18.  /  
  19. @RunWith(SpringJUnit4ClassRunner.class)  
  20. @ContextConfiguration(locations = “classpath:spring-mybatis.xml”)  
  21. public class GetUserTest {  
  22.   
  23.     private static String UUID = “3”;  
  24.     @Resource  
  25.     private IUserService userService;  
  26.     private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);  
  27.   
  28.     @Test  
  29.     public void test() {  
  30.         User user = userService.getUserById(UUID);  
  31.         logger.info(JSON.toJSONString(user));  
  32.     }  
  33.   
  34.     / 
  35.       测试联合查询 
  36.      /  
  37.     @Test  
  38.     public void test2() {  
  39.         List<User> users = userService.queryUserList();  
  40.         logger.info(JSON.toJSONString(users));  
  41.     }  
  42. }</span>  


         
         
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.user;
  2. import com.alibaba.fastjson.JSON;
  3. import com.sica.domain.User;
  4. import com.sica.service.IUserService;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.test.context.ContextConfiguration;
  10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  11. import javax.annotation.Resource;
  12. import java.util.List;
  13. /
  14. * Created by xiang.li on 2015/2/1.
  15. /
  16. @RunWith(SpringJUnit4ClassRunner.class)
  17. @ContextConfiguration(locations = "classpath:spring-mybatis.xml")
  18. public class GetUserTest {
  19. private static String UUID = "3";
  20. @Resource
  21. private IUserService userService;
  22. private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);
  23. @Test
  24. public void test() {
  25. User user = userService.getUserById(UUID);
  26. logger.info(JSON.toJSONString(user));
  27. }
  28. /
  29. 测试联合查询
  30. */
  31. @Test
  32. public void test2() {
  33. List<User> users = userService.queryUserList();
  34. logger.info(JSON.toJSONString(users));
  35. }
  36. }</span>


测试结果




可以看到,所有的用户和用户对应的角色都全部查出来了,这说明,这次的测试很成功。


关于优化


对于优化嘛,我这里简单的提几点,大家可以考虑一下。首先,就是对表的设计,在设计表初期,不仅仅要考虑到数据库的规范性,还好考虑到所谓的业务,以及对性能的影响,比如,如果从规范性角度考虑的话,可能就会分多个表,但是如果从性能角度来考虑的话,庞大的数据量在多表联合查询的时候,相对于单表来说,就会慢很多,这时,如果字段不是很多的话,可以考虑冗余几个字段采用单表的设计。

其次嘛,就是在 sql 上下功夫了,对于联合查询,sql 的优化是很有必要的,到底是采用 INNER JOIN,还是采用 LEFT JOIN 亦或是 RIGHT JOIN 、OUTTER JOIN 等,都是要在满足业务需求之后,通过测试性能得出的结论。

再次嘛,就是在程序中调用的时候了,是采用懒加载,还是采用非懒加载的方式,这也算是一个因素吧,具体的还是要考虑业务的需要。

最后嘛,就要用到数据库的缓存了,或者在数据库与程序的中间再加一层缓存。不过,还是建议用好数据库本身自带的缓存功能。


结束语


最后的最后,还是要提醒大家,不要因为觉得简单就引不起足够的重视,否则你会由于一点点小的失误,而浪费大把大把的时间的。我就在这上边体会过,所以,这里奉劝大家,还是小心为妙啊@!








这篇文章我打算来简单的谈谈 mybatis 的多表联合查询。起初是觉得挺简单的,没必要拿出来写,毕竟 mybatis 这东西现在是个开发的都会用,而且网上的文章也是一搜罗一大堆,根本就用不着我来重复。但是吧,就我前几天在做一个多表联合查询的时候,竟然出了很多意想不到的问题,而且这些问题的出现,并不是对 mybatis 不了解,而是在用的过程中会或多或少的忽略一些东西,导致提示各种错误。


背景


老规矩,开始之前,还是要先说说这件事的背景。也就是最近几天,公司要做一个后台的管理平台,由于之前的一些限制,这次要做成单独的项目进行部署,因此就要重新考虑很多东西。索性这几天有时间,就做了一个小 Demo ,实现 mybatis 的多表联合查询的,由于之前用的是 Hibernate 做的联合查询,众所周知,Hibernate 是全自动的数据库持久层框架,它可以通过实体来映射数据库,通过设置一对多、多对一、一对一、多对多的关联来实现联合查询。


正文


下面就来说一下 mybatis 是通过什么来实现多表联合查询的。首先看一下表关系,如图:



这里,我已经搭好了开发的环境,用到的是 SpringMVC + Spring + MyBatis,当然,为了简单期间,你可以不用搭前端的框架,只使用 Spring + MyBatis 就可以,外加 junit 测试即可。环境我就不带大家搭了,这里只说涉及到联合查询的操作。

设计好表之后,我用到了 mybatis 的自动生成工具 mybatis generator 生成的实体类、mapper 接口、以及 mapper xml 文件。由于是测试多表联合查询,因此需要自己稍加改动。

下面是 User 和 Role 的实体类代码:

User

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.domain;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. public class User implements Serializable {  
  7.     private String id;  
  8.   
  9.     private String username;  
  10.   
  11.     private String password;  
  12.   
  13.     private List<Role> roles;  
  14.   
  15.     private static final long serialVersionUID = 1L;  
  16.   
  17.     public String getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(String id) {  
  22.         this.id = id == null ? null : id.trim();  
  23.     }  
  24.   
  25.     public String getUsername() {  
  26.         return username;  
  27.     }  
  28.   
  29.     public void setUsername(String username) {  
  30.         this.username = username == null ? null : username.trim();  
  31.     }  
  32.   
  33.     public String getPassword() {  
  34.         return password;  
  35.     }  
  36.   
  37.     public void setPassword(String password) {  
  38.         this.password = password == null ? null : password.trim();  
  39.     }  
  40.   
  41.     public List<Role> getRoles() {  
  42.         return roles;  
  43.     }  
  44.   
  45.     public void setRoles(List<Role> roles) {  
  46.         this.roles = roles;  
  47.     }  
  48.   
  49.     @Override  
  50.     public boolean equals(Object that) {  
  51.         if (this == that) {  
  52.             return true;  
  53.         }  
  54.         if (that == null) {  
  55.             return false;  
  56.         }  
  57.         if (getClass() != that.getClass()) {  
  58.             return false;  
  59.         }  
  60.         User other = (User) that;  
  61.         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))  
  62.             && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))  
  63.             && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));  
  64.     }  
  65.   
  66.     @Override  
  67.     public int hashCode() {  
  68.         final int prime = 31;  
  69.         int result = 1;  
  70.         result = prime  result + ((getId() == null) ? 0 : getId().hashCode());  
  71.         result = prime  result + ((getUsername() == null) ? 0 : getUsername().hashCode());  
  72.         result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());  
  73.         return result;  
  74.     }  
  75. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.domain;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. public class User implements Serializable {
  5. private String id;
  6. private String username;
  7. private String password;
  8. private List<Role> roles;
  9. private static final long serialVersionUID = 1L;
  10. public String getId() {
  11. return id;
  12. }
  13. public void setId(String id) {
  14. this.id = id == null ? null : id.trim();
  15. }
  16. public String getUsername() {
  17. return username;
  18. }
  19. public void setUsername(String username) {
  20. this.username = username == null ? null : username.trim();
  21. }
  22. public String getPassword() {
  23. return password;
  24. }
  25. public void setPassword(String password) {
  26. this.password = password == null ? null : password.trim();
  27. }
  28. public List<Role> getRoles() {
  29. return roles;
  30. }
  31. public void setRoles(List<Role> roles) {
  32. this.roles = roles;
  33. }
  34. @Override
  35. public boolean equals(Object that) {
  36. if ( this == that) {
  37. return true;
  38. }
  39. if (that == null) {
  40. return false;
  41. }
  42. if (getClass() != that.getClass()) {
  43. return false;
  44. }
  45. User other = (User) that;
  46. return ( this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  47. && ( this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
  48. && ( this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));
  49. }
  50. @Override
  51. public int hashCode() {
  52. final int prime = 31;
  53. int result = 1;
  54. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  55. result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
  56. result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
  57. return result;
  58. }
  59. }</span>

Role

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.domain;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Role implements Serializable {  
  6.     private String id;  
  7.   
  8.     private String name;  
  9.   
  10.     private String jsms;  
  11.   
  12.     private String bz;  
  13.   
  14.     private Integer jlzt;  
  15.   
  16.     private String glbm;  
  17.   
  18.     private String userid;  
  19.   
  20.     private static final long serialVersionUID = 1L;  
  21.   
  22.     public String getId() {  
  23.         return id;  
  24.     }  
  25.   
  26.     public void setId(String id) {  
  27.         this.id = id == null ? null : id.trim();  
  28.     }  
  29.   
  30.     public String getName() {  
  31.         return name;  
  32.     }  
  33.   
  34.     public void setName(String name) {  
  35.         this.name = name == null ? null : name.trim();  
  36.     }  
  37.   
  38.     public String getJsms() {  
  39.         return jsms;  
  40.     }  
  41.   
  42.     public void setJsms(String jsms) {  
  43.         this.jsms = jsms == null ? null : jsms.trim();  
  44.     }  
  45.   
  46.     public String getBz() {  
  47.         return bz;  
  48.     }  
  49.   
  50.     public void setBz(String bz) {  
  51.         this.bz = bz == null ? null : bz.trim();  
  52.     }  
  53.   
  54.     public Integer getJlzt() {  
  55.         return jlzt;  
  56.     }  
  57.   
  58.     public void setJlzt(Integer jlzt) {  
  59.         this.jlzt = jlzt;  
  60.     }  
  61.   
  62.     public String getGlbm() {  
  63.         return glbm;  
  64.     }  
  65.   
  66.     public void setGlbm(String glbm) {  
  67.         this.glbm = glbm == null ? null : glbm.trim();  
  68.     }  
  69.   
  70.     public String getUserid() {  
  71.         return userid;  
  72.     }  
  73.   
  74.     public void setUserid(String userid) {  
  75.         this.userid = userid == null ? null : userid.trim();  
  76.     }  
  77.   
  78.     @Override  
  79.     public boolean equals(Object that) {  
  80.         if (this == that) {  
  81.             return true;  
  82.         }  
  83.         if (that == null) {  
  84.             return false;  
  85.         }  
  86.         if (getClass() != that.getClass()) {  
  87.             return false;  
  88.         }  
  89.         Role other = (Role) that;  
  90.         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))  
  91.             && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))  
  92.             && (this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))  
  93.             && (this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))  
  94.             && (this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))  
  95.             && (this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))  
  96.             && (this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));  
  97.     }  
  98.   
  99.     @Override  
  100.     public int hashCode() {  
  101.         final int prime = 31;  
  102.         int result = 1;  
  103.         result = prime  result + ((getId() == null) ? 0 : getId().hashCode());  
  104.         result = prime  result + ((getName() == null) ? 0 : getName().hashCode());  
  105.         result = prime  result + ((getJsms() == null) ? 0 : getJsms().hashCode());  
  106.         result = prime  result + ((getBz() == null) ? 0 : getBz().hashCode());  
  107.         result = prime  result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());  
  108.         result = prime  result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());  
  109.         result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());  
  110.         return result;  
  111.     }  
  112. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.domain;
  2. import java.io.Serializable;
  3. public class Role implements Serializable {
  4. private String id;
  5. private String name;
  6. private String jsms;
  7. private String bz;
  8. private Integer jlzt;
  9. private String glbm;
  10. private String userid;
  11. private static final long serialVersionUID = 1L;
  12. public String getId() {
  13. return id;
  14. }
  15. public void setId(String id) {
  16. this.id = id == null ? null : id.trim();
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name == null ? null : name.trim();
  23. }
  24. public String getJsms() {
  25. return jsms;
  26. }
  27. public void setJsms(String jsms) {
  28. this.jsms = jsms == null ? null : jsms.trim();
  29. }
  30. public String getBz() {
  31. return bz;
  32. }
  33. public void setBz(String bz) {
  34. this.bz = bz == null ? null : bz.trim();
  35. }
  36. public Integer getJlzt() {
  37. return jlzt;
  38. }
  39. public void setJlzt(Integer jlzt) {
  40. this.jlzt = jlzt;
  41. }
  42. public String getGlbm() {
  43. return glbm;
  44. }
  45. public void setGlbm(String glbm) {
  46. this.glbm = glbm == null ? null : glbm.trim();
  47. }
  48. public String getUserid() {
  49. return userid;
  50. }
  51. public void setUserid(String userid) {
  52. this.userid = userid == null ? null : userid.trim();
  53. }
  54. @Override
  55. public boolean equals(Object that) {
  56. if ( this == that) {
  57. return true;
  58. }
  59. if (that == null) {
  60. return false;
  61. }
  62. if (getClass() != that.getClass()) {
  63. return false;
  64. }
  65. Role other = (Role) that;
  66. return ( this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  67. && ( this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
  68. && ( this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))
  69. && ( this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))
  70. && ( this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))
  71. && ( this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))
  72. && ( this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));
  73. }
  74. @Override
  75. public int hashCode() {
  76. final int prime = 31;
  77. int result = 1;
  78. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  79. result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
  80. result = prime * result + ((getJsms() == null) ? 0 : getJsms().hashCode());
  81. result = prime * result + ((getBz() == null) ? 0 : getBz().hashCode());
  82. result = prime * result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());
  83. result = prime * result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());
  84. result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());
  85. return result;
  86. }
  87. }</span>

首先讲一下业务,这里用到的 User 、Role 的对应关系是,一个用户有多个角色,也就是 User : Role 是 1 : n 的关系。因此,在 User 的实体中加入一个 Role 的属性,对应一对多的关系。

然后就是 mapper 接口和 xml 文件了:

mapper接口

UserMapper

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.mapper;  
  2.   
  3. import com.sica.domain.User;  
  4.   
  5. import java.util.List;  
  6.   
  7. public interface UserMapper {  
  8.     int deleteByPrimaryKey(String id);  
  9.   
  10.     int insert(User record);  
  11.   
  12.     int insertSelective(User record);  
  13.   
  14.     User selectByPrimaryKey(String id);  
  15.   
  16.     int updateByPrimaryKeySelective(User record);  
  17.   
  18.     int updateByPrimaryKey(User record);  
  19.   
  20.     List<User> queryForList();  
  21. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.mapper;
  2. import com.sica.domain.User;
  3. import java.util.List;
  4. public interface UserMapper {
  5. int deleteByPrimaryKey(String id);
  6. int insert(User record);
  7. int insertSelective(User record);
  8. User selectByPrimaryKey(String id);
  9. int updateByPrimaryKeySelective(User record);
  10. int updateByPrimaryKey(User record);
  11. List<User> queryForList();
  12. }</span>

mapper xml文件

UserMapper

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”><?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.sica.mapper.UserMapper”>  
  4.     <resultMap id=“BaseResultMap” type=“com.sica.domain.User”>  
  5.         <id column=“id” property=“id” jdbcType=“VARCHAR”/>  
  6.         <result column=“username” property=“username” jdbcType=“VARCHAR”/>  
  7.         <result column=“password” property=“password” jdbcType=“VARCHAR”/>  
  8.     </resultMap>  
  9.   
  10.     <resultMap id=“queryForListMap” type=“com.sica.domain.User”>  
  11.         <id column=“id” property=“id” jdbcType=“VARCHAR”/>  
  12.         <result column=“username” property=“username” jdbcType=“VARCHAR”/>  
  13.         <result column=“password” property=“password” jdbcType=“VARCHAR”/>  
  14.         <collection property=“roles” javaType=“java.util.List” ofType=“com.sica.domain.Role”>  
  15.             <id column=“r_id” property=“id” jdbcType=“VARCHAR” />  
  16.             <result column=“r_name” property=“name” jdbcType=“VARCHAR” />  
  17.             <result column=“r_jsms” property=“jsms” jdbcType=“VARCHAR” />  
  18.             <result column=“r_bz” property=“bz” jdbcType=“VARCHAR” />  
  19.             <result column=“r_jlzt” property=“jlzt” jdbcType=“INTEGER” />  
  20.             <result column=“r_glbm” property=“glbm” jdbcType=“VARCHAR” />  
  21.         </collection>  
  22.     </resultMap>  
  23.     <select id=“queryForList” resultMap=“queryForListMap”>  
  24.         SELECT  
  25.           u.id,  
  26.           u.username,  
  27.           u.password,  
  28.           r.id r_id,  
  29.           r.name r_name,  
  30.           r.jsms r_jsms,  
  31.           r.bz r_bz,  
  32.           r.jlzt r_jlzt,  
  33.           r.glbm r_glbm  
  34.         FROM  
  35.           user u  
  36.         LEFT JOIN  
  37.           role r  
  38.         ON  
  39.           u.id = r.userid  
  40.     </select>  
  41.     <sql id=“Base_Column_List”>  
  42.       id, username, password  
  43.     </sql>  
  44.     <select id=“selectByPrimaryKey” resultMap=“BaseResultMap” parameterType=“java.lang.String”>  
  45.         select  
  46.         <include refid=“Base_Column_List”/>  
  47.         from user  
  48.         where id = #{id,jdbcType=VARCHAR}  
  49.     </select>  
  50.     <delete id=“deleteByPrimaryKey” parameterType=“java.lang.String”>  
  51.     delete from user  
  52.     where id = #{id,jdbcType=VARCHAR}  
  53.     </delete>  
  54.     <insert id=“insert” parameterType=“com.sica.domain.User”>  
  55.     insert into user (id, username, password  
  56.       )  
  57.     values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}  
  58.       )  
  59.     </insert>  
  60.     <insert id=“insertSelective” parameterType=“com.sica.domain.User”>  
  61.         insert into user  
  62.         <trim prefix=“(“ suffix=“)” suffixOverrides=“,”>  
  63.             <if test=“id != null”>  
  64.                 id,  
  65.             </if>  
  66.             <if test=“username != null”>  
  67.                 username,  
  68.             </if>  
  69.             <if test=“password != null”>  
  70.                 password,  
  71.             </if>  
  72.         </trim>  
  73.         <trim prefix=“values (“ suffix=“)” suffixOverrides=“,”>  
  74.             <if test=“id != null”>  
  75.                 #{id,jdbcType=VARCHAR},  
  76.             </if>  
  77.             <if test=“username != null”>  
  78.                 #{username,jdbcType=VARCHAR},  
  79.             </if>  
  80.             <if test=“password != null”>  
  81.                 #{password,jdbcType=VARCHAR},  
  82.             </if>  
  83.         </trim>  
  84.     </insert>  
  85.     <update id=“updateByPrimaryKeySelective” parameterType=“com.sica.domain.User”>  
  86.         update user  
  87.         <set>  
  88.             <if test=“username != null”>  
  89.                 username = #{username,jdbcType=VARCHAR},  
  90.             </if>  
  91.             <if test=“password != null”>  
  92.                 password = #{password,jdbcType=VARCHAR},  
  93.             </if>  
  94.         </set>  
  95.         where id = #{id,jdbcType=VARCHAR}  
  96.     </update>  
  97.     <update id=“updateByPrimaryKey” parameterType=“com.sica.domain.User”>  
  98.     update user  
  99.     set username = #{username,jdbcType=VARCHAR},  
  100.       password = #{password,jdbcType=VARCHAR}  
  101.     where id = #{id,jdbcType=VARCHAR}  
  102.   </update>  
  103. </mapper></span>  


    
    
  1. <span style="font-family:Comic Sans MS;font-size:12px;"> <?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.sica.mapper.UserMapper">
  4. <resultMap id="BaseResultMap" type="com.sica.domain.User">
  5. <id column="id" property="id" jdbcType="VARCHAR"/>
  6. <result column="username" property="username" jdbcType="VARCHAR"/>
  7. <result column="password" property="password" jdbcType="VARCHAR"/>
  8. </resultMap>
  9. <resultMap id="queryForListMap" type="com.sica.domain.User">
  10. <id column="id" property="id" jdbcType="VARCHAR"/>
  11. <result column="username" property="username" jdbcType="VARCHAR"/>
  12. <result column="password" property="password" jdbcType="VARCHAR"/>
  13. <collection property="roles" javaType="java.util.List" ofType="com.sica.domain.Role">
  14. <id column="r_id" property="id" jdbcType="VARCHAR" />
  15. <result column="r_name" property="name" jdbcType="VARCHAR" />
  16. <result column="r_jsms" property="jsms" jdbcType="VARCHAR" />
  17. <result column="r_bz" property="bz" jdbcType="VARCHAR" />
  18. <result column="r_jlzt" property="jlzt" jdbcType="INTEGER" />
  19. <result column="r_glbm" property="glbm" jdbcType="VARCHAR" />
  20. </collection>
  21. </resultMap>
  22. <select id="queryForList" resultMap="queryForListMap">
  23. SELECT
  24. u.id,
  25. u.username,
  26. u.password,
  27. r.id r_id,
  28. r.name r_name,
  29. r.jsms r_jsms,
  30. r.bz r_bz,
  31. r.jlzt r_jlzt,
  32. r.glbm r_glbm
  33. FROM
  34. user u
  35. LEFT JOIN
  36. role r
  37. ON
  38. u.id = r.userid
  39. </select>
  40. <sql id="Base_Column_List">
  41. id, username, password
  42. </sql>
  43. <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String">
  44. select
  45. <include refid="Base_Column_List"/>
  46. from user
  47. where id = #{id,jdbcType=VARCHAR}
  48. </select>
  49. <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
  50. delete from user
  51. where id = #{id,jdbcType=VARCHAR}
  52. </delete>
  53. <insert id="insert" parameterType="com.sica.domain.User">
  54. insert into user (id, username, password
  55. )
  56. values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
  57. )
  58. </insert>
  59. <insert id="insertSelective" parameterType="com.sica.domain.User">
  60. insert into user
  61. <trim prefix="(" suffix=")" suffixOverrides=",">
  62. <if test="id != null">
  63. id,
  64. </if>
  65. <if test="username != null">
  66. username,
  67. </if>
  68. <if test="password != null">
  69. password,
  70. </if>
  71. </trim>
  72. <trim prefix="values (" suffix=")" suffixOverrides=",">
  73. <if test="id != null">
  74. #{id,jdbcType=VARCHAR},
  75. </if>
  76. <if test="username != null">
  77. #{username,jdbcType=VARCHAR},
  78. </if>
  79. <if test="password != null">
  80. #{password,jdbcType=VARCHAR},
  81. </if>
  82. </trim>
  83. </insert>
  84. <update id="updateByPrimaryKeySelective" parameterType="com.sica.domain.User">
  85. update user
  86. <set>
  87. <if test="username != null">
  88. username = #{username,jdbcType=VARCHAR},
  89. </if>
  90. <if test="password != null">
  91. password = #{password,jdbcType=VARCHAR},
  92. </if>
  93. </set>
  94. where id = #{id,jdbcType=VARCHAR}
  95. </update>
  96. <update id="updateByPrimaryKey" parameterType="com.sica.domain.User">
  97. update user
  98. set username = #{username,jdbcType=VARCHAR},
  99. password = #{password,jdbcType=VARCHAR}
  100. where id = #{id,jdbcType=VARCHAR}
  101. </update>
  102. </mapper> </span>

之后,我扩展了一个 Dao 接口,当然,你也可以直接使用 mapper 接口,都是一样的。

Dao 接口

IUserDao

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.dao;  
  2.   
  3. import com.sica.mapper.UserMapper;  
  4.   
  5. /* 
  6.   Created by IntelliJ IDEA. 
  7.   Package: com.sica.dao 
  8.   Name: IUserDao 
  9.   User: xiang.li 
  10.   Date: 2015/5/22 
  11.   Time: 15:25 
  12.   Desc: To change this template use File | Settings | File Templates. 
  13.  */  
  14. public interface IUserDao extends UserMapper {  
  15.   
  16. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.dao;
  2. import com.sica.mapper.UserMapper;
  3. /*
  4. Created by IntelliJ IDEA.
  5. * Package: com.sica.dao
  6. * Name: IUserDao
  7. * User: xiang.li
  8. * Date: 2015/5/22
  9. * Time: 15:25
  10. * Desc: To change this template use File | Settings | File Templates.
  11. */
  12. public interface IUserDao extends UserMapper {
  13. }</span>

下面就是 service 和实现层的代码了。

IUserService

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.service;  
  2.   
  3. import com.sica.domain.User;  
  4.   
  5. import java.util.List;  
  6.   
  7. / 
  8.   Created by xiang.li on 2015/1/31. 
  9.  /  
  10. public interface IUserService {  
  11.   
  12.     / 
  13.       根据Id查询用户对象 
  14.       @param id 编号 
  15.       @return 用户对象 
  16.      /  
  17.     User getUserById(String id);  
  18.   
  19.     /* 
  20.       根据用户名查询用户对象 
  21.       @return  List 
  22.      /  
  23.     List<User> queryUserList();  
  24. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.service;
  2. import com.sica.domain.User;
  3. import java.util.List;
  4. /
  5. * Created by xiang.li on 2015/1/31.
  6. /
  7. public interface IUserService {
  8. /
  9. 根据Id查询用户对象
  10. * @param id 编号
  11. * @return 用户对象
  12. /
  13. User getUserById(String id);
  14. /*
  15. * 根据用户名查询用户对象
  16. * @return List
  17. */
  18. List<User> queryUserList();
  19. }</span>

UserServiceImpl

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.service.impl;  
  2.   
  3. import com.sica.dao.IUserDao;  
  4. import com.sica.domain.User;  
  5. import com.sica.service.IUserService;  
  6. import org.springframework.stereotype.Service;  
  7.   
  8. import javax.annotation.Resource;  
  9. import java.util.List;  
  10.   
  11. /* 
  12.   Created by xiang.li on 2015/1/31. 
  13.  */  
  14. @Service(“userService”)  
  15. public class UserServiceImpl implements IUserService {  
  16.   
  17.     @Resource  
  18.     public IUserDao userDao;  
  19.   
  20.     @Override  
  21.     public User getUserById(String id) {  
  22.         return this.userDao.selectByPrimaryKey(id);  
  23.     }  
  24.   
  25.     @Override  
  26.     public List<User> queryUserList() {  
  27.         return userDao.queryForList();  
  28.     }  
  29.   
  30. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.service.impl;
  2. import com.sica.dao.IUserDao;
  3. import com.sica.domain.User;
  4. import com.sica.service.IUserService;
  5. import org.springframework.stereotype.Service;
  6. import javax.annotation.Resource;
  7. import java.util.List;
  8. /*
  9. Created by xiang.li on 2015/1/31.
  10. */
  11. @Service( "userService")
  12. public class UserServiceImpl implements IUserService {
  13. @Resource
  14. public IUserDao userDao;
  15. @Override
  16. public User getUserById(String id) {
  17. return this.userDao.selectByPrimaryKey(id);
  18. }
  19. @Override
  20. public List<User> queryUserList() {
  21. return userDao.queryForList();
  22. }
  23. }</span>

当然,还有所谓的 applicationContext.xml 配置,不过,我这里叫 spring-mybatis.xml。


  1. <span style=“font-family:Comic Sans MS;font-size:12px;”><?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=http://www.springframework.org/schema/beans  
  3.        xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance  
  4.        xmlns:p=http://www.springframework.org/schema/p  
  5.        xmlns:context=http://www.springframework.org/schema/context  
  6.        xmlns:mvc=http://www.springframework.org/schema/mvc  
  7.        xsi:schemaLocation=”http://www.springframework.org/schema/beans  
  8.        http://www.springframework.org/schema/beans/spring-beans.xsd &nbsp;
  9.         http://www.springframework.org/schema/context &nbsp;
  10.         http://www.springframework.org/schema/context/spring-context.xsd &nbsp;
  11.         http://www.springframework.org/schema/mvc &nbsp;
  12.         http://www.springframework.org/schema/mvc/spring-mvc.xsd>  
  13.   
  14.     <!– 自动扫描 –>  
  15.     <context:component-scan base-package=“com.sica”/>  
  16.     <!– 引入配置文件 –>  
  17.     <bean id=“propertyConfigurer” class=“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”  
  18.           p:location=“classpath:jdbc.properties”  
  19.           />  
  20.   
  21.     <!– 配置数据库连接池 –>  
  22.     <!– 初始化连接大小 –>  
  23.     <!– 连接池最大数量 –>  
  24.     <!– 连接池最大空闲 –>  
  25.     <!– 连接池最小空闲 –>  
  26.     <!– 获取连接最大等待时间 –>  
  27.     <bean id=“dataSource” class=“org.apache.commons.dbcp.BasicDataSource” destroy-method=“close”  
  28.           p:driverClassName= {jdbc.driver}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:url</span><span>=</span><span class="attribute-value">" {jdbc.url}”  
  29.           p:username= {jdbc.username}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:password</span><span>=</span><span class="attribute-value">" {jdbc.password}”  
  30.           p:initialSize= {jdbc.initialSize}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:maxActive</span><span>=</span><span class="attribute-value">" {jdbc.maxActive}”  
  31.           p:maxIdle= {jdbc.maxIdle}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:minIdle</span><span>=</span><span class="attribute-value">" {jdbc.minIdle}”  
  32.           p:maxWait=“${jdbc.maxWait}”  
  33.           />  
  34.   
  35.     <!– spring和MyBatis完美整合,不需要mybatis的配置映射文件 –>  
  36.     <bean id=“sqlSessionFactory” class=“org.mybatis.spring.SqlSessionFactoryBean” lazy-init=“default”  
  37.           p:dataSource-ref=“dataSource”  
  38.           p:mapperLocations=“classpath:com/sica/mapping/*.xml”  
  39.           />  
  40.   
  41.     <!– DAO接口所在包名,Spring会自动查找其下的类 –>  
  42.     <bean class=“org.mybatis.spring.mapper.MapperScannerConfigurer”  
  43.           p:basePackage=“com.sica.dao”  
  44.           p:sqlSessionFactoryBeanName=“sqlSessionFactory”  
  45.           />  
  46.   
  47.     <!– (事务管理)transaction manager, use JtaTransactionManager for global tx –>  
  48.     <bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”  
  49.           p:dataSource-ref=“dataSource”  
  50.           />  
  51. </beans></span>  


    
    
  1. <span style="font-family:Comic Sans MS;font-size:12px;"> <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- 自动扫描 -->
  3. <context:component-scan base-package="com.sica"/>
  4. <!-- 引入配置文件 -->
  5. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  6. p:location= "classpath:jdbc.properties"
  7. />
  8. <!-- 配置数据库连接池 -->
  9. <!-- 初始化连接大小 -->
  10. <!-- 连接池最大数量 -->
  11. <!-- 连接池最大空闲 -->
  12. <!-- 连接池最小空闲 -->
  13. <!-- 获取连接最大等待时间 -->
  14. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
  15. p:driverClassName= "${jdbc.driver}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:url</span>=<span class="hljs-string">"${jdbc.url}"
  16. p:username= "${jdbc.username}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="31"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:password</span>=<span class="hljs-string">"${jdbc.password}"
  17. p:initialSize= "${jdbc.initialSize}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:maxActive</span>=<span class="hljs-string">"${jdbc.maxActive}"
  18. p:maxIdle= "${jdbc.maxIdle}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:minIdle</span>=<span class="hljs-string">"${jdbc.minIdle}"
  19. p:maxWait= "${jdbc.maxWait}"
  20. />
  21. <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
  22. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" lazy-init="default"
  23. p:dataSource-ref= "dataSource"
  24. p:mapperLocations= "classpath:com/sica/mapping/*.xml"
  25. />
  26. <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  27. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
  28. p:basePackage= "com.sica.dao"
  29. p:sqlSessionFactoryBeanName= "sqlSessionFactory"
  30. />
  31. <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
  32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  33. p:dataSource-ref= "dataSource"
  34. />
  35. </beans> </span>

最后,我用到的是 junit 进行的测试,测试代码如下。

GetUserTest

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.user;  
  2.   
  3. import com.alibaba.fastjson.JSON;  
  4. import com.sica.domain.User;  
  5. import com.sica.service.IUserService;  
  6. import org.junit.Test;  
  7. import org.junit.runner.RunWith;  
  8. import org.slf4j.Logger;  
  9. import org.slf4j.LoggerFactory;  
  10. import org.springframework.test.context.ContextConfiguration;  
  11. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  12.   
  13. import javax.annotation.Resource;  
  14. import java.util.List;  
  15.   
  16. / 
  17.   Created by xiang.li on 2015/2/1. 
  18.  /  
  19. @RunWith(SpringJUnit4ClassRunner.class)  
  20. @ContextConfiguration(locations = “classpath:spring-mybatis.xml”)  
  21. public class GetUserTest {  
  22.   
  23.     private static String UUID = “3”;  
  24.     @Resource  
  25.     private IUserService userService;  
  26.     private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);  
  27.   
  28.     @Test  
  29.     public void test() {  
  30.         User user = userService.getUserById(UUID);  
  31.         logger.info(JSON.toJSONString(user));  
  32.     }  
  33.   
  34.     / 
  35.       测试联合查询 
  36.      /  
  37.     @Test  
  38.     public void test2() {  
  39.         List<User> users = userService.queryUserList();  
  40.         logger.info(JSON.toJSONString(users));  
  41.     }  
  42. }</span>  


    
    
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.user;
  2. import com.alibaba.fastjson.JSON;
  3. import com.sica.domain.User;
  4. import com.sica.service.IUserService;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.test.context.ContextConfiguration;
  10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  11. import javax.annotation.Resource;
  12. import java.util.List;
  13. /
  14. * Created by xiang.li on 2015/2/1.
  15. /
  16. @RunWith(SpringJUnit4ClassRunner.class)
  17. @ContextConfiguration(locations = "classpath:spring-mybatis.xml")
  18. public class GetUserTest {
  19. private static String UUID = "3";
  20. @Resource
  21. private IUserService userService;
  22. private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);
  23. @Test
  24. public void test() {
  25. User user = userService.getUserById(UUID);
  26. logger.info(JSON.toJSONString(user));
  27. }
  28. /
  29. 测试联合查询
  30. */
  31. @Test
  32. public void test2() {
  33. List<User> users = userService.queryUserList();
  34. logger.info(JSON.toJSONString(users));
  35. }
  36. }</span>


测试结果




可以看到,所有的用户和用户对应的角色都全部查出来了,这说明,这次的测试很成功。


关于优化


对于优化嘛,我这里简单的提几点,大家可以考虑一下。首先,就是对表的设计,在设计表初期,不仅仅要考虑到数据库的规范性,还好考虑到所谓的业务,以及对性能的影响,比如,如果从规范性角度考虑的话,可能就会分多个表,但是如果从性能角度来考虑的话,庞大的数据量在多表联合查询的时候,相对于单表来说,就会慢很多,这时,如果字段不是很多的话,可以考虑冗余几个字段采用单表的设计。

其次嘛,就是在 sql 上下功夫了,对于联合查询,sql 的优化是很有必要的,到底是采用 INNER JOIN,还是采用 LEFT JOIN 亦或是 RIGHT JOIN 、OUTTER JOIN 等,都是要在满足业务需求之后,通过测试性能得出的结论。

再次嘛,就是在程序中调用的时候了,是采用懒加载,还是采用非懒加载的方式,这也算是一个因素吧,具体的还是要考虑业务的需要。

最后嘛,就要用到数据库的缓存了,或者在数据库与程序的中间再加一层缓存。不过,还是建议用好数据库本身自带的缓存功能。


结束语


最后的最后,还是要提醒大家,不要因为觉得简单就引不起足够的重视,否则你会由于一点点小的失误,而浪费大把大把的时间的。我就在这上边体会过,所以,这里奉劝大家,还是小心为妙啊@!







这篇文章我打算来简单的谈谈 mybatis 的多表联合查询。起初是觉得挺简单的,没必要拿出来写,毕竟 mybatis 这东西现在是个开发的都会用,而且网上的文章也是一搜罗一大堆,根本就用不着我来重复。但是吧,就我前几天在做一个多表联合查询的时候,竟然出了很多意想不到的问题,而且这些问题的出现,并不是对 mybatis 不了解,而是在用的过程中会或多或少的忽略一些东西,导致提示各种错误。


背景


老规矩,开始之前,还是要先说说这件事的背景。也就是最近几天,公司要做一个后台的管理平台,由于之前的一些限制,这次要做成单独的项目进行部署,因此就要重新考虑很多东西。索性这几天有时间,就做了一个小 Demo ,实现 mybatis 的多表联合查询的,由于之前用的是 Hibernate 做的联合查询,众所周知,Hibernate 是全自动的数据库持久层框架,它可以通过实体来映射数据库,通过设置一对多、多对一、一对一、多对多的关联来实现联合查询。


正文


下面就来说一下 mybatis 是通过什么来实现多表联合查询的。首先看一下表关系,如图:



这里,我已经搭好了开发的环境,用到的是 SpringMVC + Spring + MyBatis,当然,为了简单期间,你可以不用搭前端的框架,只使用 Spring + MyBatis 就可以,外加 junit 测试即可。环境我就不带大家搭了,这里只说涉及到联合查询的操作。

设计好表之后,我用到了 mybatis 的自动生成工具 mybatis generator 生成的实体类、mapper 接口、以及 mapper xml 文件。由于是测试多表联合查询,因此需要自己稍加改动。

下面是 User 和 Role 的实体类代码:

User

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.domain;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.List;  
  5.   
  6. public class User implements Serializable {  
  7.     private String id;  
  8.   
  9.     private String username;  
  10.   
  11.     private String password;  
  12.   
  13.     private List<Role> roles;  
  14.   
  15.     private static final long serialVersionUID = 1L;  
  16.   
  17.     public String getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(String id) {  
  22.         this.id = id == null ? null : id.trim();  
  23.     }  
  24.   
  25.     public String getUsername() {  
  26.         return username;  
  27.     }  
  28.   
  29.     public void setUsername(String username) {  
  30.         this.username = username == null ? null : username.trim();  
  31.     }  
  32.   
  33.     public String getPassword() {  
  34.         return password;  
  35.     }  
  36.   
  37.     public void setPassword(String password) {  
  38.         this.password = password == null ? null : password.trim();  
  39.     }  
  40.   
  41.     public List<Role> getRoles() {  
  42.         return roles;  
  43.     }  
  44.   
  45.     public void setRoles(List<Role> roles) {  
  46.         this.roles = roles;  
  47.     }  
  48.   
  49.     @Override  
  50.     public boolean equals(Object that) {  
  51.         if (this == that) {  
  52.             return true;  
  53.         }  
  54.         if (that == null) {  
  55.             return false;  
  56.         }  
  57.         if (getClass() != that.getClass()) {  
  58.             return false;  
  59.         }  
  60.         User other = (User) that;  
  61.         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))  
  62.             && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))  
  63.             && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));  
  64.     }  
  65.   
  66.     @Override  
  67.     public int hashCode() {  
  68.         final int prime = 31;  
  69.         int result = 1;  
  70.         result = prime  result + ((getId() == null) ? 0 : getId().hashCode());  
  71.         result = prime  result + ((getUsername() == null) ? 0 : getUsername().hashCode());  
  72.         result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());  
  73.         return result;  
  74.     }  
  75. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.domain;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. public class User implements Serializable {
  5. private String id;
  6. private String username;
  7. private String password;
  8. private List<Role> roles;
  9. private static final long serialVersionUID = 1L;
  10. public String getId() {
  11. return id;
  12. }
  13. public void setId(String id) {
  14. this.id = id == null ? null : id.trim();
  15. }
  16. public String getUsername() {
  17. return username;
  18. }
  19. public void setUsername(String username) {
  20. this.username = username == null ? null : username.trim();
  21. }
  22. public String getPassword() {
  23. return password;
  24. }
  25. public void setPassword(String password) {
  26. this.password = password == null ? null : password.trim();
  27. }
  28. public List<Role> getRoles() {
  29. return roles;
  30. }
  31. public void setRoles(List<Role> roles) {
  32. this.roles = roles;
  33. }
  34. @Override
  35. public boolean equals(Object that) {
  36. if ( this == that) {
  37. return true;
  38. }
  39. if (that == null) {
  40. return false;
  41. }
  42. if (getClass() != that.getClass()) {
  43. return false;
  44. }
  45. User other = (User) that;
  46. return ( this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  47. && ( this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
  48. && ( this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));
  49. }
  50. @Override
  51. public int hashCode() {
  52. final int prime = 31;
  53. int result = 1;
  54. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  55. result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
  56. result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
  57. return result;
  58. }
  59. }</span>

Role

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.domain;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Role implements Serializable {  
  6.     private String id;  
  7.   
  8.     private String name;  
  9.   
  10.     private String jsms;  
  11.   
  12.     private String bz;  
  13.   
  14.     private Integer jlzt;  
  15.   
  16.     private String glbm;  
  17.   
  18.     private String userid;  
  19.   
  20.     private static final long serialVersionUID = 1L;  
  21.   
  22.     public String getId() {  
  23.         return id;  
  24.     }  
  25.   
  26.     public void setId(String id) {  
  27.         this.id = id == null ? null : id.trim();  
  28.     }  
  29.   
  30.     public String getName() {  
  31.         return name;  
  32.     }  
  33.   
  34.     public void setName(String name) {  
  35.         this.name = name == null ? null : name.trim();  
  36.     }  
  37.   
  38.     public String getJsms() {  
  39.         return jsms;  
  40.     }  
  41.   
  42.     public void setJsms(String jsms) {  
  43.         this.jsms = jsms == null ? null : jsms.trim();  
  44.     }  
  45.   
  46.     public String getBz() {  
  47.         return bz;  
  48.     }  
  49.   
  50.     public void setBz(String bz) {  
  51.         this.bz = bz == null ? null : bz.trim();  
  52.     }  
  53.   
  54.     public Integer getJlzt() {  
  55.         return jlzt;  
  56.     }  
  57.   
  58.     public void setJlzt(Integer jlzt) {  
  59.         this.jlzt = jlzt;  
  60.     }  
  61.   
  62.     public String getGlbm() {  
  63.         return glbm;  
  64.     }  
  65.   
  66.     public void setGlbm(String glbm) {  
  67.         this.glbm = glbm == null ? null : glbm.trim();  
  68.     }  
  69.   
  70.     public String getUserid() {  
  71.         return userid;  
  72.     }  
  73.   
  74.     public void setUserid(String userid) {  
  75.         this.userid = userid == null ? null : userid.trim();  
  76.     }  
  77.   
  78.     @Override  
  79.     public boolean equals(Object that) {  
  80.         if (this == that) {  
  81.             return true;  
  82.         }  
  83.         if (that == null) {  
  84.             return false;  
  85.         }  
  86.         if (getClass() != that.getClass()) {  
  87.             return false;  
  88.         }  
  89.         Role other = (Role) that;  
  90.         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))  
  91.             && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))  
  92.             && (this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))  
  93.             && (this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))  
  94.             && (this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))  
  95.             && (this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))  
  96.             && (this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));  
  97.     }  
  98.   
  99.     @Override  
  100.     public int hashCode() {  
  101.         final int prime = 31;  
  102.         int result = 1;  
  103.         result = prime  result + ((getId() == null) ? 0 : getId().hashCode());  
  104.         result = prime  result + ((getName() == null) ? 0 : getName().hashCode());  
  105.         result = prime  result + ((getJsms() == null) ? 0 : getJsms().hashCode());  
  106.         result = prime  result + ((getBz() == null) ? 0 : getBz().hashCode());  
  107.         result = prime  result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());  
  108.         result = prime  result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());  
  109.         result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());  
  110.         return result;  
  111.     }  
  112. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.domain;
  2. import java.io.Serializable;
  3. public class Role implements Serializable {
  4. private String id;
  5. private String name;
  6. private String jsms;
  7. private String bz;
  8. private Integer jlzt;
  9. private String glbm;
  10. private String userid;
  11. private static final long serialVersionUID = 1L;
  12. public String getId() {
  13. return id;
  14. }
  15. public void setId(String id) {
  16. this.id = id == null ? null : id.trim();
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name == null ? null : name.trim();
  23. }
  24. public String getJsms() {
  25. return jsms;
  26. }
  27. public void setJsms(String jsms) {
  28. this.jsms = jsms == null ? null : jsms.trim();
  29. }
  30. public String getBz() {
  31. return bz;
  32. }
  33. public void setBz(String bz) {
  34. this.bz = bz == null ? null : bz.trim();
  35. }
  36. public Integer getJlzt() {
  37. return jlzt;
  38. }
  39. public void setJlzt(Integer jlzt) {
  40. this.jlzt = jlzt;
  41. }
  42. public String getGlbm() {
  43. return glbm;
  44. }
  45. public void setGlbm(String glbm) {
  46. this.glbm = glbm == null ? null : glbm.trim();
  47. }
  48. public String getUserid() {
  49. return userid;
  50. }
  51. public void setUserid(String userid) {
  52. this.userid = userid == null ? null : userid.trim();
  53. }
  54. @Override
  55. public boolean equals(Object that) {
  56. if ( this == that) {
  57. return true;
  58. }
  59. if (that == null) {
  60. return false;
  61. }
  62. if (getClass() != that.getClass()) {
  63. return false;
  64. }
  65. Role other = (Role) that;
  66. return ( this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  67. && ( this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
  68. && ( this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))
  69. && ( this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))
  70. && ( this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))
  71. && ( this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))
  72. && ( this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));
  73. }
  74. @Override
  75. public int hashCode() {
  76. final int prime = 31;
  77. int result = 1;
  78. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  79. result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
  80. result = prime * result + ((getJsms() == null) ? 0 : getJsms().hashCode());
  81. result = prime * result + ((getBz() == null) ? 0 : getBz().hashCode());
  82. result = prime * result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());
  83. result = prime * result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());
  84. result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());
  85. return result;
  86. }
  87. }</span>

首先讲一下业务,这里用到的 User 、Role 的对应关系是,一个用户有多个角色,也就是 User : Role 是 1 : n 的关系。因此,在 User 的实体中加入一个 Role 的属性,对应一对多的关系。

然后就是 mapper 接口和 xml 文件了:

mapper接口

UserMapper

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.mapper;  
  2.   
  3. import com.sica.domain.User;  
  4.   
  5. import java.util.List;  
  6.   
  7. public interface UserMapper {  
  8.     int deleteByPrimaryKey(String id);  
  9.   
  10.     int insert(User record);  
  11.   
  12.     int insertSelective(User record);  
  13.   
  14.     User selectByPrimaryKey(String id);  
  15.   
  16.     int updateByPrimaryKeySelective(User record);  
  17.   
  18.     int updateByPrimaryKey(User record);  
  19.   
  20.     List<User> queryForList();  
  21. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.mapper;
  2. import com.sica.domain.User;
  3. import java.util.List;
  4. public interface UserMapper {
  5. int deleteByPrimaryKey(String id);
  6. int insert(User record);
  7. int insertSelective(User record);
  8. User selectByPrimaryKey(String id);
  9. int updateByPrimaryKeySelective(User record);
  10. int updateByPrimaryKey(User record);
  11. List<User> queryForList();
  12. }</span>

mapper xml文件

UserMapper

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”><?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.sica.mapper.UserMapper”>  
  4.     <resultMap id=“BaseResultMap” type=“com.sica.domain.User”>  
  5.         <id column=“id” property=“id” jdbcType=“VARCHAR”/>  
  6.         <result column=“username” property=“username” jdbcType=“VARCHAR”/>  
  7.         <result column=“password” property=“password” jdbcType=“VARCHAR”/>  
  8.     </resultMap>  
  9.   
  10.     <resultMap id=“queryForListMap” type=“com.sica.domain.User”>  
  11.         <id column=“id” property=“id” jdbcType=“VARCHAR”/>  
  12.         <result column=“username” property=“username” jdbcType=“VARCHAR”/>  
  13.         <result column=“password” property=“password” jdbcType=“VARCHAR”/>  
  14.         <collection property=“roles” javaType=“java.util.List” ofType=“com.sica.domain.Role”>  
  15.             <id column=“r_id” property=“id” jdbcType=“VARCHAR” />  
  16.             <result column=“r_name” property=“name” jdbcType=“VARCHAR” />  
  17.             <result column=“r_jsms” property=“jsms” jdbcType=“VARCHAR” />  
  18.             <result column=“r_bz” property=“bz” jdbcType=“VARCHAR” />  
  19.             <result column=“r_jlzt” property=“jlzt” jdbcType=“INTEGER” />  
  20.             <result column=“r_glbm” property=“glbm” jdbcType=“VARCHAR” />  
  21.         </collection>  
  22.     </resultMap>  
  23.     <select id=“queryForList” resultMap=“queryForListMap”>  
  24.         SELECT  
  25.           u.id,  
  26.           u.username,  
  27.           u.password,  
  28.           r.id r_id,  
  29.           r.name r_name,  
  30.           r.jsms r_jsms,  
  31.           r.bz r_bz,  
  32.           r.jlzt r_jlzt,  
  33.           r.glbm r_glbm  
  34.         FROM  
  35.           user u  
  36.         LEFT JOIN  
  37.           role r  
  38.         ON  
  39.           u.id = r.userid  
  40.     </select>  
  41.     <sql id=“Base_Column_List”>  
  42.       id, username, password  
  43.     </sql>  
  44.     <select id=“selectByPrimaryKey” resultMap=“BaseResultMap” parameterType=“java.lang.String”>  
  45.         select  
  46.         <include refid=“Base_Column_List”/>  
  47.         from user  
  48.         where id = #{id,jdbcType=VARCHAR}  
  49.     </select>  
  50.     <delete id=“deleteByPrimaryKey” parameterType=“java.lang.String”>  
  51.     delete from user  
  52.     where id = #{id,jdbcType=VARCHAR}  
  53.     </delete>  
  54.     <insert id=“insert” parameterType=“com.sica.domain.User”>  
  55.     insert into user (id, username, password  
  56.       )  
  57.     values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}  
  58.       )  
  59.     </insert>  
  60.     <insert id=“insertSelective” parameterType=“com.sica.domain.User”>  
  61.         insert into user  
  62.         <trim prefix=“(“ suffix=“)” suffixOverrides=“,”>  
  63.             <if test=“id != null”>  
  64.                 id,  
  65.             </if>  
  66.             <if test=“username != null”>  
  67.                 username,  
  68.             </if>  
  69.             <if test=“password != null”>  
  70.                 password,  
  71.             </if>  
  72.         </trim>  
  73.         <trim prefix=“values (“ suffix=“)” suffixOverrides=“,”>  
  74.             <if test=“id != null”>  
  75.                 #{id,jdbcType=VARCHAR},  
  76.             </if>  
  77.             <if test=“username != null”>  
  78.                 #{username,jdbcType=VARCHAR},  
  79.             </if>  
  80.             <if test=“password != null”>  
  81.                 #{password,jdbcType=VARCHAR},  
  82.             </if>  
  83.         </trim>  
  84.     </insert>  
  85.     <update id=“updateByPrimaryKeySelective” parameterType=“com.sica.domain.User”>  
  86.         update user  
  87.         <set>  
  88.             <if test=“username != null”>  
  89.                 username = #{username,jdbcType=VARCHAR},  
  90.             </if>  
  91.             <if test=“password != null”>  
  92.                 password = #{password,jdbcType=VARCHAR},  
  93.             </if>  
  94.         </set>  
  95.         where id = #{id,jdbcType=VARCHAR}  
  96.     </update>  
  97.     <update id=“updateByPrimaryKey” parameterType=“com.sica.domain.User”>  
  98.     update user  
  99.     set username = #{username,jdbcType=VARCHAR},  
  100.       password = #{password,jdbcType=VARCHAR}  
  101.     where id = #{id,jdbcType=VARCHAR}  
  102.   </update>  
  103. </mapper></span>  


  
  
  1. <span style="font-family:Comic Sans MS;font-size:12px;"> <?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.sica.mapper.UserMapper">
  4. <resultMap id="BaseResultMap" type="com.sica.domain.User">
  5. <id column="id" property="id" jdbcType="VARCHAR"/>
  6. <result column="username" property="username" jdbcType="VARCHAR"/>
  7. <result column="password" property="password" jdbcType="VARCHAR"/>
  8. </resultMap>
  9. <resultMap id="queryForListMap" type="com.sica.domain.User">
  10. <id column="id" property="id" jdbcType="VARCHAR"/>
  11. <result column="username" property="username" jdbcType="VARCHAR"/>
  12. <result column="password" property="password" jdbcType="VARCHAR"/>
  13. <collection property="roles" javaType="java.util.List" ofType="com.sica.domain.Role">
  14. <id column="r_id" property="id" jdbcType="VARCHAR" />
  15. <result column="r_name" property="name" jdbcType="VARCHAR" />
  16. <result column="r_jsms" property="jsms" jdbcType="VARCHAR" />
  17. <result column="r_bz" property="bz" jdbcType="VARCHAR" />
  18. <result column="r_jlzt" property="jlzt" jdbcType="INTEGER" />
  19. <result column="r_glbm" property="glbm" jdbcType="VARCHAR" />
  20. </collection>
  21. </resultMap>
  22. <select id="queryForList" resultMap="queryForListMap">
  23. SELECT
  24. u.id,
  25. u.username,
  26. u.password,
  27. r.id r_id,
  28. r.name r_name,
  29. r.jsms r_jsms,
  30. r.bz r_bz,
  31. r.jlzt r_jlzt,
  32. r.glbm r_glbm
  33. FROM
  34. user u
  35. LEFT JOIN
  36. role r
  37. ON
  38. u.id = r.userid
  39. </select>
  40. <sql id="Base_Column_List">
  41. id, username, password
  42. </sql>
  43. <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String">
  44. select
  45. <include refid="Base_Column_List"/>
  46. from user
  47. where id = #{id,jdbcType=VARCHAR}
  48. </select>
  49. <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
  50. delete from user
  51. where id = #{id,jdbcType=VARCHAR}
  52. </delete>
  53. <insert id="insert" parameterType="com.sica.domain.User">
  54. insert into user (id, username, password
  55. )
  56. values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
  57. )
  58. </insert>
  59. <insert id="insertSelective" parameterType="com.sica.domain.User">
  60. insert into user
  61. <trim prefix="(" suffix=")" suffixOverrides=",">
  62. <if test="id != null">
  63. id,
  64. </if>
  65. <if test="username != null">
  66. username,
  67. </if>
  68. <if test="password != null">
  69. password,
  70. </if>
  71. </trim>
  72. <trim prefix="values (" suffix=")" suffixOverrides=",">
  73. <if test="id != null">
  74. #{id,jdbcType=VARCHAR},
  75. </if>
  76. <if test="username != null">
  77. #{username,jdbcType=VARCHAR},
  78. </if>
  79. <if test="password != null">
  80. #{password,jdbcType=VARCHAR},
  81. </if>
  82. </trim>
  83. </insert>
  84. <update id="updateByPrimaryKeySelective" parameterType="com.sica.domain.User">
  85. update user
  86. <set>
  87. <if test="username != null">
  88. username = #{username,jdbcType=VARCHAR},
  89. </if>
  90. <if test="password != null">
  91. password = #{password,jdbcType=VARCHAR},
  92. </if>
  93. </set>
  94. where id = #{id,jdbcType=VARCHAR}
  95. </update>
  96. <update id="updateByPrimaryKey" parameterType="com.sica.domain.User">
  97. update user
  98. set username = #{username,jdbcType=VARCHAR},
  99. password = #{password,jdbcType=VARCHAR}
  100. where id = #{id,jdbcType=VARCHAR}
  101. </update>
  102. </mapper> </span>

之后,我扩展了一个 Dao 接口,当然,你也可以直接使用 mapper 接口,都是一样的。

Dao 接口

IUserDao

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.dao;  
  2.   
  3. import com.sica.mapper.UserMapper;  
  4.   
  5. /* 
  6.   Created by IntelliJ IDEA. 
  7.   Package: com.sica.dao 
  8.   Name: IUserDao 
  9.   User: xiang.li 
  10.   Date: 2015/5/22 
  11.   Time: 15:25 
  12.   Desc: To change this template use File | Settings | File Templates. 
  13.  */  
  14. public interface IUserDao extends UserMapper {  
  15.   
  16. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.dao;
  2. import com.sica.mapper.UserMapper;
  3. /*
  4. Created by IntelliJ IDEA.
  5. * Package: com.sica.dao
  6. * Name: IUserDao
  7. * User: xiang.li
  8. * Date: 2015/5/22
  9. * Time: 15:25
  10. * Desc: To change this template use File | Settings | File Templates.
  11. */
  12. public interface IUserDao extends UserMapper {
  13. }</span>

下面就是 service 和实现层的代码了。

IUserService

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.service;  
  2.   
  3. import com.sica.domain.User;  
  4.   
  5. import java.util.List;  
  6.   
  7. / 
  8.   Created by xiang.li on 2015/1/31. 
  9.  /  
  10. public interface IUserService {  
  11.   
  12.     / 
  13.       根据Id查询用户对象 
  14.       @param id 编号 
  15.       @return 用户对象 
  16.      /  
  17.     User getUserById(String id);  
  18.   
  19.     /* 
  20.       根据用户名查询用户对象 
  21.       @return  List 
  22.      /  
  23.     List<User> queryUserList();  
  24. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.service;
  2. import com.sica.domain.User;
  3. import java.util.List;
  4. /
  5. * Created by xiang.li on 2015/1/31.
  6. /
  7. public interface IUserService {
  8. /
  9. 根据Id查询用户对象
  10. * @param id 编号
  11. * @return 用户对象
  12. /
  13. User getUserById(String id);
  14. /*
  15. * 根据用户名查询用户对象
  16. * @return List
  17. */
  18. List<User> queryUserList();
  19. }</span>

UserServiceImpl

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.service.impl;  
  2.   
  3. import com.sica.dao.IUserDao;  
  4. import com.sica.domain.User;  
  5. import com.sica.service.IUserService;  
  6. import org.springframework.stereotype.Service;  
  7.   
  8. import javax.annotation.Resource;  
  9. import java.util.List;  
  10.   
  11. /* 
  12.   Created by xiang.li on 2015/1/31. 
  13.  */  
  14. @Service(“userService”)  
  15. public class UserServiceImpl implements IUserService {  
  16.   
  17.     @Resource  
  18.     public IUserDao userDao;  
  19.   
  20.     @Override  
  21.     public User getUserById(String id) {  
  22.         return this.userDao.selectByPrimaryKey(id);  
  23.     }  
  24.   
  25.     @Override  
  26.     public List<User> queryUserList() {  
  27.         return userDao.queryForList();  
  28.     }  
  29.   
  30. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.service.impl;
  2. import com.sica.dao.IUserDao;
  3. import com.sica.domain.User;
  4. import com.sica.service.IUserService;
  5. import org.springframework.stereotype.Service;
  6. import javax.annotation.Resource;
  7. import java.util.List;
  8. /*
  9. Created by xiang.li on 2015/1/31.
  10. */
  11. @Service( "userService")
  12. public class UserServiceImpl implements IUserService {
  13. @Resource
  14. public IUserDao userDao;
  15. @Override
  16. public User getUserById(String id) {
  17. return this.userDao.selectByPrimaryKey(id);
  18. }
  19. @Override
  20. public List<User> queryUserList() {
  21. return userDao.queryForList();
  22. }
  23. }</span>

当然,还有所谓的 applicationContext.xml 配置,不过,我这里叫 spring-mybatis.xml。


  1. <span style=“font-family:Comic Sans MS;font-size:12px;”><?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=http://www.springframework.org/schema/beans  
  3.        xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance  
  4.        xmlns:p=http://www.springframework.org/schema/p  
  5.        xmlns:context=http://www.springframework.org/schema/context  
  6.        xmlns:mvc=http://www.springframework.org/schema/mvc  
  7.        xsi:schemaLocation=”http://www.springframework.org/schema/beans  
  8.        http://www.springframework.org/schema/beans/spring-beans.xsd &nbsp;
  9.         http://www.springframework.org/schema/context &nbsp;
  10.         http://www.springframework.org/schema/context/spring-context.xsd &nbsp;
  11.         http://www.springframework.org/schema/mvc &nbsp;
  12.         http://www.springframework.org/schema/mvc/spring-mvc.xsd>  
  13.   
  14.     <!– 自动扫描 –>  
  15.     <context:component-scan base-package=“com.sica”/>  
  16.     <!– 引入配置文件 –>  
  17.     <bean id=“propertyConfigurer” class=“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”  
  18.           p:location=“classpath:jdbc.properties”  
  19.           />  
  20.   
  21.     <!– 配置数据库连接池 –>  
  22.     <!– 初始化连接大小 –>  
  23.     <!– 连接池最大数量 –>  
  24.     <!– 连接池最大空闲 –>  
  25.     <!– 连接池最小空闲 –>  
  26.     <!– 获取连接最大等待时间 –>  
  27.     <bean id=“dataSource” class=“org.apache.commons.dbcp.BasicDataSource” destroy-method=“close”  
  28.           p:driverClassName= {jdbc.driver}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:url</span><span>=</span><span class="attribute-value">" {jdbc.url}”  
  29.           p:username= {jdbc.username}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:password</span><span>=</span><span class="attribute-value">" {jdbc.password}”  
  30.           p:initialSize= {jdbc.initialSize}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:maxActive</span><span>=</span><span class="attribute-value">" {jdbc.maxActive}”  
  31.           p:maxIdle= {jdbc.maxIdle}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">p:minIdle</span><span>=</span><span class="attribute-value">" {jdbc.minIdle}”  
  32.           p:maxWait=“${jdbc.maxWait}”  
  33.           />  
  34.   
  35.     <!– spring和MyBatis完美整合,不需要mybatis的配置映射文件 –>  
  36.     <bean id=“sqlSessionFactory” class=“org.mybatis.spring.SqlSessionFactoryBean” lazy-init=“default”  
  37.           p:dataSource-ref=“dataSource”  
  38.           p:mapperLocations=“classpath:com/sica/mapping/*.xml”  
  39.           />  
  40.   
  41.     <!– DAO接口所在包名,Spring会自动查找其下的类 –>  
  42.     <bean class=“org.mybatis.spring.mapper.MapperScannerConfigurer”  
  43.           p:basePackage=“com.sica.dao”  
  44.           p:sqlSessionFactoryBeanName=“sqlSessionFactory”  
  45.           />  
  46.   
  47.     <!– (事务管理)transaction manager, use JtaTransactionManager for global tx –>  
  48.     <bean id=“transactionManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”  
  49.           p:dataSource-ref=“dataSource”  
  50.           />  
  51. </beans></span>  


  
  
  1. <span style="font-family:Comic Sans MS;font-size:12px;"> <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- 自动扫描 -->
  3. <context:component-scan base-package="com.sica"/>
  4. <!-- 引入配置文件 -->
  5. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  6. p:location= "classpath:jdbc.properties"
  7. />
  8. <!-- 配置数据库连接池 -->
  9. <!-- 初始化连接大小 -->
  10. <!-- 连接池最大数量 -->
  11. <!-- 连接池最大空闲 -->
  12. <!-- 连接池最小空闲 -->
  13. <!-- 获取连接最大等待时间 -->
  14. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
  15. p:driverClassName= "${jdbc.driver}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:url</span>=<span class="hljs-string">"${jdbc.url}"
  16. p:username= "${jdbc.username}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="31"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:password</span>=<span class="hljs-string">"${jdbc.password}"
  17. p:initialSize= "${jdbc.initialSize}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:maxActive</span>=<span class="hljs-string">"${jdbc.maxActive}"
  18. p:maxIdle= "${jdbc.maxIdle}"</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-attr">p:minIdle</span>=<span class="hljs-string">"${jdbc.minIdle}"
  19. p:maxWait= "${jdbc.maxWait}"
  20. />
  21. <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
  22. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" lazy-init="default"
  23. p:dataSource-ref= "dataSource"
  24. p:mapperLocations= "classpath:com/sica/mapping/*.xml"
  25. />
  26. <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  27. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
  28. p:basePackage= "com.sica.dao"
  29. p:sqlSessionFactoryBeanName= "sqlSessionFactory"
  30. />
  31. <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
  32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  33. p:dataSource-ref= "dataSource"
  34. />
  35. </beans> </span>

最后,我用到的是 junit 进行的测试,测试代码如下。

GetUserTest

  1. <span style=“font-family:Comic Sans MS;font-size:12px;”>package com.sica.user;  
  2.   
  3. import com.alibaba.fastjson.JSON;  
  4. import com.sica.domain.User;  
  5. import com.sica.service.IUserService;  
  6. import org.junit.Test;  
  7. import org.junit.runner.RunWith;  
  8. import org.slf4j.Logger;  
  9. import org.slf4j.LoggerFactory;  
  10. import org.springframework.test.context.ContextConfiguration;  
  11. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  12.   
  13. import javax.annotation.Resource;  
  14. import java.util.List;  
  15.   
  16. / 
  17.   Created by xiang.li on 2015/2/1. 
  18.  /  
  19. @RunWith(SpringJUnit4ClassRunner.class)  
  20. @ContextConfiguration(locations = “classpath:spring-mybatis.xml”)  
  21. public class GetUserTest {  
  22.   
  23.     private static String UUID = “3”;  
  24.     @Resource  
  25.     private IUserService userService;  
  26.     private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);  
  27.   
  28.     @Test  
  29.     public void test() {  
  30.         User user = userService.getUserById(UUID);  
  31.         logger.info(JSON.toJSONString(user));  
  32.     }  
  33.   
  34.     / 
  35.       测试联合查询 
  36.      /  
  37.     @Test  
  38.     public void test2() {  
  39.         List<User> users = userService.queryUserList();  
  40.         logger.info(JSON.toJSONString(users));  
  41.     }  
  42. }</span>  


  
  
  1. <span style= "font-family:Comic Sans MS;font-size:12px;"> package com.sica.user;
  2. import com.alibaba.fastjson.JSON;
  3. import com.sica.domain.User;
  4. import com.sica.service.IUserService;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.test.context.ContextConfiguration;
  10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  11. import javax.annotation.Resource;
  12. import java.util.List;
  13. /
  14. * Created by xiang.li on 2015/2/1.
  15. /
  16. @RunWith(SpringJUnit4ClassRunner.class)
  17. @ContextConfiguration(locations = "classpath:spring-mybatis.xml")
  18. public class GetUserTest {
  19. private static String UUID = "3";
  20. @Resource
  21. private IUserService userService;
  22. private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);
  23. @Test
  24. public void test() {
  25. User user = userService.getUserById(UUID);
  26. logger.info(JSON.toJSONString(user));
  27. }
  28. /
  29. 测试联合查询
  30. */
  31. @Test
  32. public void test2() {
  33. List<User> users = userService.queryUserList();
  34. logger.info(JSON.toJSONString(users));
  35. }
  36. }</span>


测试结果




可以看到,所有的用户和用户对应的角色都全部查出来了,这说明,这次的测试很成功。


关于优化


对于优化嘛,我这里简单的提几点,大家可以考虑一下。首先,就是对表的设计,在设计表初期,不仅仅要考虑到数据库的规范性,还好考虑到所谓的业务,以及对性能的影响,比如,如果从规范性角度考虑的话,可能就会分多个表,但是如果从性能角度来考虑的话,庞大的数据量在多表联合查询的时候,相对于单表来说,就会慢很多,这时,如果字段不是很多的话,可以考虑冗余几个字段采用单表的设计。

其次嘛,就是在 sql 上下功夫了,对于联合查询,sql 的优化是很有必要的,到底是采用 INNER JOIN,还是采用 LEFT JOIN 亦或是 RIGHT JOIN 、OUTTER JOIN 等,都是要在满足业务需求之后,通过测试性能得出的结论。

再次嘛,就是在程序中调用的时候了,是采用懒加载,还是采用非懒加载的方式,这也算是一个因素吧,具体的还是要考虑业务的需要。

最后嘛,就要用到数据库的缓存了,或者在数据库与程序的中间再加一层缓存。不过,还是建议用好数据库本身自带的缓存功能。


结束语


最后的最后,还是要提醒大家,不要因为觉得简单就引不起足够的重视,否则你会由于一点点小的失误,而浪费大把大把的时间的。我就在这上边体会过,所以,这里奉劝大家,还是小心为妙啊@!


猜你喜欢

转载自blog.csdn.net/z_ssyy/article/details/81739806