小言_互联网的博客

【MyBatis】| MyBatis使用⼩技巧

523人阅读  评论(0)

目录

一:MyBatis使用⼩技巧

1. #{}和${}

2. typeAliases

3. mappers

4. IDEA配置⽂件模板

5. 插⼊数据时获取⾃动⽣成的主键


一:MyBatis使用⼩技巧

1. #{}和${}

#{}:先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防⽌sql注⼊,⽐较常⽤。

${}:先进⾏sql语句拼接,然后再编译sql语句,底层是Statement实现。存在sql注⼊现象。只有在需要进⾏sql语句关键字拼接的情况下才会⽤到。

(1)定义接口CarMapper ,面向接口编程


  
  1. package com.bjpowernode.mybatis.mapper;
  2. import com.bjpowernode.mybatis.pojo.Car;
  3. import java.util.*;
  4. public interface CarMapper {
  5. // 根据汽车类型查询
  6. List<Car> selectByCarType (String carType);
  7. }

(2)在CarMapper.xml文件中编写sql语句

注意:namespace是接口CarMapper的完整类名,id是接口对应的方法名


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper">
  6. <select id="selectByCarType" resultType="com.bjpowernode.mybatis.pojo.Car">
  7. select
  8. id,
  9. car_num as carNum,
  10. brand,
  11. guide_price as guidePrice,
  12. produce_time as produceTime,
  13. car_type as carType
  14. from t_car
  15. where car_type = #{carType}
  16. </select>
  17. </mapper>

(3)编写测试类,看执行结果对比


  
  1. package com.bjpowernode.mybatis.test;
  2. import com.bjpowernode.mybatis.mapper.CarMapper;
  3. import com.bjpowernode.mybatis.pojo.Car;
  4. import com.bjpowernode.mybatis.utils.SqlSessionUtils;
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.junit.Test;
  7. import java.util.List;
  8. public class CarMapperTest {
  9. @Test
  10. public void testSelectByCarType (){
  11. SqlSession sqlSession = SqlSessionUtils.openSession();
  12. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
  13. List<Car> cars = mapper.selectByCarType( "燃油车");
  14. for (Car car :cars){
  15. // 会调toString方法
  16. System.out.println(car);
  17. }
  18. sqlSession.close();
  19. }
  20. }

①使用#{}执行结果,能正常执行结果

特点:先执行SQL语句的编译,然后给SQL语句的占位符问号?传值

②使用${}执行结果,会抛出异常,直接拼接字符串但是没有引号

特点:先执行SQL语句的拼接,然后再对SQL语句进行编译

(4)#{}和${}的选择

注:如果需要SQL语句的关键字放到SQL语句中,只能使用${},因为#{}是以值的形式放到SQL语句当中;例如:升序或者降序排需要传asc或者desc,此时要把这个关键字传进去,就需要${}

①接口类中的方法


  
  1. package com.bjpowernode.mybatis.mapper;
  2. import com.bjpowernode.mybatis.pojo.Car;
  3. import java.util.*;
  4. public interface CarMapper {
  5. // 根据汽车类型查询
  6. List<Car> selectByCarType (String carType);
  7. // 查询所有的汽车信息,然后通过asc升序,desc降序
  8. List<Car> selectByAscOrDesc (String ascOrDesc);
  9. }

②编写sql语句,根据传参按照produce_time升序或者降序


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper">
  6. <select id="selectByCarType" resultType="com.bjpowernode.mybatis.pojo.Car">
  7. select
  8. id,
  9. car_num as carNum,
  10. brand,
  11. guide_price as guidePrice,
  12. produce_time as produceTime,
  13. car_type as carType
  14. from t_car
  15. where car_type = #{carType}
  16. </select>
  17. <select id="selectByAscOrDesc" resultType="com.bjpowernode.mybatis.pojo.Car">
  18. select
  19. id,
  20. car_num as carNum,
  21. brand,
  22. guide_price as guidePrice,
  23. produce_time as produceTime,
  24. car_type as carType
  25. from
  26. t_car
  27. order by
  28. produce_time #{ascOrDesc}
  29. </select>
  30. </mapper>

③编写测试程序


  
  1. package com.bjpowernode.mybatis.test;
  2. import com.bjpowernode.mybatis.mapper.CarMapper;
  3. import com.bjpowernode.mybatis.pojo.Car;
  4. import com.bjpowernode.mybatis.utils.SqlSessionUtils;
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.junit.Test;
  7. import java.util.List;
  8. public class CarMapperTest {
  9. @Test
  10. public void selectByAscOrDesc (){
  11. SqlSession sqlSession = SqlSessionUtils.openSession();
  12. CarMapper mapper = sqlSession.getMapper(CarMapper.class);
  13. List<Car> cars = mapper.selectByAscOrDesc( "asc");
  14. for (Car car :cars){
  15. // 会调toString方法
  16. System.out.println(car);
  17. }
  18. sqlSession.close();
  19. }
  20. }

使用#{},先编译在传值,传的是一个字符串,会有引号,明显不符合语法!

 使用${},先把关键字拼串上去,在进行编译,符合语法规则!

