栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis学习笔记2

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis学习笔记2

用简单表演示:

#创建数据库ssm
CREATE DATABASE ssm DEFAULT CHARSET utf8;

#使用(打开)ssm数据库
use ssm;

#创建表student
CREATE TABLE `student` (
`id` int(11)  AUTO_INCREMENT primary key ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into student(name,email,age) values('张三','zhangsan@126.com',22);
insert into student(name,email,age) values('李四','lisi@126.com',21);
insert into student(name,email,age) values('王五','wangwu@163.com',22);
insert into student(name,email,age) values('赵六','zhaoliun@qq.com',24);

学习时用的并非SpringBoot项目,所以安装使用SSM框架时的老配置

1.创建Maven项目

2.引入mysql驱动和Mybatis框架依赖

3.修改pom.xml添加资源文件指定

4.在idea中添加数据库的可视化(这个随自己)

5.添加jdbc.properties属性文件(数据库的配置)

6.添加SqlMapConfig.xml文件,该文件是Mybatis的核心配置文件

7.创建实体类用来封装数据

8.添加完成学生表的增删改查的功能StudentMapper.xml

9.测试

 

 引入了单元测试,mysql驱动,mybatis框架

 

指定资源文件的原因,如果不指定,target文件会少东西,老的SSM配置是比较麻烦

 自定资源文件后再运行单元测试(为了编译或者用maven编译下),看下target,

 就是包含resources

idea支持数据库可视化

 

 

创建查询

 

 在resources下引入jdbc.properties配置文件

其实注册mapper.xml文件也可以放到其地方,随你自己指定

 建实体类

 我这里命名空间乱写的

 用单元测试看下配置对不对

Resources导入的是ibatis的,mybatis的前身就是ibatis

CRUD来一套

前面命名空间的意义在于分辨:比如两个接口 都有getAll()如何分辨就是namespace的意义

这里关于parameterType 类型映射表  其实可以不写,基本都省略不写了,左边是.XML的prameterType或者resultType的写法,对应右边java类型

也就是说如果参数是Map  那么parameterType或者resultType可以写成map

如果是自定义对象比如Student   resultType需要具体包名+类名,比如com.hui.pojo.Student

现在很多时候用SpringBoot.我们写成resultType="Student",原因是配置文件配置了

mybatis或mybatis都可以这样配置

 

使用轮子

 再来几遍

 

 插入主键回传

 新增时报错,原因mysql驱动版本太低,8.0那么jdbc驱动也需要改下

改变mysql驱动版本

jdbc driver改一下

 再测试,OK

注意增删改需要commit

 删除一个学生

 

 更新

 

 以上在单元测试中,创建SqlSession的代码都是重复的,关闭也是重复的

重温下在单元测试中的@Before和@After

在StudentMapper.xml中给单个实体类取别名,不然每次都要写parameterType="com.hrui.pojo.Student"

 这样StudengMapper.xml里的parameterType和resultType可以简写成

parameterType="student" 和resultType="student"

 

 测试也都OK

 批量注册实体类别名

关于设置日志输出(sql语句参数类型等输出)

 

 具体设置

 执行时,在控制台输出

 这里提一下动态代理

 下面这个问题一时没有解决,先往下继续

下面重建个项目演示动态代理访问

新建张表用来演示

use ssm;
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROp TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) COMMENT '用户名称',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(2) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `users` VALUES (1, '王五', '2000-09-10', '2', '安徽');
INSERT INTO `users` VALUES (2, '张三', '2001-07-12', '1', '北京市');
INSERT INTO `users` VALUES (3, '张小明', '1999-02-22', '1', '河南');
INSERT INTO `users` VALUES (4, '陈小亮', '2002-11-19', '1', '辽宁');
INSERT INTO `users` VALUES (5, '张三丰', '2001-03-10', '1', '上海市');
INSERT INTO `users` VALUES (6, '陈小明', '2002-01-19', '1', '重庆市');
INSERT INTO `users` VALUES (7, '王五四', '2001-05-13', '2', '天津市');
select * from users;

上面表主键自增设置为27,意思就是主键从27开始

但是插入时候给了id,这样也是可以的,至少没有报错

 引入需要的依赖



    4.0.0

    com.hrui
    mybatis-02
    1.0-SNAPSHOT

    
        8
        8
    

    
        
        
            junit
            junit
            4.12
            test
        
        
        
        
            mysql
            mysql-connector-java
            8.0.29
        
        
        
        
            org.mybatis
            mybatis
            3.5.6
        
        
            org.projectlombok
            lombok
            RELEASE
            compile
        
    

    
    
        
            
                src/main/java
                
                    ***.properties
                
            


            
                src/main/resources
                
                    ***.properties
                
            
        
    


jdbc.properties.其实名字也随自己取

db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://xxxxxxxxxx:3306/ssm?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
db.username=xxxxx
db.password=xxxxxxx

关于SqlMapConfig.xml名字无所谓,随自己取名

主要作用

