ssm框架 MyBatis框架

MyBatis框架
ORM框架的一种:Object relation mapping 对象 关系 映射
Hibernate:重量级,纯ORM,将数据库的操作装百年为对象操作,无须使用sql,效率、性能、学习成本高,优势就是无法手动对sql进行优化
Mybatis:轻量级,半ORM ,需要开发者手动编写sql,自动将sql的返回值映射成对象。好处是可以使用sql,程序员可以对sql及进行极致优化
mybatis的取值方式:
1、通过反射从对象中自动获取值
2、从map中取值
3、基本数据类型,直接取值
4、当超过两个参数时,必须使用注解@Param
5、如果参数是数据或者List,也需要使用@Param注解
6、默认情况下,mybatis只识别一个参数,默认的情况下,识别的类型有基本数据类型、String、普通的Javabean
MyBatis框架和 spring 框架的整合步骤:
1、引入依赖,在pom文件中设置
2、在spring配置文件设置mybatis的配置
3、定义接口,添加注解@Mapper
4、编写此接口的mapper文件
1、引入依赖:
<!-- mybatis框架本身 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <!-- 用于将mybatis和spring整合到一起 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency>
2、spring 配置文件中设置mybatis
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
3、配置指定的mybatis的配置文件
1.配置下划线转驼峰命名
<settings> <!-- 启用下划线转换成驼峰式命名 --> <setting name="mapUnderscoreToCamelCase" value="true" /> </settings>
2.配置别名
<!-- 配置别名 --> <typeAliases> <package name="com.situ.model" /> </typeAliases>
4、定义接口,添加注解@Mapper
也就是在dao层的接口上面加上注解,就不需要用实现类进行实现,直接通过xml文件进行配置string.xml文件配置扫描器
5、分页插件的使用:
// MyBaits 分页插件的使用 // 1.mybatis分页插件用法 PageHelper.startPage(ipageNo, ipageSize); // 2.此处查询无需执行手动分页操作 List<Book> books = bs.findAll(sb); // 3.获得分页对象 PageInfo<Book> pi = new PageInfo<>(books);
6、编写此接口的mapper文件。也就是每一个模型实体的映射文件
一般文件保存的路径就是包名下面的mapper文件,例如:classpath:com/situ/dao/mapper/*.xml
mapper文件的配置:配置文件需要注意的问题很多。
一、可以定义别名:
在MyBatis的配置文件中,如果不定义,可以使用包名+类名
可查看第三点,第二条!?
二、在mapper 配置文件中的自动映射和手动映射的问题
自动映射
<!-- 定义sql片段 --> <sql id="StudentColumn">id,stu_id,name,phone,email,pinyin,sex,birthday,weixin</sql> <select id="findById" resultType="Student"> select <include refid="StudentColumn" /> from t_student where id = #{id} </select>
手动映射:通过一个结果集映射来配置,需要注意的就是resultTyped的值是,类(可以定义别名),还是结果集映射。
<!-- 配置一个结果集映射 --> <resultMap type="Student" id="StudentMap"> <id column="id" property="id" /> <result column="stu_id" property="stuId" /> <result column="name" property="name" /> <result column="phone" property="phone" /> <result column="email" property="email" /> <result column="pinyin" property="pinyin" /> <result column="sex" property="sex" /> <result column="birthday" property="birthday" /> <result column="weixin" property="weixin" /> </resultMap> <!-- 定义sql片段 --> <sql id="StudentColumn">id,stu_id,name,phone,email,pinyin,sex,birthday,weixin</sql> <!-- 定义一个查询,mybatis使用的OGNL表达式 --> <select id="findAll" resultMap="StudentMap"> select <include refid="StudentColumn" /> from t_student <where> <if test="esb.id != null"> and id = #{esb.id} </if> <if test="esb.stuId != null and esb.stuId != ''"> and stu_id = #{esb.stuId} </if> <if test="esb.name !=null and esb.name != ''"> <!-- 绑定一个变量 --> <bind name="nameLike" value="'%'+ esb.name +'%'" /> and name like #{nameLike} </if> <if test="esb.birthdayRangeStart!=null"> and birthday >= #{esb.birthdayRangeStart} </if> <if test="esb.birthdayRangeEnd!=null"> and birthday < #{esb.birthdayRangeEnd} </if> </where> </select>
三、数据的增删改查
增:
<!-- 保存 --> <insert id="save" parameterType="Student"> insert into t_student (stu_id,name,sex,pinyin,birthday,phone,email,weixin) values ( #{stuId}, #{name}, #{sex}, #{pinyin}, #{birthday}, #{phone,jdbcType=VARCHAR}, #{email}, #{weixin} ) </insert>
删:
需要注意的:
1、删除集合的时候,需要在dao的接口类运用注解:
@Param(“ids”)
2、批量删除的语法foreach
<!-- 删除唯一一个实体 --> <delete id="deleteById"> delete from t_student where id = #{id} </delete> <!-- 批量删除 --> <delete id="deleteByIds"> delete from t_student where id in <!-- 迭代集合 --> <foreach collection="ids" item="id" open="(" close=")" separator=","> #{id} </foreach> </delete>
改
<!-- 更新学生 --> <update id="update" parameterType="Student"> update t_student <set> stu_id = #{stuId}, name = #{name}, sex = #{sex}, birthday = #{birthday}, pinyin = #{pinyin}, phone = #{phone}, email = #{email}, weixin = #{weixin} </set> <where> id = #{id} </where> </update>
查:
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>0
四、关于插件dao层中,通过两个参数进行查询和一个参数查询的不同
1、两个参数:需要添加注解,@Param(“参数名”),在同各国不同的#{参数名.id}通过调用
2、一个参数,直接可以调用,#{id} 来调用
五、数据的模糊查询:
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>1
通过绑定一个变量,进行查询
六、数据的大于小于
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>2
通过> 和<
七、where条件的and的使用
1、在where中,and可以用于第一个,mabatis框架直接去掉了第一个
八、分页
通过mybatis 其中的工具进行分页
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>3
九、在配置的时候如果很多sql语句都调用了相同的sql可以使用定义指定的片段参数,
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>4
十、日期类型,需要在实体中,进行注解:
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>5
十一、一对一关联:
关联所使用的方法:
1、sql语句关联:通过sql语句进行关联
缺点:
违背了面向对象的职责。例如:在数据库中,学生表中对应的班级id,通过学生表中的班级id查询班级名称,在学生DAO的实现xml文件中,既有学生信息,又有班级信息
性能不好,通常此类方法,通过查询15个学生,每一个学生对应的班级,需要重新进行sql班级查询,也就是通常所说的1对n查询
2、通过抽离班级的方法:也就是通过把 班级的模块化,通过调用班级DAO的实现xml进行查询
缺点:性能不好,同上
十二、1+N 的问题:
1、延迟加载(懒加载):简单配置、缓解1+n 的问题, 用到就查询,不用不查询
通过在mybatis.xml 文件中设置延迟加载的开关:
缺点:不用的时候是可以解决1+n的问题,一但使用,还是会出现1 + N 的问题
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>6
2、二级缓存
缺点:适用于只读类型,不经常修改数据的进行缓存,可以相对的解决部分1 + N 的问题
通过在mybatis.xml 文件中设置二级缓存的开关:
类似于:一级开关
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>7
在使用的dao层的xml文件中定义二级缓存相对应的配置
类似于:二级开关:
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>8
在使用的dao层的xml文件中进行查询的时候配置相对应的useCache true就是进行缓存,false就是不进行缓存,默认缓存
类似于:三级开关
<!-- 一、创建SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 指定mybatis的配置文件 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 指定每一个模型实体的映射文件 --> <property name="mapperLocations" value="classpath:com/situ/dao/mapper/*.xml"></property> </bean> <!-- 二、mapper扫描器,将包下面的mapper接口自动创建代理对象,自动创建到Spring容器中,bean的id就是mapper的类名(首字母小写) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.situ.dao" /> </bean> <!-- 三、创建SqlSession会话,不是单例的 --> <bean class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>9
3、自定义设置,可以设置成为1 + 1 的问题,
通过自己定义相对应的Java代码或者前端的js 代码进行 查询,直接一下把所有的信息进行查询出来,然后通过判断,例如在查询学生信息的时候,同步查询班级的信息,然后直接根据学生信息中的班级id 进行和班级的id 进行对比,如果班级的id 一致的话,那么直接就可以调用,转变为有1+n 的问题转变为 1+1 的问题。
在dao层进行sql查询所有的list 进行调用
在js同通过ajax进行调用。
十一、一对一、一对多、多对多 表之间的关系
文章作者:刘广法,转载请注明出处。