mybatis基础知识

0、单个简单类型参数

单个简单类型(例如 String Long Date Char)参数不用在标签中,设置parameterType,并且在mybatis框架中,自动给parameterType设置了别名,简单的类型,就是前面加一个下划线,例如_int,包装类型就是一样的(具体看开发手册)

0.1、多个简单类型参数时

mybatis底层框架会自动创建一个Map集合,并且Map集合是以这种方式存储参数的
map.put(“arg0”,name);
map.put(“arg1”,sex);
map.put(“param1”,name);
map.put(“param2”,sex);
顺序是按照controller放入参数的顺序
则在mapper.xml的sql语句中是这样取值的

select * from student where name = #{arg0} and sex = #{arg1}

0.1(改进版)@Param注解

Controller的参数上加上Param注解,则在mapper中取参时,即可直接按取得别名取参数

List<Student> selectByNameAndSex(@Param("name") String name, @Param("sex") Character sex);

1、Map集合传参

parameterType = “map”

Map<String,Object> map = new HashMap<>();
               map.put("k1","111");
               map.put("k2","222");

然后sql语句接参

insert into t_car values (#{k1},#{k2})

#{}中写入map的key

有时用select语句查询pojo时,(没有合适pojo装时)也可以把resultType设置为map,然后用map接受即可
如果select出多条记录,则也可以用用List装,或者Map<Long,Map<String,Object>> selectAllRetMap(); 这比List好,因为取map时不用循环取,把Long的值与map中的id设置为一样,则取的时候直接get即可

2、Pojo传参

用类传参时,
#{}中写入属性名

3、返回List<实体类>

则resultType直接设置为实体类的路径即可

3、传参属性名和字段名不符的情况

可以使用resultMap,也可以在sql语句中是用别名的情况(as …)

结果映射集

<resultMap id="carResultMap" type="Car">
    <!-- 如果有主键,建议这里配置一个id标签,官方解释可以提高mybatis效率 -->
    <id property="id" column="id"/>
    <!--property后面填写POJO类的属性名-->
    <!--column后面填写数据库表的字段名-->
    <result property="carNum" column="car_num"/>
</resultMap>

多对一 和 一对多的映射关系

多对一:多在前,则多就是主表
一对多:一在前,则一就是主表
例如学生 与 班级的关系,就是多个学生对应一个班级,则多对一,学生表就是主表,则在主表中去定义班级
多对一时的定义
public class Student{
private Class class;//
}

一对多时的定义
public class Class{
private List stus;
}

多对一查询常用方式之一 < association >

<resultMap id="studentReusltMapAssociation" type="student">
   <id property="sid" column="sid"/>
   <result property="sname" column="sname"/>
   <!--
       association: 多对一的关联标签
         property: 提供要映射的POJO类的属性名
         javaType: 用来指定要映射的java类型
     
   -->
   <association property="class" javaType="com.aa.pojo.Class">
       <id property="cid" column="cid"/>
       <result property="cname" column="cname">
    </association>   

</resultMap>

 <select id="selectByIdAssociation" resultMap="studentResultMapAssociation">
      select 
          s.sid,s.sname,c.cid,c.name
          from
             t_stu s left join t_class c on s.cid = c.cid
          where
             s.sid = #{sid}
 </select>

多对一查询方法之二 1、可复用强 2、延迟加载也称为懒加载(核心原理:用的时候再执行查询语句,不用的时候不查)

<resultMap id="studentReusltMapAssociation" type="student">
   <id property="sid" column="sid"/>
   <result property="sname" column="sname"/>
   <association property="class" 
                select="com.aa.bb.ClassMapper.selectByIdStep2" //直接调用到其他mapper中的sql语句
                column="cid" //column表示其他sql语句所需要的参数,也是本sql语句查出来的值 
                fetchType="lazy" //开启懒加载 />

</resultMap>

 <select id="selectByIdAssociation" resultMap="studentResultMapAssociation">
      select 
          sid,sname,cid
          from
          t_stu where sid = #{sid}
          
 </select>

一对多常用方式 < collection >

<resultMap id="classResultMap" type="Class">
   <id property="cid" column="cid"/>
   <result property="cname" column="cname"/>
   <!--
       collection: 一对多的关联标签
         property: 提供要映射的POJO类的属性名
         ofType: 属性中映射的java类型
   -->
   
   <collection property="stus" ofType="com.aa.pojo.Student">
       <id property="sid" column="sid"/>
       <result property="sname" column="sname">
    </collection>   
</resultMap>
 <select id="selectByCollection" resultMap="selectByCollection">
      select 
         c.cid,c.name,s.sid,s.sname,
          from
             t_class c left join t_stu s on c.cid = s.cid
          where
             c.cid = #{cid}
 </select>

当然collection 也可以采用association的那种嵌套sql语句的方式

动态SQL

if标签

<!--
     1.if标签中test属性是必须的
     2.if标签中test属性值是false或者true
     3.如果test是true,则会与sql拼接
     4.test中的参数名
       当使用了@Param注解,那么test直接写 brand 即可  不用再用#{}或${}..
       没用@Param 就是用 arg0...
       pojo类时,用类的属性名
     5.test中 && 用 and表示
-->
 <if test="brand != null and brand != ''">

 </if>
 //可多个if连着写

where标签

<!--配合if等等标签,更加只能的where语句,就算全部内容无效,则where语句就不生效-->
<where>
   <if>
   </if>
</where>

trim标签

prefix 表示给trim的所有内容添加前缀,下面就是添加一个where
suffix 就是添加后缀
prefixOverrides 表示给trim中的每一个标签的前缀给删除了
suffixOverrides 下面就是表示如果标签中的后缀为and或or就删除

  <trim prefix="where" suffix="" prefixOverrides="" suffixOverrides="and|or" >
  </trim>

set标签

主要是用于update中

<update id="updateBySet">
  update t_car
    <set>
       <if test="carNum != null" ></if>
    </set>
</update>

通过set标签就可以动态在更新数据时加入一些动态的if判断

数据源

dataSource被称为数据源,也就是连接池
dataSource为程序提供一个Connection对象,只要是提供Connection对象的都可以称为是数据源。
我们也自己也可以编写一套数据源组件,只要实现接口javax.sql.DataSource接口即可
常用数据源druid
< dataSource type = “druid” >


Druid是阿里巴巴开发的号称为监控而生的数据库连接池

它的优点包括:

可以监控数据库访问性能

SQL执行日志

SQL防火墙 

但spring boot和shardingjdbc默认使用的数据库连接池是 HikariCP

如果要在shardingsphere中使用druid,需要在项目中整合后才能生效

#{} 和 ${}的区别

#{}: 底层使用PreparedStatement,特点:先进行SQL语句的编译,然后给SQL语句的占位符 ? 传值,可以避免SQL注入的风险,
${}: 底层使用Statement。特点:先进行SQL语句的拼接,然后再对SQL语句进行编译,存在SQL注入的风险(就是直接把值与sql语句凭借一起,而#{}是用?先占位)

通俗讲 #{}里的数据还带双引号,${}就直接是值,则 ${}常常用于sql凭借,比如 order by … ${} ,此时就可以在括号中传入asc或desc,如果此时用#{}反而报错
${}还可以用于表名的拼接,例如当有表
t_log_20220901
t_log_20220902
则使用sql语句时
select * from t_log_ ${…}此时就可以用 ${}来实现拼接

模糊查询(可以用${},但不建议,建议用第三种)

第一种

concat(‘%’,${brand},‘%’)

第二种(${})

‘%${brand}%’

第三种(常用)

“%”#{brand}“%”

批量删除(${}的用法)

Mapper


//批量删除,根据id
int deleteBatch(String ids);

前端给ids传入(“155,156,157”)

Mapper.xml

<delete id="deleteBatch">
    delete from t_car where id in(${ids})
</delete>    

像这种字符串中有多个值时,就得用钱符号来接受 ${ids}

批量插入(三种)

批处理效率非常高,之所以很多人测试批处理很慢的原因应该是mysql默认关闭批处理,url需要添加rewriteBatchedStatements=true
1、循环插入
mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.buhe.demo.mapper.StudentMapper">
  <insert id="insert" parameterType="Student">
    INSERT INTO tb_student (name, age, phone, address, class_id) VALUES (#{name},#{age},#{phone},#{address},#{classId})
  </insert>
</mapper>

mapper接口

public interface StudentMapper {
    int insert(Student student);
}

测试代码

//java项目www.fhadmin.org
@SpringBootTest
class DemoApplicationTests {
	@Resource
	private StudentMapper studentMapper;
 
	@Test
	public void testInsert(){
		//数据生成
		List<Student> studentList = createData(100);
 
		//循环插入
		long start = System.currentTimeMillis();
		studentList.stream().forEach(student -> studentMapper.insert(student));
		System.out.println(System.currentTimeMillis() - start);
	}
 
	private List<Student> createData(int size){
		List<Student> studentList = new ArrayList<>();
		Student student;
		for(int i = 0; i < size; i++){
			student = new Student();
			student.setName("小王" + i);
			student.setAge(18);
			student.setClassId(1);
			student.setPhone("1585xxxx669");
			student.setAddress("未知");
			studentList.add(student);
		}
 
		return studentList;
	}
}

2、foreach标签
mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.buhe.demo.mapper.StudentMapper">
  <insert id="insertBatch">
    INSERT INTO tb_student (name, age, phone, address, class_id) VALUES
    <foreach collection="list" separator="," item="item">
        (#{item.name},#{item.age},#{item.phone},#{item.address},#{item.classId})
    </foreach>
  </insert>
</mapper>

mapper接口

public interface StudentMapper {
      int insertBatch(List<Student> studentList);
}

测试代码

//java项目www.fhadmin.org
@SpringBootTest
class DemoApplicationTests {
	@Resource
	private StudentMapper studentMapper;
 
	@Test
	public void testInsertByForeachTag(){
		//数据生成
		List<Student> studentList = createData(100);
 
		//使用foreach标签,拼接SQL插入
		long start = System.currentTimeMillis();
		studentMapper.insertBatch(studentList);
		System.out.println(System.currentTimeMillis() - start);
	}
 
 
	private List<Student> createData(int size){
		List<Student> studentList = new ArrayList<>();
		Student student;
		for(int i = 0; i < size; i++){
			student = new Student();
			student.setName("小王" + i);
			student.setAge(18);
			student.setClassId(1);
			student.setPhone("1585xxxx669");
			student.setAddress("未知");
			studentList.add(student);
		}
 
		return studentList;
	}
}
  1. 批处理

测试代码:

//java项目www.fhadmin.org
@SpringBootTest
class DemoApplicationTests {
	@Autowired
	private SqlSessionFactory sqlSessionFactory;
 
	@Test
	public void testInsertBatch(){
		//数据生成
		List<Student> studentList = createData(100);
 
                //使用批处理
		long start = System.currentTimeMillis();
		SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
		StudentMapper studentMapperNew = sqlSession.getMapper(StudentMapper.class);
		studentList.stream().forEach(student -> studentMapperNew.insert(student));
		sqlSession.commit();
		sqlSession.clearCache();
		System.out.println(System.currentTimeMillis() - start);
	}
 
	private List<Student> createData(int size){
		List<Student> studentList = new ArrayList<>();
		Student student;
		for(int i = 0; i < size; i++){
			student = new Student();
			student.setName("小王" + i);
			student.setAge(18);
			student.setClassId(1);
			student.setPhone("1585xxxx669");
			student.setAddress("未知");
			studentList.add(student);
		}
 
		return studentList;
	}
}

别名技巧

在配置文件中写

<typeAliases>
    <!--
      type: 指定给那个类型起别名
      alias: 指定别名(可以省略,默认别名就是该路径的类名)
    -->
    <typeAlias type="com.vv.mybatis.pojo.Car">
    //这样在mapper.xml中的resultType就不用写这么长了,写个类名即可

    <package name="com.vv.mybatis.pojo">
    //这是直接把该路径下的类全部取别名,一般用这种吧,方便,第一张要一个类一个类输入
<typeAliases>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值