1.读取对应的jdbc.properties获得驱动,url,username,password等等或者初始化数据库连接池连接数,最大连接数等

22.设置日志输出

3.注册实体类别名

4.注册指定写sql的.xml位置等等

SqlMapConfig.xml





    
    
    
    
        
    
    
    
        
        
        
        
    
    
    
        
            
            
            
            
                
                
                
                
            
        
        
        
        
        
        
        
        
        
        
    
    
    
        
    

注意上面 


   
       
   

idea配置数据库可视化

 

 创建实体类

 动态代理的实现规范:

1)UsersMapper.xml文件与UserMapper.java的接口必须同一个目录里(SpringBoot中另讲)

2)UsersMapper.xml文件与UserMapper.java的接口的文件名必须一致,后缀不管.(好像也有问题是吧哈哈)

3)UserMapper.xml文件中的标签的id值与UserMapper.java的接口中方法名一致

4)UserMapper.xml文件中的标签的parameterType属性值与UserMapper.java的接口中方法参数类型一致

5)UserMapper.xml文件中的标签的resultType值与UserMapper.java的接口中方法返回值类型一致

6)UserMapper.xml文件中namespace属性必须是接口的完全名(包名+类名)

7)在SqlMapConfig.xml文件中注册mapper文件时,使用

 查看一个类的路径

 

 测试

package com.hrui;

import com.hrui.mapper.UserMapper;
import com.hrui.pojo.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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;


public class MyTest {
    SqlSession sqlSession;
    @Before
    public void openSqlSession() throws IOException {
        //使用文件流读取配置文件SqlMapConfig.xml
        InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory工厂
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
        //取出SqlSession对象
        sqlSession=factory.openSession();
    }
    @After
    public void closeSqlSession(){
        //关闭
        sqlSession.close();
    }
    @Test
    public void testA(){
        //取出动态代理对象,完成接口中方法的调用,实则是调用.xml文件中相同的标签的功能
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        System.out.println(userMapper.getClass());
        List list=userMapper.getAll();
        list.forEach(user-> System.out.println(user));
}

 注意,我给.XML改个名字

 但是我们在使用SpringBoot中好像没有这样.只要命名空间OK就行

糊弄下过去就是说肯定是某个属性改过了.了解后再说

练练手

 .xml






    
    
        select * from users
    

    
        select * from users where username like concat('%',#{name},'%')
    

    
        update users set username=#{userName},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    

    
        insert into users(username,birthday,sex,address)values(#{userName},#{birthday},#{sex},#{address})
    

    
        delete from users where id=#{id}
    

注意几点:

update一般传进来一个对象

UserMapper userMapper=sqlSession.getMapper(UserMapper.class);代码重复,提取出来

这里birthday我是直接new Date()

SimpleDateFormat sdf=new SompleDateFormat("yyyy-MM-dd");

sdf.parse("1999-02-22");

具体代码

package com.hrui;

import com.hrui.mapper.UserMapper;
import com.hrui.pojo.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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


public class MyTest {
    SqlSession sqlSession;
    UserMapper  userMapper;
    //日期格式化
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");


    @Before
    public void openSqlSession() throws IOException {
        //使用文件流读取配置文件SqlMapConfig.xml
        InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory工厂
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
        //取出SqlSession对象
        sqlSession=factory.openSession();
        //取出动态代理对象,完成接口中方法的调用,实则是调用.xml文件中相同的标签的功能
        userMapper=sqlSession.getMapper(UserMapper.class);
    }
    @After
    public void closeSqlSession(){
        //关闭
        sqlSession.close();
    }
    @Test
    public void testA(){

        System.out.println(userMapper.getClass());
        List list=userMapper.getAll();
        list.forEach(user-> System.out.println(user));
    }

    @Test
    public void testB(){

        System.out.println(userMapper.getClass());
        User user=userMapper.getUserById(1);
        System.out.println(user);
    }

    @Test
    public void testC(){

        System.out.println(userMapper.getClass());
        List users=userMapper.getUserByName("王");
        users.forEach(user -> System.out.println(user));
    }

    @Test
    public void testD() throws ParseException {

        System.out.println(userMapper.getClass());
        //int num = sqlSession.update("updateUser", new User(1, "小小王", new Date(), "1", "宁波"));
        userMapper.updateUser(new User(1, "小小王", sdf.parse("2000-01-01"), "1", "宁波"));

        sqlSession.commit();
    }
    @Test
    public void testE(){

        System.out.println(userMapper.getClass());
        userMapper.saveUser(,new User("宝宝",new Date(),"2","杭州"));
        sqlSession.commit();
    }

    @Test
    public void testF(){

        System.out.println(userMapper.getClass());
        userMapper.deleteById(28);
        sqlSession.commit();
    }
}

比如前端传进来肯定是个字符串  "2000-01-01"或其他格式 

上面比如可以这样

User user=new User(111,"haha",sdf.parse("2000-01-01"),"2","杭州");

 用下面方式可以转化

但是很多框架都已经做好了

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") //返回时间类型
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") //接收时间类型
@ApiModelProperty(value = "活动开始时间")
private LocalDateTime startTime;

注意增删改还是需要sqlSession.commit()

 #{}占位符底层使用的是PreparedStatement对象,是安全的数据库访问,防止sql注入

#{}里写什么,看parameterType参数类型

1)如果parameterType的类型是基本类型(8种基本(封装)类型+String)

且只有一个参数

则#{}里随便写

2)parameterType是实体类,则#{}里只能是类中成员变量,且#{userName}区分大小写

复杂的后面讲 甚至parameterType可以不写

${}字符串拼接或字符串替换

1)一般用于模糊查询中,其实我上面就没有用,有sql注入风险

