Mybatis2笔记

目录

1、解决属性名和字段名不一致的问题

2、日志

2.1、日志工厂

2.2、STDOUT_LOGGING标准日志输出,在设置中设置

 2.3、Log4J

3、分页

3.1、使用limit分页(物理分页)

3.2、RowBounds分页

3.3、Mybatis分页插件 PageHelper

4、使用注解开发

4.1、注解在接口上的实现

4.2、在核心配置文件中绑定接口

4.3、测试

5、Mybatis获取参数的两种方式

5.1、单个字面量类型的参数

5.2、多个字面量类型的参数

关于@Param()注解

6、Mybatis详细执行流程

7、Lombok

怎么用?

8、多对一

8.1、啥意思?

8.2、测试环境搭建

8.3、按照查询嵌套处理(类似于子查询)

8.4、按照结果嵌套处理(更快)

9、一对多处理

9.1、按照查询嵌套处理(子查询)

9.2、按照结果嵌套处理(更快推荐)

小结:

注意:


1、解决属性名和字段名不一致的问题

解决方法:

1、起别名

select * from mybatis.user
select id,name,pwd as passwd from mybatis.user

2、resultMap

结果集映射

id     name    pwd

id     name    passwd

<!--结果集映射-->
    <resultMap id="UserMap" type="User">
    <!--column 对应数据库里的字段,property 对应实体类里的属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="pword"/>
    </resultMap>
    <select id="getUserList" resultMap="UserMap">
        select * from mybatis.user
    </select>

resultMap 元素是 MyBatis 中最重要最强大的元素。

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

2、日志

2.1、日志工厂

如果一个数据库操作出现了异常,我们需要排错,日志就是最好的帮手

SLF4J 

LOG4J (掌握)

LOG4J2 

JDK_LOGGING 

COMMONS_LOGGING 

STDOUT_LOGGING(掌握) 

NO_LOGGING

2.2、STDOUT_LOGGING标准日志输出,在设置中设置

<!--设置日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

 2.3、Log4J

用前得导包

啥是LOG4J?

  • Log4j是 Apache 的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是 控制台 、文件、 GUI 组件,甚至是套接口服务器、 NT 的事件记录器、 UNIX Syslog 守护进程 等
  • 我们也可以控制每一条日志的输出格式;
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

1、先导log4j的包

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2、

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/zhang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

简单的使用

1、在要使用log4j的类中,导入包import org.apache.log4j.Logger;

2、日志对象,参数为当前类的class

static Logger logger = Logger.getLogger(UserDaoTest.class); 
@Test
    public void log4jTest(){
        logger.info("info:进入log4j");
        logger.debug("info:进入log4j");
        logger.error("info:进入log4j");
    }

输出的log文件内容:

[INFO][22-10-08][com.zhang.dao.UserDaoTest]info:进入log4j
[DEBUG][22-10-08][com.zhang.dao.UserDaoTest]info:进入log4j
[ERROR][22-10-08][com.zhang.dao.UserDaoTest]info:进入log4j

3、分页

为什么分页?

减少数据的处理量

3.1、使用limit分页(物理分页)

select * from user limit startIndex,pageSize;
select * from user limit 3;[0,n-1]
select * from user limit 0,2;每一页显示两个从第0个人开始
使用Mybatis实现分页,核心SQL

接口:

List<User> getUserByLimit(Map<String,Integer> map);

Mapper.xml:

  <select id="getUserByLimit" resultMap="UserMap" parameterType="map">
        select * from mybatis.user limit #{startIndex},#{pageSize}
    </select>

测试:

@Test
    public void Timit(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        HashMap<String, Integer> map = new HashMap<>();
        map.put("startIndex",0);
        map.put("pageSize",2);
        List<User> userByLimit = mapper.getUserByLimit(map);
        for (User user : userByLimit) {
            System.out.println(user);
        }
        sqlSession.close();
    }

3.2、RowBounds分页

不使用SQL分页

1、接口

//分页二
     List<User> getUserByRowBounds();

2、mapper.xml

<!--分页2-->
<select id="getUserByRowBounds" resultMap="UserMap">
     select *from mybatis.user
</select>

3、测试

@Test
    public void getUserByRowBounds(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //通过RowBounds实现分页
        RowBounds rowBounds = new RowBounds(1, 2);

        //通过Java代码层面进行分页(不太建议)
        List<User> User = sqlSession.selectList("com.zhang.dao.UserMapper.getUserByRowBounds",null,rowBounds);
        for (com.zhang.pojo.User user : User) {
            System.out.println(user);
        }

        sqlSession.close();
    }

3.3、Mybatis分页插件 PageHelper

官方网址:https://pagehelper.github.io/

4、使用注解开发

关于接口的理解。

接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。

接口的本身反映了系统设计人员对系统的抽象理解。

接口应有两类:第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);

第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);

一个体有可能有多个抽象面。

