mybatis_day02

1 lombok组件

1.1 概念

以前的Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toString;异常处理;I/O流的关闭操作等等,这些样板代码既没有技术含量,又影响着代码的美观,Lombok应运而生。

Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。

1.2 使用步骤

  • 安装步骤查看:https://www.cnblogs.com/boonya/p/10691466.html

1 下载lombok.jar,lombok.jar官方下载地址:https://projectlombok.org/download

2 :安装插件lombok.jar

image-20221229102536718

image-20221229102609678

image-20221229102619766

image-20221229102630221

3:安装后查看lombok是否安装成功

  • eclipse的安装目录下多个lombok,jar

image-20221229102753750

  • eclipse.ini文件中多了lombok的信息

image-20221229102835565

4 重启eclipse

5 实体类中使用lombok的注解

package com.zhiyou100.test03;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.experimental.Accessors;

@Data  //@Data :相当于@Setter + Getter + @ToString + @EqualsAndHashCode
@AllArgsConstructor  //创建全参数的构造方法
@NoArgsConstructor  //创建无参数的构造方法
@Accessors(chain=true)         //set方法的返回值是当前对象::实现方法链的调用
public class Teacher implements Serializable{
	
	private Integer tid;
	@NonNull  //判断属性是否为null 为空报错
	private String tname;
	
	private String tpwd;
	
}

6 测试

package com.zhiyou100.test03;

public class Test02 {
	public static void main(String[] args) {
		Teacher t1=new Teacher();
		Teacher t2=new Teacher(11,"韩梅梅","123");
		System.out.println(t2);
		System.out.println(t2.getTname()+"::"+t2.getTpwd());
		t2.setTid(111);
		t2.setTname("憨憨");
		t2.setTid(1111).setTname("韩非子").getTid();//方法链
	}

}

7 lombok的常用注解

image-20221229103010390

2 多参数时解决方法

2.0 单值参数时:

1 占位符名字随意
2 parameterType可以省略
<!-- 根据id查询:单值参数:::当一个参数时 占位符的名字可以随意 -->
<select id="getBySid01"  parameterType="int" resultType="Student">
    select * from student where sid=#{s}   
</select>
<!-- 根据id查询:parameterType参数类型是可以省略的 -->
<select id="getBySid02"   resultType="Student">
    select * from student where sid=#{s}   
</select>
	//<select id="getBySid01"  parameterType="int" resultType="Student">
	public Student getBySid01(int sid);
	public Student getBySid02(int sid);

2.1 多值参数:方案1:使用对象接受数据

2.2 多值参数:方案2:使用map存储参数

2.3 多值参数:方案3:在mapper映射文件中 用索引表示占位符

2.4 多值参数:方案4:形参上使用注解@Param(value) value值就是占位符的名字

//<!-- 解决方案1:把参数定义为对象::占位符的名字就是对象的属性名 -->
	//<select id="getByCondition01"   parameterType="Student"  resultType="Student">
	public List<Student> getByCondition01(Student stu);
	
	//<!-- 解决方案2:把参数定义为Map::占位符的名字就是键的名字 -->
	//<select id="getByCondition02"   parameterType="java.util.Map"  resultType="Student">
	public List<Student> getByCondition02(Map<String,Object> map);
	
	//<!-- 解决方案3:多个参数:占位符用索引表示::从0开始 -->
//	<select id="getByCondition03"   resultType="Student">
//	      select * from student where sex=#{0} and sdy=#{1} and score &gt; #{2}   
//	</select>
	public List<Student> getByCondition03(String sex,boolean sdy,float score);
	