如果用${}的话,模糊查询可以这样写

where username like '%${name}%',因为根本不提倡${}的写法,所以也没必要

同样

如果parameterType的类型是基本类型(8种基本(封装)类型+String)

且只有一个参数

则${}里随便写---->区分版本.如果是mybatis版本在3.5.1以下只能写${value}

2)如果是实体类,如上一样

${}用于字符串替换:比如如下

关于模糊查询:

比如 where username like concat('%',#{name},'%');就OK了

现在有个需求比如

select * form users where username like concat('%',#{userName},'%')

select * form users where address like concat('%',#{address},'%')

希望写一条sql搞定

需要用到列明只能用${}绝对不能用#{}    上面users写成user了   注意

但自己有次听课,记得mybatis某个版本后,多参数也不需要@Param注解了 

 

关于主键回传:

业务需求比如:当插入一个用户后,我需要再另外一张表记录该插入用户的id

可是用户插入后我们不知道该用户id,难道我们再去查下用户表,看看刚插入的用户id是什么???完全没必要,mybatis有主键回传功能

就以前面写过的插入用户为例子

 

 看下输出  id为null

 现在我在.XML里加点东西

 继续测试刚才的插入

 id已经有了

另外sql里

select last_insert_id();可以看到查到最后一次或者说最近一次插入数据的id

主键回传的另外一种方式

 


    
        select last_insert_id()
    
    insert into users(username,birthday,sex,address)values(#{userName},#{birthday},#{sex},#{address})

keyProperty:user对象的哪个属性来接返回的主键值

resultType:返回的主键的类型

order:在插入语句执行前,还是执行后返回主键的值(注意插入前根本不存在主键的值,还没插入呢)

关于UUID

 

关于动态SQL

select * from users  无条件查询

select * from users where sex=1   带一个条件查询

select * from users where sex=1 and username like '%市%'    带两个条件查询

比如上面三条sql,我们无法确定有几个条件

1)标签:用来定义代码片段,可以将所有的列名或复杂的条件定义为代码片段,供使用时调用

2):用来引用定义的代码片段.

现学现用下面我们改造下sql

3):进行条件判断

4):进行多条件判断,在查询,删除,更新中使用

 测试下

 

5):有选择的进行更新,至少更新一列

 

 比如更新35

 这里如果你什么都不更新会报错

6)用来进行集合或数组的遍历

collection:collection属性的值有三个,分别是list,array,map分别对应的参数类型为List,数组,map

item属性:循环体中具体的对象.支持属性点路径访问,如item.age,item.info.details,在list和数组中item指其中的对象,在map中item指value

index属性:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选.

open:表示该语句以什么开始

close:表示该语句以什么结束

separator:表示元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间","隔开,避免手动输入逗号导致sql错误,如in(1,2)这样.该参数可选

演示,比如我需要查id=2   4  6的数据

select * from users where id=2 or id=4 or id=6

或者select * from users where id in(2,4,6)

演示数组参数

 .XML

也可以将两边括号写在foreach里面

 测试

演示批量删除

 

 

 数据库看下有没有删掉

演示批量插入

insert into user

(username,birthday,sex,address)

values

('a','1999-09-09','1','绍兴'),

('b','1999-09-09','1','绍兴2'),

('c','1999-09-09','1','绍兴3')

 

 

演示批量更新

 报错

 报错原因并非sql写错了什么的

而是需要设置使用批量更新操作

在jdbc.properties加&allowMultiQueries=true  允许多行操作

 再次执行OK

关于parameterType  增删改查除了自定义实体类  都可以不写  简单类型想写就写,传入参数是集合数组都可以不写   ()   

查询必须写resultType或者resultMap

标准做法就是parameterType除了8种基本类型包装类+String 或者实体类去写以下

其他都可以不写

甚至你就不写  能怎么地吧  哈哈哈哈

关于Mybatis指定参数下标位置查询(就是如果多参,不写@Param注解 如果指定下标查询)

这个问题记得mybatis改版后就不需要再写@Param注解区分参数,但是具体哪个版本忘记了

 

 在mybatis版本3.4.1之前  直接between #{0}  and #{1}   该版本之后 between #{arg0} and #{arg1}

可以用0,1,2,3,4,5,6,7等等下标来取值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/995346.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号