(5) 使用${}完成表名拼接

注:这里需要查询新的表名,所以需要编写新的PoJo类Log、新建配置文件LogMapper.xml、新建一个接口LogInterface、新建测试类LogMapperTest类进行测试、在核心配置文件mybatis-config.xml当中引入LogMapper.xml

①现实业务当中,可能会存在分表存储数据的情况,因为一张表存储数据的话,数据量太大,查询效率比较低。
②可以将这些数据有规律的分表存储,这样扫描的数据量变少了,在查询的时候效率就比较高。例如日志表:专门存储日志信息的,可以每天生成一个新表,每张表以当天日期作为名称,例如:t_log_20220901、t_log_20220902....
③假如想知道某一天的日志信息,假设今天是20230103,那么直接把日期传进去,完成“t_log_日期表”的拼接。


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.powernode.mybatis.mapper.LogMapper">
  6. <select id="selectAllByTable" resultType="com.bjpowernode.mybatis.pojo.Log">
  7. <!--select * from t_log_#{date}-->
  8. select * from t_log_${date}
  9. </select>
  10. </mapper>

(6)使用${}完成批量删除

注:批量删除对应的sql语句有两种写法

第一种:使用or的形式,delete from t_user where id = 1 or id = 2 or id = 3;

第二种:使用in的形式,delete from t_user where id in(1, 2, 3);

①定义的方法中参数实际上是一个String类型的字符串,我们传参的时候,也是一个字符串传过去,例如:mapper.deleteBatch("1,2,3")的形式。

②关键是我们先拼串再编译,还是先编译在传值;前者是字符串的完美拼接,后者是直接把一个字符串传过去,会带有引号!


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

(7)使用${}完成模糊查询