4.1、注解在接口上的实现

 @Select("select id,name,pwd as passwd from mybatis.user")
 List<User> getUsers();
 //方法存在多个参数时需要使用@Param注解,引用对象不需要用@Param,像User之类的
 @Select("select id,name,pwd as passwd from mybatis.user where id = #{id}")
 User getUserById(@Param("id") int id);

 @Insert("insert into user(id, name, pwd) VALUES (#{id},#{name},#{passwd})")
 int add(User user);

 @Update("update user set name = #{name}, pwd = #{passwd} where id = #{id}")
 int updateUser(User user);

 @Delete("delete from user where id = #{uid}")
 int deleteUser(@Param("uid") int id);

4.2、在核心配置文件中绑定接口

 <mappers>
        <mapper class="com.zhang.dao.UserMapper"/>
 </mappers>

4.3、测试

@Test
public void Test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.getUsers();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();

    }
 @Test
    public void add(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int user = mapper.add(new User(7,"iiii","9999444"));
        System.out.println(user);
        sqlSession.close();
    }

本质:反射机制的实现

底层是动态代理

5、Mybatis获取参数的两种方式

#{}和${}

5.1、单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型

可以使用${}和#{}以任意的名称获取参数的值,${}需要手动加单引号

5.2、多个字面量类型的参数

如果mapper接口中的方法参数为多个时

此时Mybatis会自动将这些参数放在一个map集合中,以arg1、arg2..为键,以参数为值;以param1,param2...为键,以参数为值;因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值,${}需要手动加单引号

关于@Param()注解

  • 基本类型的参数或者String类型的,需要加上
  • 引用类型不用加   像User实体类这样的
  • 如果只有一个基本类型的话可以忽略,但还是建议加上
  • 我们在SQL引用的就是这里的@Param()中设定的属性名

6、Mybatis详细执行流程

7、Lombok

Lombok是一个Java库,能自动插入编辑器并构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或eques方法,同时可以自动化日志变量。

简而言之:Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。

怎么用?

1、在idea里安装Lombok插件

2、导入projectlombok的jar包

 <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>

3、有哪些注解?

@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor,  有参

@RequiredArgsConstructor and @NoArgsConstructor  无参
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data       get,set,toString,hasCode,equals ,无参构造
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows

8、多对一

8.1、啥意思?

  • 多个学生对应一个老师
  • 对于学生而言,是关联  多个学生关联一个老师
  • 对老师而言,是集合,一个老师对应多个学生

CREATE TABLE `teacher` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, '张老师'); 

CREATE TABLE `student` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `tid` INT(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fktid` (`tid`),
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

8.2、测试环境搭建

  1. 导入lombok,自己手写实体类方法也行
  2. 新建实体类Teacher、Student
  3. 创建Mapper接口
  4. 创建mapper.xml文件
  5. 在核心配置文件中绑定mapper接口或文件
  6. 测试能否成功

8.3、按照查询嵌套处理(类似于子查询)

<!--
1、查询所有学生信息
2、根据查询出来的学生的tid,寻找对应的老师
-->
<select id="getStudent" resultMap="StudentTeacher">
    select *from student
</select>
 <resultMap id="StudentTeacher" type="Student">
     <result property="id" column="id"/>
     <result property="name" column="name"/>
<!--复杂的属性,我们需要单独处理-->
     <!--association  对象用-->
     <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
     <!--collection  集合用-->
<!--     <collection property=""/>-->
 </resultMap>
    <select id="getTeacher" resultType="Teacher">
        select *from teacher
    </select>

8.4、按照结果嵌套处理(更快)

<!--方法二:根据结果嵌套处理 (更快)-->
<select id="getStudent2" resultMap="StudentTeacher2">
    select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid = t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

9、一对多处理

搭建完环境后对实体类做些修改

public class Teacher {
    private int id;
    private String name;
    //一个老师对应多个学生
    private List<Student> students;
}
public class Student {
    private int id;
    private String name;
    //一个学生对应一个老师
    private int tid;
}

9.1、按照查询嵌套处理(子查询)

 <!--方式二:根据查询嵌套(子查询)-->
    <select id="getTeacher2" resultMap="TeacherStudent2">
        select *from mybatis.teacher where id=#{tid}
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
        <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacher" column="id"/>
    </resultMap>
    <select id="getStudentByTeacher" resultType="Student">
        select *from mybatis.student where tid = #{tid}
    </select>

9.2、按照结果嵌套处理(更快推荐)

<!--方式一:根据结果嵌套查询-->
<select id="getTeacherStudent" resultMap="TeacherStudent">
    select s.id sid,s.name sname,t.name tname,t.id tid
    from mybatis.student s,mybatis.teacher t
    where s.tid = t.id and t.id = #{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
    <!--javaType指定属性类型
    像集合中的泛型信息,需要使用ofType获取
    -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

小结:

  1. 关联  association  多对一
  2. 集合  collection   一对多
  3. javaType  和  ofType

javaType 用来指定实体类中属性的类型

ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型

注意:

  • 保证SQL的可读性,尽量通俗易懂
  • 注意一对多和多对一中,属性和字段的问题
  • 如果问题不好排错,可以使用日志,建议使用Log4j

需要研究的:Mysql引擎、InnoDB底层原理、索引、索引优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fiercezm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值