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
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;
}
}
- 批处理
测试代码:
//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>