//	<!-- 解决方案4:使用注解@Param::属性与占位符名一致即可 -->
//	<select id="getByCondition04"   resultType="Student">
//       select * from student where sex=#{se} and sdy=#{sd} and score &gt; #{sc}   
//  </select>
	public List<Student> getByCondition04(@Param("se") String sex, @Param("sd")boolean sdy,@Param("sc")float score);
  
  <!-- 根据性别 最低分 是否党员作为条件进行查询 -->
  <!-- 解决方案1:把参数定义为对象::占位符的名字就是对象的属性名 -->
  <select id="getByCondition01"   parameterType="Student"  resultType="Student">
     select * from student where sex=#{sex} and sdy=#{sdy} and score &gt; #{score}   
  </select>
  
  <!-- 解决方案2:把参数定义为Map::占位符的名字就是键的名字 -->
  <select id="getByCondition02"   parameterType="java.util.Map"  resultType="Student">
       select * from student where sex=#{se} and sdy=#{dy} and score &gt; #{sc}   
  </select>
  
  <!-- 解决方案3:多个参数:占位符用索引表示::从0开始 -->
  <select id="getByCondition03"   resultType="Student">
       select * from student where sex=#{0} and sdy=#{1} and score &gt; #{2}   
  </select>
  
   <!-- 解决方案4:使用注解@Param::属性与占位符名一致即可 -->
   <select id="getByCondition04"   resultType="Student">
       select * from student where sex=#{se} and sdy=#{sd} and score &gt; #{sc}   
  </select>

3 当结果集与对象属性不一致时

3.0 测试不一致时的结果

  • 表结构

image-20221229151113460

