MyBatis基础——学习笔记

目录

1.概念:

2.使用MyBatis的流程

2.1.导入Mysql和MyBatis所依赖的jar包(中途也会根据需要导入其他jar包)

2.2.在resources中创建mybatis.xml配置文件(内容复制粘贴即可)

 2.3.创建数据库和表并添加内容。

 2.4.创建实体类

2.5.在resources中创建mybatis和数据库的映射文件(复制即可)

2.6将映射文件注册到配置文件中

 2.7测试Mybatis

3.使用mybatis完成对数据库的crud(增删改查)

3.1在映射文件中写sql语句

3.2测试类

4.优化MaBatis

4.1.为实体类起别名

4.2.添加sql日志

5.企业开发模式

5.1.创建一个dao接口并定义自己需要的方法(是接口不是类)。

5.2.创建并编写映射文件

5.3测试

6.传递多个参数的方法

6.1.方式一

6.2.方式二

7.添加时返回递增的主键值

8.解决表的字段名与实体类的属性名不一致的情况

8.1.方式一:为查询的列起别名,而别名和属性名一致。

 8.2.方式二:使用resultMap完成列和属性之间的映射关系。

9.动态sql

9.1.什么时动态sql

9.2.动态sql的标签有哪些

9.3.if标签——单条件判断

9.4.choose标签——多条件分支判断

9.5.where标签(辅助标签)

9.6.set标签

9.7.foreach标签

9.8.sql片段

10.mybatis映射文件处理特殊字符的方法

10.1使用转义符

10.2.使用

11.mybatis完成模糊查询

11.1使用字符串拼接完成

11.2.使用${}

12.连表查询

13.分页查询(pageHelper)

13.1.回顾分页的sql语句:

13.2.导入pagehelper 依赖的jar 包

13.3.mybatis中设置pageHelper的拦截器

 13.4.测试并使用pagehelper

 13.5.pagehelper的作用:

13.6.pagehelper的原理

14.mybatis的代码生成器——generator

14.1.作用

14.2.使用流程

15.mybatis的缓存

 15.1.缓存的好处

 15.2.什么样的数据适合/不适合放入缓存中

 15.3.mybatis的缓存有两种

 15.4.演示一级缓存

 15.4.1.测试重新开启一个session时一级缓存是否有效

          15.5.演示二级缓存


1.概念:

MyBatis 是一款优秀的持久层Dao框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Java实体类)映射成数据库中的记录.

使用MyBatis的好处:可以简化jdbc的操作以及占位符赋值以及查询结果集的封装。

2.使用MyBatis的流程

2.1.导入Mysql和MyBatis所依赖的jar包(中途也会根据需要导入其他jar包)



    4.0.0

    com.pgx
    mybatis03
    1.0-SNAPSHOT

    
        8
        8
    
    
        
            mysql
            mysql-connector-java
            8.0.22
        
        
            org.mybatis
            mybatis
            3.4.6
        
        
            log4j
            log4j
            1.2.17
        
        
            org.projectlombok
            lombok
            1.18.24
        
        
            junit
            junit
            4.12
        
    

2.2.在resources中创建mybatis.xml配置文件(内容复制粘贴即可)




    
        
            
            
            
                
                
                
                
            
        
    

 2.3.创建数据库和表并添加内容。

DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user`  (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `realname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`userid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, 'admin', '管理员');
INSERT INTO `tb_user` VALUES (2, 'lm', '黎明');
INSERT INTO `tb_user` VALUES (3, 'ldh', '刘德华');
INSERT INTO `tb_user` VALUES (4, 'zxy', '张学友');
INSERT INTO `tb_user` VALUES (5, 'gfc', '郭富城');

 2.4.创建实体类

package com.pgx.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//使用lombok插件添加注解生成get,set方法和有参构造,无参构造,以及重写了toString方法
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    protected int id;
    protected String username;
    protected String password;
}

2.5.在resources中创建mybatis和数据库的映射文件(复制即可)





    
    

2.6将映射文件注册到配置文件中

MyBatis基础——学习笔记_第1张图片

 2.7测试Mybatis

public class Test01 {
    public static void main(String[] args) throws Exception {
        //1.读取mybatis配置文件的内容----未来不需要写tomcat 解析配置文件
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        //2. 获取SqlSessionFactory对象
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);

        //3. 获取SqlSession对象----封装了对数据库操作的各种方法
        SqlSession session=factory.openSession();

        //调用查询一个结果的接口
        //String statement, 命名空间.id----指向mybatis配置文件中sql标签中的id
        // Object parameter 需要实参(想要查询的id)
        User user = session.selectOne("qy151.user.findById", 2);
        System.out.println(user);
        //4.关闭
        session.close();

    }
}

3.使用mybatis完成对数据库的crud(增删改查)

3.1在映射文件中写sql语句





    
    

    
    
        insert into tb_user(username,realname) values(#{username},#{realname})
    

    
    
        delete from tb_user where userid=#{id}
    

    
    
         update tb_user set username=#{username},realname=#{realname} where userid=#{userid}
    

    
    

3.2测试类

package com.test;

import com.ykq.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.Reader;
import java.util.List;


public class Test01 {
    //查询所有
    @Test
    public void testFindAll()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);
        SqlSession session=factory.openSession();
        List users = session.selectList("qy151.user.findAll");
        System.out.println(users);
        session.commit();//必须提交
        session.close();
    }

    //修改
    @Test
    public void testUpdate()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);
        SqlSession session=factory.openSession();
        User user=new User(8,"lm","黎明");
        int row = session.update("qy151.user.update", user);
        System.out.println(row);

        session.commit();//必须提交
        session.close();
    }

    //删除
    @Test
    public void testDelete()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);
        SqlSession session=factory.openSession();

        int row = session.delete("qy151.user.delete", 1);
        System.out.println(row);

        session.commit();//必须提交
        session.close();
    }

    //测试添加
    @Test
    public void testAdd() throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);
        SqlSession session=factory.openSession();
        User user=new User();
//        user.setUsername("lmtb");
//        user.setRealname("黎明他爸");
        int row = session.insert("qy151.user.add", user);
        System.out.println(row);
        session.commit();//必须提交
        session.close();
    }
}

4.优化MaBatis

4.1.为实体类起别名

MyBatis基础——学习笔记_第2张图片

 作用:在映射文件sql语句查询标签中定义返回类型的时候省略实体类的路径,直接写别名。

    //这里的User就是使用了别名    
    

4.2.添加sql日志

1).导入log4j依赖

 		
        
            log4j
            log4j
            1.2.17
        

2).在resources中创建log4j.properties文件(文件名必须是这个,并将下面的代码写进去,复制即可)

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

作用:在控制台打印你的sql语句的操作,便于查看或纠正sql语句错误

MyBatis基础——学习笔记_第3张图片

5.企业开发模式

思考: 我们之前使用SqlSession封装的一些方法可以完成crud操作,但是SqlSession封装的方法,传递的参数statement, 传递占位符的参数只能传递一个。而且他的方法名称都是固定。而真实在开发环境下我们不使用SqlSession封装的方法,而是习惯自己定义方法,自己调用自己的方法。

步骤:

5.1.创建一个dao接口并定义自己需要的方法(是接口不是类)。

package com.pgx.dao;

import com.pgx.entity.User;


import java.util.List;

public interface UserDao {
    //根据id查询莫一条记录的方法
    public User findOne(int id);
    //查询所有记录的方法
    public List findAll();
    //添加记录的方法
    public int insert(User user);
    //根据id修改记录的方法
    public int edit(User user);
    //根据id删除记录的方法
    public int delete(int id);

}

5.2.创建并编写映射文件





    
        insert into user values(null,#{username},#{password})
    
    
        update user set username=#{username},password=#{password} where id=#{id}
    
    
        delete from user where id=#{id}
    

    

    
    

注意:

1.这时的namespace命名空间必须时你的Dao所在的位置。

 2.标签里的id的值必须时Dao中定义的方法名,当你调用Dao中的方法时它会根据你的命名空间和   标签id判断执行哪一个Sql语句

5.3测试

public class Text {
    //测试根据id查询某一条记录
    @Test
    public void text01()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        //获取相应接口的代理对象
        UserDao userdao = session.getMapper(UserDao.class);
        //通过该对象调用其中的方法,并根据方法穿参(后面的方法同理)
        User user = userdao.findOne(1);

        System.out.println(user);

        session.close();
    }
    //测试查询所有记录的方法
    @Test
    public void text02()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        UserDao userdao = session.getMapper(UserDao.class);
        List list = userdao.findAll();

        System.out.println(list);

        session.close();
    }
    //测试添加的方法
    @Test
    public void text03()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        UserDao userdao = session.getMapper(UserDao.class);
        User user = new User();
        user.setUsername("女枪");
        user.setPassword("4800");
        int row = userdao.insert(user);
        //返回了主键id的值
        System.out.println(user);

        System.out.println(row);

        session.commit();
        session.close();

    }
    //测试修改的方法
    @Test
    public void text04()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        UserDao userdao = session.getMapper(UserDao.class);
        User user = new User(2,"卡沙","6300");
        int row = userdao.edit(user);

        System.out.println(row);

        session.commit();
        session.close();
    }
    //测试删除的方法
    @Test
    public void text05()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        UserDao userdao = session.getMapper(UserDao.class);
        int row = userdao.delete(8);

        System.out.println(row);

        session.commit();
        session.close();
    }
}

6.传递多个参数的方法

思考:为什么传递多个参数时不可以直接使用实例类的属性名作为参数?

因为mybatis在我们传递多个参数时,会帮我们将传入的参数名封装成param1,param2..........

6.1.方式一

方法:

 public User login( String username, String password);

sql语句:

    

6.2.方式二

方法:

//通过@param为参数起别名,其中的内容就可以直接写在sql里的#{}中 
public User login(@Param("username") String username, @Param("password") String password);

sql语句:

    

7.添加时返回递增的主键值

     
    
        insert into user values(null,#{username},#{password})
    

测试:

MyBatis基础——学习笔记_第4张图片

8.解决表的字段名与实体类的属性名不一致的情况

8.1.方式一:为查询的列起别名,而别名和属性名一致。

    

 8.2.方式二:使用resultMap完成列和属性之间的映射关系。


    
         
         
         
         
         
    

    
    

9.动态sql

9.1.什么时动态sql

select * from 表名 where name=#{name}

//当 name!=null时sql语句为

select * from 表名 where name=#{name}

//当 name=null 时sql语句为

select * from 表名

9.2.动态sql的标签有哪些

MyBatis基础——学习笔记_第5张图片

动态sql的作用:

  简而言之就是可以通过一条sql语句设置动态后满足多种查询需求

9.3.if标签——单条件判断

方法

//如果name不为null则按照name查询 如果为null则查询所有
    public List findByCondition(@Param("name")String name,@Param("money") Double money);

sql语句:

 两个条件都满足时两个都作为条件进行查询

9.4.choose标签——多条件分支判断

方法:

 //如果name不为null则按照name查询 如果为null则查询所有
    public List findByCondition02(@Param("name")String name,@Param("money") Double money);

sql语句:

只会选择满足其中的一个条件作为查询条件,如果都满足,也只会选择第一个满足的条件作为查询条件,如果都不满足 会使用otherwise中的条件作为查询条件。类似与Java中的switch(case,fainly) 

9.5.where标签(辅助标签)

可以看到上面sql语句中,存在 where 1=1 ,是用于当条件都不满足时保证sql语句的合法

where标签的作用:可以自动为你添加where关键字,并且可以帮你去除第一个and |or

 

9.6.set标签

使用场景:一般配合if标签使用,修改时修改的内容如果输入空,则不会修改原本的内容。该标签可以帮我们生成set关键字,并且可以去除最后一个逗号。

方法:

public int update(User user);

sql:

    
        update tbl_user02
        
            
                name = #{name},
            
            
                pwd = #{pwd},
            
            
                email = #{email},
            
        
        where id = #{id}
    

9.7.foreach标签

使用场景:批量查询,删除,添加。

9.7.1.查询

方法:

public List findByids(int[] ary);

sql:


    

9.7.2.删除

方法:

public int batchDelete(int[] ary);

sql:

    
         delete from account where  id in
        
            #{id}
        
    

9.7.3.添加

方法:

public int saveBatch(List list);

sql:

    //批量添加sql语句语法:
      insert into account(属性1,属性2) values(值1,值2),(值3,值4),(值5,值6)

    
    
        insert into account(name,isdeleted) values
        
            (#{acc.name},#{acc.isdeleted})
        
    

9.8.sql片段

MyBatis基础——学习笔记_第6张图片

 执行sql语句时,不建议使用 * 作为查找内容,但是将字段都列出来的话又太繁琐,所以我们可以根据需要查找的内容,封装到sql片段中,编写sql语句时直接调用即可。

10.mybatis映射文件处理特殊字符的方法

10.1使用转义符

select * from User where id>1 and id<5

//使用转义符

select * from User where id > 1 and id < 5

10.2.使用

    

11.mybatis完成模糊查询

11.1使用字符串拼接完成

 方法:

public List findByLike(String name)

sql:

 

11.2.使用${}

    

通过观察: 发现使用${}实际上是字符串拼接,它不能防止sql注入, 而#{}它是预编译,它可以防止sql注入问题,#{}实际使用的PreparedStatement.

12.连表查询

表1(学生表)

MyBatis基础——学习笔记_第7张图片

 表2(班级表)

MyBatis基础——学习笔记_第8张图片

 条件:

根据学生id查询学生信息并携带班级信息。

sql语句:select * from student s join class c on s.cid = c.cid where stu_id = ?

student实体类:

package com.pgx.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    //班级对象作为属性
    private Clazz clazz;
}

class实体类:

package com.pgx.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Clazz {
    private int cid;
    private String cname;
}

创建接口并构造方法:

package com.pgx.dao;

import com.pgx.entity.Student;

import java.util.List;

public interface StudentDao {
    Student findAll(int id);
}

在映射文件中实现方法实现方法:





    
        
        
        
        
          
        
            
            
        
    

    

测试:

MyBatis基础——学习笔记_第9张图片

13.分页查询(pageHelper)

13.1.回顾分页的sql语句:

select * from 表名 where 条件 limit (page-1)*pageSize, pageSize;

page: 当前页码
pageSize: 每页显示的条数。

13.2.导入pagehelper 依赖的jar 包

        
            com.github.pagehelper
            pagehelper
            5.1.11
        

13.3.mybatis中设置pageHelper的拦截器

    
        
    

MyBatis基础——学习笔记_第10张图片

 13.4.测试并使用pagehelper

MyBatis基础——学习笔记_第11张图片

 13.5.pagehelper的作用:

 会帮我们的sql语句自动添加分页功能,并且获取一些其他信息。

13.6.pagehelper的原理

 当执行sql语句时不在时直接进到数据库查找,而是先经过拦截器,拦截器会为sql语句拼接上分页查询的部分,然后在进入数据库查询。

14.mybatis的代码生成器——generator

14.1.作用

可以根据表,帮你生成具体的实体类,操作类(dao),xml映射文件并携带简单的crud的方法和具体实现

14.2.使用流程

1).导入依赖的jar包

       
            org.mybatis.generator
            mybatis-generator-core
            1.4.0
        

2).创建generator的配置文件

MyBatis基础——学习笔记_第12张图片

内容(复制并结合自己进行修改):





    
    

    
        
        
            
        

        
        
        

        
            
        

        
        
            
            
        

        
        
            
        

        
        
            
        

        
        

3).编写测试类并在该类中使用代码生成器

 List warnings = new ArrayList();
   boolean overwrite = true;
   File configFile = new File("generator.xml");
   ConfigurationParser cp = new ConfigurationParser(warnings);
   Configuration config = cp.parseConfiguration(configFile);
   DefaultShellCallback callback = new DefaultShellCallback(overwrite);
   MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
   myBatisGenerator.generate(null);

15.mybatis的缓存

 15.1.缓存的好处

减少与数据库的交互,提高效率。

15.2.什么样的数据适合/不适合放入缓存中

适合:经常查询并且不经常改变的;数据的正确与否对最终结果影响不大的;

不适合:经常改变的数据;数据的正确与否对最终结果影响很大的;---数据安全性要求不高。例如:商品的库存,银行的汇率,股市的牌价;

15.3.mybatis的缓存有两种

1).一级缓存:基于SqlSession级别的缓存。默认一级缓存是开启的,不能关闭。

2).二级缓存:基于SqlSessionFactory级别的缓存,它可以做到多个SqlSession共享数据。默认它是关闭。需要手动开启。

15.4.演示一级缓存

 @Test
    public void text03()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        UserMapper um = session.getMapper(UserMapper.class);
        //查询id为2的数据信息,第一次查询缓存无法命中向数据库发送sql语句,把结果放入缓存中
        Users user = um.selectByPrimaryKey(2);
        System.out.println(user);
        //查询id为2的数据信息,第二次查询缓存命中,不会像数据库发送sql语句,结果从缓存中获取
        Users user1 = um.selectByPrimaryKey(2);
        System.out.println(user1);

        session.close();
    }

输出结果:

MyBatis基础——学习笔记_第13张图片

 15.4.1.测试重新开启一个session时一级缓存是否有效

 

  @Test
    public void text04()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        UserMapper um = session.getMapper(UserMapper.class);

        Users user = um.selectByPrimaryKey(2);
        System.out.println(user);

        
        //重新开启一个session对象并查询同一条信息
        SqlSession session1 = factory.openSession();
        UserMapper um1 = session1.getMapper(UserMapper.class);

        Users user2 = um1.selectByPrimaryKey(2);
        System.out.println(user2);
    }

输出结果:

MyBatis基础——学习笔记_第14张图片

 

 结论:一级缓存仍然无效!

15.5.演示二级缓存

1).首先要开启二级缓存

    
        
        
    

在mybatis.xml文件中配置

MyBatis基础——学习笔记_第15张图片

 2).在映射文件中使用缓存

MyBatis基础——学习笔记_第16张图片

 3).实体类一定要序列化接口(实现Serializable接口)

MyBatis基础——学习笔记_第17张图片

 4).测试二级缓存

    @Test
    public void test03() throws Exception{
        Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        SqlSession session=factory.openSession();

        UsersMapper mapper = session.getMapper(UsersMapper.class);
        //第一次查询编号=2的用户信息--缓存不能命中,则向数据库查询-发送sql语句、把查询的结果放入缓存中。
        //查询的结果放入一级缓存和二级缓存。 如果二级缓存能命中,第二次查询就不会发送sql语句
        Users users = mapper.selectByPrimaryKey(2);
        System.out.println(users);
        session.close();
        //开启新的SqlSession
        SqlSession session1=factory.openSession();
        UsersMapper mapper1 = session1.getMapper(UsersMapper.class);
        Users users1 = mapper1.selectByPrimaryKey(2);
        System.out.println(users1);
    }

输出结果:

MyBatis基础——学习笔记_第18张图片

 结论:当使用二级缓存时,开启一个新的session对象,查询同一条记录,会从缓存中获取。

你可能感兴趣的:(mybatis,学习,java)