需求:根据汽车品牌进行模糊查询
例如:select * from t_car where brand like '%奔驰%';


  
  1. <select id="selectByBrandLike" resultType="CAR">
  2. select
  3. id,
  4. car_num as carNum,
  5. brand,
  6. guide_price as guidePrice,
  7. produce_time as produceTime,
  8. car_type as carType
  9. from
  10. t_car
  11. where
  12. <!--brand like '%#{brand}%'-->
  13. brand like '%${brand}%'
  14. brand like concat('%',#{brand},'%')
  15. brand like concat('%','${brand}','%')
  16. brand like "%"#{brand}"%"
  17. </select>

①如果使用"%#{brand}%",最终#{}底层肯定是转化为?,但是比较尴尬的是放到双引号或者单引号"?"的?是无法识别的,所以无法进行传值!

②解决方法1:使用"%${brand}%",会先进行拼串,然后在编译!

③解决方法2:concat函数,这个是mysql数据库当中的一个函数,专门进行字符串拼接,concat('%',#{brand},'%');这里也可以使用${band},外面加一个单引号,比较鸡肋,
concat('%','${brand}','%')。

④解决方法3:"%"#{brand}"%",把两个%用引号括起来,就能识别中间的?了,就能正常传值了。

2. typeAliases

使用 typeAliases标签完成别名机制!

(1)我们打开CarMapper.xml文件,发现resultType标签的全限定名称很长,包括我们以后写其它类型的查询语句,都要写这个带包的类名;所以就使用别名机制先定义别名。


  
  1. <select id="selectByCarLike" resultType="com.bjpowernode.mybatis.pojo.Car">
  2. </select>

(2)第一种:在核心配置文件mybatis-config.xml文件中使用typeAliases标签下的子标签typeAlias标签起别名。

注:namespace标签必须写全限定名称,是不能起别名的!

①type属性:指定给那个类型起别名

②alias:指定别名


  
  1. <typeAliases>
  2. <typeAlias type="com.bjpowernode.mybatis.pojo.Car" alias="car" />
  3. </typeAliases>

③ 这样就能在CarMapper.xml文件中运用别名了,并且不区分大小写!


  
  1. <select id="selectByCarLike" resultType="car">
  2. </select>

④实际上alias属性是可以省略的,有默认的别名,别名是类的简名;例如:com.bjpowernode.mybatis.pojo.Car对应的就是Car、car、cAr等等,不区分大小写。

(3)第二种:在核心配置文件mybatis-config.xml文件中使用typeAliases标签下的子标签package指定包名即可。(常用)

我们使用package标签指定一个包名,那么这个包下所有的类全部自动起别名,别名就是类简名,不区分大小写


  
  1. <typeAliases>
  2. <package name="com.bjpowernode.mybatis.pojo" />
  3. </typeAliases>

 (4)小总结

所有别名不区分大小写;namespace不能使用别名机制!


  
  1. <typeAliases>
  2. <!--别名自己指定的-->
  3. <typeAlias type="com.powernode.mybatis.pojo.Car" alias="aaa"/>
  4. <typeAlias type="com.powernode.mybatis.pojo.Log" alias="bbb"/>
  5. <!--采用默认的别名机制-->
  6. <typeAlias type="com.powernode.mybatis.pojo.Car"/>
  7. <typeAlias type="com.powernode.mybatis.pojo.Log"/>
  8. <!--包下所有的类自动起别名。使用简名作为别名。-->
  9. <package name="com.powernode.mybatis.pojo"/>
  10. </typeAliases>

3. mappers

(1)mapper标签的属性可以有三个:

①resource:这种方式是从类的根路径下开始查找资源;采用这种方式,配置文件需要放到类路径当中才行。
②url:这种方式是一种绝对路径的方式,这种方式不要求配置文件必须放到类路径当中,哪里都行,只要提供一个绝对路径就行;这种方式使用极少,因为移植性太差。
③class:这个位置提供的是mapper接口的全限定接口名,必须带有包名的。
例如:<mapper class="com.powernode.mybatis.mapper.CarMapper"/>,class指定的是:com.powernode.mybatis.mapper.CarMapper,那么mybatis框架会自动去com/powernode/mybatis/mapper目录下查找CarMapper.xml文件。

注意:也就是说,如果采用这种方式,必须保证CarMapper.xml文件和CarMapper接口必须在同一个目录下,并且名字一致。如:CarMapper接口-> CarMapper.xml。

解释:所谓的同一个目录,是在resource目录下创建包名,并且这个包名与java下的CarMapper接口包名必须一致,然后把配置文件CarMapper.xml扔到包名里;实际上java和resource都是根目录,只不过两种展现形式!

解释:在resource下创建包,实际上是创建目录,因为只有在java下创建包才是"点"的形式,例如:com.bjpowernode就表示com目录下的bjpowernode目录;对于resource下创建包就是直接创建目录,例如:com/bjpowernode也表示com目录下的bjpowernode目录,如果采用com.bjpowernode就表示一个名为com.bjpowernode的目录。


  
  1. <mappers>
  2. <mapper resource="CarMapper.xml"/> 要求类的根路径下必须有:CarMapper.xml
  3. <mapper url="file:///d:/CarMapper.xml"/> 要求在d:/下有CarMapper.xml文件
  4. <mapper class="com.powernode.mybatis.mapper.CarMapper"/> 全限定接口名,带有包名
  5. </mappers>

(2)假如有很多个接口名,要写很多个全限定接口名也很麻烦;实际上在mappers标签下还有一个package属性,用来指定包名,这种方式在开发中是比较常用的。

前提:XML文件必须和接口放在一起,并且名字一致!

解释:指定报名,实际上就是指定这个路径,在这个路径下查找配置文件。


  
  1. <mappers>
  2. <package name="com.bjpowernode.mybatis.mapper" />
  3. </mappers>

4. IDEA配置⽂件模板

mybatis-config.xml和SqlMapper.xml⽂件可以在IDEA中提前创建好模板,以后通过模板创建配置⽂件

(1)准备好的mybatis-config.xml核心配置文件的模板


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <properties resource=""/>
  7. <typeAliases>
  8. <package name=""/>
  9. </typeAliases>
  10. <environments default="dev">
  11. <environment id="dev">
  12. <transactionManager type="JDBC"/>
  13. <dataSource type="POOLED">
  14. <property name="driver" value="${jdbc.driver}"/>
  15. <property name="url" value="${jdbc.url}"/>
  16. <property name="username" value="${jdbc.username}"/>
  17. <property name="password" value="${jdbc.password}"/>
  18. </dataSource>
  19. </environment>
  20. </environments>
  21. <mappers>
  22. <package name=""/>
  23. </mappers>
  24. </configuration>

(2)准备好的SqlMapper.xml配置文件的模板


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="">
  6. </mapper>

(3)步骤:File--->Settings--->Editor--->File and Code Templates

(4)使用:以后直接alt+insert就能找到这个模板

 (5)选定这个模板后,就会让你输出文件的名字,例如:mybatis-config 

(6)点击ok,就会自动生成我们自定义模板的核心配置文件mybatis-config.xml

5. 插⼊数据时获取⾃动⽣成的主键

(1)前面用的主键一直是自动生成的,所以我们并不知道主键是多少,要是下面这种业务,⼀个⽤户有多个⻆⾊,一对多,两张表,多的表加外键

 (2)插⼊⼀条新的记录之后,⾃动⽣成了主键,⽽这个主键需要在其他表中使⽤时;插⼊⼀个⽤户数据的同时需要给该⽤户分配⻆⾊:需要将⽣成的⽤户的id插⼊到⻆⾊表的user_id字段 上。

①第⼀种⽅式:可以先插⼊⽤户数据,再写⼀条查询语句获取id,然后再插⼊user_id字段。【⽐较麻烦】

②第⼆种⽅式:mybatis提供了⼀种⽅式更加便捷。

(3)主要是在插入数据时,使用两个属性

①useGeneratedKeys="true" 表示使用自动生成的主键值。
②keyProperty="id" 指定主键值赋值给对象的哪个属性,就表示将主键值赋值给Car对象的id属性。


  
  1. <insert id="insertCarUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
  2. insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
  3. </insert>

(4)测试结果

①如果不加上这两个参数,打印结果主键显示null

 ②如果加上这两个参数,打印结果就会显示自动生成的主键


转载:https://blog.csdn.net/m0_61933976/article/details/128531269
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场