SSM框架相关理论
1 Mybatis
1.1 Mybatis配置
-
在pom文件中引入相关的依赖
-
在Mybatis的核心配置文件中设置数据库连接信息、映射文件的信息、日志设置等。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"/> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins> <environments default="localdb"> <environment id="localdb"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.Driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.passwd}"/> </dataSource> </environment> </environments> <mappers> <!--<mapper resource="com/lzx/dao/StudentDao.xml"/>--> <package name="com.lzx.dao"/> </mappers> </configuration>
-
核心配置文件相关内容
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 核心配置文件中的标签顺序必须按照如下的顺序配置 properties?,settings?,typeAliases?,typeHandlers?, objectFactory?,objectWrapperFactory?,reflectorFactory?, plugins?,environments?,databaseIdProvider?,mappers? --> <properties resources="数据库连接的配置文件名"/> <settings> <setting name="",value=""/> </settings> <typeAliases> <typeAliase name="实体类对应的包名(该包下所有的类都有默认的别名,即类名且不区分大小写)"></typeAliase> <typeAliase type="需要设置别名的类型",alias="自定义的别名(不区分大小写,不写默认为类名)"></typeAliase> </typeAliases> <enviroments default="默认使用的数据库配置"> <enviroment id="自定义的唯一标识"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.Driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.passwd}"/> </dataSource> </environment> </enviroments> <mappers> <mapper resources="SQL映射文件的全限定名称"/> <package name="Sql映射文件所在的包名,要求与mapper映射接口所在包名一致且映射文件的名称与mapper接口的名称一致"/> </mappers> </configuration>
-
设置SQL映射文件,建议文件名与mapper接口名一致
- 命名空间与mapper接口的全限定名称一致
- SQL语句的id与Mapper接口中的方法名一致
<?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.lzx.dao.StudentDao"> <sql id="selectAll">select id,name,email,age from t_student</sql> <select id="selectAllStudents" resultType="com.lzx.domain.Student"> select id,name,email,age from t_student order by id </select> <insert id="insertStudent"> insert into t_student values(#{id},#{name},#{email},#{age}) </insert> <select id="selectStudents" resultType="com.lzx.domain.Student"> select id,name,email,age from t_student where id in <foreach collection="list" item="i" separator="," open="(" close=")"> #{i} </foreach> </select> <select id="selectStudentsByIf" resultType="com.lzx.domain.Student"> <include refid="selectAll"/> <where> <if test="name!=null and name != ''"> name = #{name} </if> <if test="age>0"> or age > #{age} </if> </where> </select> </mapper>
1.2 Mybatis参数获取
- 两种参数获取方式
- #{}相当于占位符,使用PreparedStatement执行sql,效率高,同时能避免SQL注入。
- ${}相当于字符串拼接,使用Statement对象执行sql,效率低,有SQL注入的风险。
- 参数传递的几种情况
- 当方法参数只有一个时,#{}和 都 行 , 但 是 {}都行,但是 都行,但是{}需要手动添加单引号
- 当方法的参数有多个时,Mybatis会自动创建一个map集合,集合的键为arg0,arg1…以及param1,param2,…对应的值就是参数值,访问时两种键的方式均可,即#{arg0},#{arg1}以及#{param1},#{param2}都可以访问到参数值,利用${}需要手动添加单引号
- 当方法有多个参数时,可以手动创建map集合,然后利用自定义的键值获取参数值,利用${}需要手动添加单引号
- 当方法的参数为实体类对象的时候,可以通过#{}或者 访 问 属 性 值 来 获 取 对 应 的 参 数 值 , 利 用 {}访问属性值来获取对应的参数值,利用 访问属性值来获取对应的参数值,利用{}需要手动添加单引号,获取属性值实际是通过get方法获取的。
- 当有一个或者多个参数时,可以利用@Param注解来给对应的参数赋名,然后通过注解值来获取对应的参数值,本质还是将注解的值作为键构造map集合,此时通过param1,param2仍然可以获取map集合中的参数值。
- 使用${}的几种场景(因为#{}解析时会自动添加单引号)
- 模糊查询时,‘%${}%’
- 用到in的场景中,in(${})
- 动态设置表名,select * from ${};
1.3 Mybatis查询结果返回值
-
当查询结果只有一条
- resultType设置为对应的实体类,方法返回结果设置为实体类对象
- resultType设置为对应的实体类,方法返回结果设置为实体类对象的list集合
- resultType设置为map集合,方法的返回结果设置为Map<String,Object>
-
当查询结果有多条时
- resultType设置为对应的实体类,方法返回结果设置为List<实体类>
- resultType设置为对应的实体类,方法返回结果设置为List<Map<String,Object>>
- resultType设置为Map集合,方法的返回结果设置为Map<String,Object>,在方法的上面使用注解@Mapkey(“键值(某个字段名)”)指定键值。
-
获取自增的主键
-
解决字段名与实体类属性名不一致
-
给字段名取别名,使别名与属性名一致。
-
设置Mybatis全局配置,将_自动映射为驼峰
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
-
利用resultMap设置自定义的映射关系
<resultMap id="userResultMap" type = "User"> <id property="主键属性名" column="主键字段名"></id> <result property="普通属性名" column="普通字段名"></result> .... <!--必须将所有的属性都映射一遍--> </resultMap> <select id="selectAllUsers" resultMap = "userResultMap"> SQL </select>
-
-
处理多对一的映射关系
-
利用级联属性赋值
-
利用resultMap的子标签association子标签
<association property="属性名" javaType="属性类型"> <id property="主键属性名" column="主键字段名"></id> <result property="普通属性名" column="普通字段名"></result> .... </association>
-
分步查询,利用association子标签,可以实现延迟加载。
- 可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
- aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。
- 此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟fetchType=“lazy(迟加载)|eager(立即加载)”
<association property = "属性名" select = "分步查询的sql的唯一标识(namespace.sqlId)" column = "分步查询的条件" fetchType = "当开启延迟加载时,可以手动控制延迟加载的效果"></association>
<settings> <!--开启延迟加载--> <setting name = "lazyLoadingEnabled" value = "true"/> </settings>
-
-
处理一对多的关系
-
利用collection子标签
<collection property = "属性名" ofType = "集合中元素类型"> <id property="主键属性名" column="主键字段名"></id> <result property="普通属性名" column="普通字段名"></result> .... </collection>
-
分步查询
<collection property = "属性名" select = "分步查询的sql的唯一标识(namespace.sqlId)" column = "分步查询的条件"> </collection>
-
1.4 动态SQL语句
1.4.1 if标签
<if test = "条件">
<!--需要拼接的SQL语句-->
</if>
1.4.2 where标签
<!--动态生成where关键字,标签内有内容时可以将内容前多余的and或or去掉,没有内容时不生成where关键字-->
<where>
<if test = "条件">
<!--需要拼接的SQL语句-->
</if>
</where>
1.4.3 trim标签
<trim prefix="内容前添加" suffix="内容后添加" suffixOverrides="内容后删除" prefixOverrides="内容前删除">
<if test = "条件">
<!--需要拼接的SQL语句-->
</if>
</trim>
1.4.4 choose,when,otherwise标签
<!--相当于if...else if ... else语句-->
<choose>
<when test="">
SQL语句1
</when>
<when test="">
SQL语句2
</when>
<when test="">
SQL语句3
</when>
<otherwise>
SQL语句4
</otherwise>
</choose>
1.4.5 foreach标签(用于批量操作)
<foreach collection = "要遍历的数组或者集合的名字" item = "数组或者集合中的数据" separator = "分隔符" open = "开始符号" close = "结束符号">
SQL语句
</foreach>
1.4.6 sql标签
<sql id = "">常用的sql语句</sql>
<include refid="sqlId"/>
1.5 Mybatis的缓存
1.5.1 一级缓存
- 默认开启,级别是sqlSession级别的,仅对查询有效。
- 一级缓存失效情况
- 不同的sqlSession对应的缓存不同
- 同一sqlSession但是查询条件不同
- 同一sqlSession两次查询期间执行了任意一次增删改操作
- 同一sqlSession两次查询期间手动清空了缓存
1.5.2 二级缓存
- 二级缓存时SqlSessionFactory级别的。
- 二级缓存开启的条件
- 核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true
- 在映射文件中设置标签
- 二级缓存必须在sqlSession关闭或者提交之后才有效
- 查询数据所转换的实体类类型必须实现序列化接口
- 二级缓存失效的条件:二次查询之间执行了任意一次增删改操作
1.5.3 缓存查询顺序
- 先查二级--------->再查一级----------->再查数据库
- sqlSession关闭后,一级缓存中的数据会写入二级缓存
1.5.4 整合第三方缓存代替二级缓存
-
引入依赖的jar包
-
创建缓存的配置文件
-
在映射文件中配置标签,设置二级缓存的类型
<cache type = "" />
1.6 Maven逆向工程的创建
1.7 分页插件
-
使用步骤
-
在pom.xml中添加依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>
-
在mybatis核心配置文件中配置分页插件
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
-
-
实现
-
在查询之前开启分页
PageHelper.startPage(int pageNum,int pageSize);
-
在查询之后获取分页相关信息
PageInfo<Emp> page = new PageInfo<>(list,5); //list表示查询到的数据 //5 表示当前导航分页的数量
-