image-20221229151133343

  • sql映射文件
  <!-- 结果集名和属性名不一致::获取的对象只有属性名在结果集中存储的属性才有值  不一致的没有值 -->
  <!-- 获取所有:getAll01:::[Student(id=null, name=null, sex=女, score=12.0, birth=null, dy=null, photo=null),...-->
  <select id="getAll01" resultType="Student">
       select * from student
  </select>
  • 结果::只有属性名和列名一致的才有值

image-20221229151251560

3.1 解决方案1:给结果集的列起别名 别名和属性名一致

 <!--  结果集名和属性名不一致 解决方案1:给结果集的列起别名:别名与属性名一致即可-->
  <select id="getAll02" resultType="Student">
       select sid id,sname name,sex,score,sdy dy,sbirth birth,sphoto photo from student
  </select>
  • 结果

image-20221229151417647

3.2 解决方案2:定义resultMap 指定结果集列与对象属性的对应关系

<!--  结果集名和属性名不一致 解决方案2:使用resultMap指定结果集列与对象属性的对应关系-->
<resultMap type="Student" id="stuMap1">  <!-- id为select中resultMap属性的值:::type为最终每行要解析成的对象类型-->
    <id  column="sid" property="id"/>  <!-- 指定主键列的对应:column是列名 property是属性名 -->
    <result column="sname" property="name"/>  <!-- 非主键列 用result标签指定对应关系 -->
    <!-- 列名和属性名一致的可以省略 -->
    <!-- <result column="sex" property="sex"/> 非主键列 用result标签指定对应关系 -->
    <result column="sdy" property="dy"/>  <!-- 非主键列 用result标签指定对应关系 -->
    <result column="sbirth" property="birth"/>  <!-- 非主键列 用result标签指定对应关系 -->
    <!-- 列名和属性名一致的可以省略 -->
    <!-- <result column="score" property="score"/>  非主键列 用result标签指定对应关系 -->
    <result column="sphoto" property="photo"/>  <!-- 非主键列 用result标签指定对应关系 -->
</resultMap>
<select id="getAll03" resultMap="stuMap1">
    select * from student
</select>
  • 结果

image-20221229151516488

4 表与表之间的关系之:n对1

4.0 数据库准备

-- 1对n 或者n对1的解决方案::在n这方定义外键来指向1这方的主键
-- 一个学生对应一个老师 一个老师有多个学生
CREATE TABLE student(
   sid INT PRIMARY KEY AUTO_INCREMENT,
   sname VARCHAR(100),
   sex CHAR(1)
);
ALTER TABLE student ADD stid INT;
ALTER TABLE student ADD CONSTRAINT fk_st FOREIGN KEY(stid) REFERENCES teacher(tid);
CREATE TABLE teacher(
   tid INT PRIMARY KEY AUTO_INCREMENT,
   tname VARCHAR(100),
   tage INT
);
INSERT INTO teacher VALUES(NULL,
                           SUBSTRING(REPLACE(UUID(),'-',''),1,10),
                           TRUNCATE(RAND()*10+30,0));
SELECT * FROM teacher;
UPDATE teacher SET tname=CONCAT(tname,"老师");
INSERT INTO student VALUES(NULL,
                           CONCAT(SUBSTRING(REPLACE(UUID(),'-',''),1,10),"学生"),
                           IF(RAND()>0.5,'男','女'),
                           TRUNCATE(RAND()*7+1,0));
SELECT * FROM student;   

4.1 不处理时:n对1:

 <!-- 当不处理时:查询学生其teacher属性是null:::结果集中列是stid 但对象的属性是teacher::不可能自动赋值 -->
  <select id="getAll1" resultType="Student">
        select * from student
  </select>

image-20221230100217337

4.2 n对1解决方案1::通过子查询实现

image-20221230100032662

  • 子查询时 总的查询次数是1+n次

image-20221230100437750

4.3 n对1解决方案2::通过连接查询实现

image-20221230101415916

  • 连接查询时:只执行了1次sql查询

image-20221230101628591

5 表与表之间的关系之:1对n

5.0 不处理时:1对n

老师的stuList属性是没有值
<!-- 当不处理时: 结果集中没有任何Student的信息::当前Teacher的stuList属性肯定是没有值-->
  <select id="getAll1" resultType="Teacher">
        select * from Teacher
  </select>

image-20221230103446775

5.1 1对n解决方案1::通过子查询实现

image-20221230103414796

  • 子查询:共执行1+n此查询

image-20221230103614803

5.2 1对n解决方案2::通过连接查询实现

image-20221230104310569

  • 连接查询 最终执行查询次数为1

image-20221230104429478

6 表与表之间的关系之:1对1

其实就是两个n对1

6.0 设置表结构

-- 一对一的解决方案:按先后顺序或者主次关系 划分两个一 一个为主表 一个为从表
--                   把从表的主键同时定义为外键 来引用主表的主键
-- 如一个学校对应一个校长::现有学校再有校长::学校为主表 校长为从表
-- 如一个丈夫对应一个妻子::丈夫为主 妻子为次::丈夫是主表 妻子是从表
CREATE TABLE husband(
   hid INT PRIMARY KEY AUTO_INCREMENT,
   hname VARCHAR(100),
   hsalary FLOAT(9,1)
);
CREATE TABLE wife(
   wid INT PRIMARY KEY,
   wname VARCHAR(100),
   wage INT,
   /*把从表的主键列 同时定义为外键 来引用主表的主键*/
   CONSTRAINT fk_h_w FOREIGN KEY(wid) REFERENCES husband(hid)
);
INSERT  INTO husband VALUES(11,"张三",1000);
INSERT  INTO husband VALUES(12,"李四",11000);
INSERT  INTO husband VALUES(13,"王五",122000);
INSERT  INTO husband VALUES(14,"赵六",1333000);
INSERT  INTO  wife VALUES(14,"赵太太",20);
INSERT  INTO  wife VALUES(13,"王太太",25);
INSERT  INTO  wife VALUES(12,"李太太",50);

6.1 1对1解决方案1:子查询

<!-- 当不处理时:查询丈夫 其wife属性是肯定是null -->
<select id="getAll1" resultType="Husband">
    select * from husband
</select>
<!-- 1对1解决方案:和n对1的解决方案完全相同 -->
<!-- 1对1解决方案:子查询 -->
<resultMap type="Husband" id="husbandMap2">
    <id column="hid" property="hid"/>
    <result column="hname" property="hname"/>
    <result column="hsalary" property="hsalary"/>
    <!-- 根据hid查询wife表 获取一个Wife对象赋值给当前对象的wife属性 -->
    <!-- 属性property:指定要给当前对象的wife属性赋值 -->
    <!-- 属性column:指定要使用结果集的hid列的值进行子查询getOneWifeByHid -->
    <!-- 属性select::指定要进行子查询的select标签的id -->
    <association property="wife"   column="hid" select="getOneWifeByHid"/>
</resultMap>
<select id="getOneWifeByHid" resultType="Wife">
    select * from wife where wid=#{hid}
</select>
<select id="getAll2" resultMap="husbandMap2">
    select * from husband
</select>

6.2 1对1解决方案2:路径查询

<!-- 1对1解决方案:连接查询-->
<resultMap type="Husband" id="husbandMap3">
    <!-- 给Husband的直接属性赋值 -->
    <id column="hid" property="hid"/>
    <result column="hname" property="hname"/>
    <result column="hsalary" property="hsalary"/>
    <!-- 把结果集中wife表的列封装为Wife对象 赋值给当前对象的wife属性-->
    <association property="wife" javaType="Wife">
        <id column="wid" property="wid"/>
        <result column="wname" property="wname"/>
        <result column="wage" property="wage"/>
    </association>
</resultMap>
<select id="getAll3" resultMap="husbandMap3">
    select * from husband h left join wife w on h.hid=w.wid
</select>

7 表与表之间的关系之:n对n

7.1 表设计

-- n对n::一个用户可以买多装商品  一种商品可以被多个用户买
--         一个学生可以选多门课程  一门课程可以被多个学生选
-- 表设计:::再定义一个关系表:关系表中定义联合主键 联合主键都可以为外键 分别引用两个主表的主键

CREATE TABLE stu(
  sid INT PRIMARY KEY AUTO_INCREMENT,
  sname VARCHAR(100),
  sex CHAR(1)
);
INSERT INTO stu VALUES(NULL,SUBSTRING(REPLACE(UUID(),'-',''),1,10),IF(RAND()>0.5,'男','女'));
CREATE TABLE ke_cheng(
  kid INT PRIMARY KEY AUTO_INCREMENT,
  kname VARCHAR(100),
  kshow VARCHAR(100)
);
INSERT INTO ke_cheng VALUES(1001,"语文","表达阅读理解交流能力");
INSERT INTO ke_cheng VALUES(1002,"历史","上下五千年");
INSERT INTO ke_cheng VALUES(1003,"化学","元素周期表");
INSERT INTO ke_cheng VALUES(1004,"物理","力电磁");
INSERT INTO ke_cheng VALUES(1005,"数学","所有科学学科的基础");
-- 定义关系表
CREATE TABLE stu_ke_cheng(
  gsid INT,
  gkid INT,
  PRIMARY KEY(gsid,gkid),
  CONSTRAINT fk_s_1 FOREIGN KEY(gsid) REFERENCES stu(sid),
  CONSTRAINT fk_k_2 FOREIGN KEY(gkid) REFERENCES ke_cheng(kid)
);
INSERT INTO stu_ke_cheng VALUES(
   TRUNCATE(RAND()*9+1,0),
   TRUNCATE(RAND()*5+1001,0)
);
SELECT * FROM stu_ke_cheng;

7.2 n对n解决方案1:子查询

<!-- 当不处理时:查询Stu 其kcList属性是肯定是null -->
<select id="getAll1" resultType="Stu">
    select * from stu
</select>

<!-- 解决n对n的方案1:子查询 -->
<resultMap type="Stu" id="stuMap2">
    <!-- 把结果集中stu的列 封装为Stu对象 -->
    <id column="sid" property="sid"/>
    <result column="sname" property="sname"/>
    <result column="sex" property="sex"/>
    <!-- 使用sid的值 对stu_ke_cheng关系表和ke_cheng 表进行子查询 获取的信息封装成KeCheng对象 赋值给kcList -->
    <collection property="kcList" ofType="KeCheng" select="getAllKeChengBySid" column="sid"/>
</resultMap>
<select id="getAllKeChengBySid" resultType="KeCheng">
    select * from stu_ke_cheng skc,ke_cheng kc where skc.gsid=#{sid} and skc.gkid=kc.kid
</select>
<select id="getAll2" resultMap="stuMap2">
    select * from stu
</select>

7.3 n对n解决方案2:连接查询

<!-- 解决n对n的方案2:连接查询-->
  <resultMap type="Stu" id="stuMap3">
     <!-- 把结果集中stu的列 封装为Stu对象 -->
     <id column="sid" property="sid"/>
     <result column="sname" property="sname"/>
     <result column="sex" property="sex"/>
     <!-- 把结果集中kecheng的列封装为KeCheng对象 赋值给当前对象的kcList属性 -->
     <collection property="kcList" ofType="KeCheng">
         <id column="kid" property="kid"/>
         <result column="kname" property="kname"/>
         <result column="kshow" property="kshow"/>
     </collection>
  </resultMap>
  <select id="getAll3" resultMap="stuMap3">
        select * from stu s left join stu_ke_cheng skc on s.sid=skc.gsid
                            left join ke_cheng kc on kc.kid=skc.gkid
  </select>
  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值