登录 or

Mybatis学习

Mybatis
一.与数据库交互
历史:jdbc-dbutil-hibernate-jdbctemplete-mybatis
 
二、操作步骤
1.导入pom依赖
2.xml文件创建(mybatis-config.xml和EmpDao.xml)mybatis官网复制的配置
3.实体类创建 bean -  Emp.java
4.dao - EmpDao.java接口(怎删改查方法)
5.修改mybatis-config.xml和EmpDao.xml
/mybatis-3-config.dtd注意看dtd源码写入的参数顺序
引入properties,进行相关配置
6.导入junit
test.java
7.mybaits添加日志,首先导入maven依赖,然后将相关配置从官网复制到log4j.properties,就可以显示sql语句了
 
 
三、配置
1、属性(properties)
2.设置(settings)
mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
3.类型别名(typeAliases)
4.类型处理器(typeHandlers)
4.环境配置(environments)开发、测试和生产环境需要有不同的配置,mybatis都可以进行配置,但是要注意
尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
事务管理器(transactionManager)JDBC
数据源(dataSource)POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
7.数据库厂商标识(databaseIdProvider)
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性
<databaseIdProvider type="DB_VENDOR" />
databaseIdProvider 对应的 DB_VENDOR 实现会将 databaseId 设置为 DatabaseMetaData#getDatabaseProductName() 返回的字符串。 由于通常情况下这些字符串都非常长,而且相同产品的不同版本会返回不同的值,你可能想通过设置属性别名来使其变短:
 
<databaseIdProvider type="DB_VENDOR">
  <property name="SQL Server" value="sqlserver"/>
  <property name="DB2" value="db2"/>
  <property name="Oracle" value="oracle" />
</databaseIdProvider>
 
 
拓展:插件plugins   pageHelper
 
insert
id:
flushcache:是否进入二级缓存
statementType:用来选择执行sql语句的方式
statement:最基本jdbc操作
prerpared:采用预编译的方式,方式sql注入
callable:调用存储过程
useGeneratedKEYS
keypropery
 
 
select
id
resultType:表示返回的结果的类型,一般使用的并不多,此类型只能返回单一的对象,而我们再查询结果集的时候需要自定义的类型
resulMap:结果映射,resultType和resultMap只能存在一个
当返回的结果是一个集合的时候,并不需要resultMap,只需要使用resultType中指定集合中的元素类型即可
当进行关联查询的时候,返回结果的对象中还包含另一个对象的引用
 
 
参数的获取值的方式:
每次在向sql语句中设置结果集的时候可以使用#{},还可以使用${},一般用#{}防止sql注入
但是要注意,${}也是有自己的使用场景的
当需要传入动态的表名、列名的时候就需要使用${},就是最直接的拼接字符串的行为
 
当查询语句中包含多个参数的时候,我们应该如何获取需要的参数?
1.如果是单个参数,
基本数据类型:那么可以使用#{}随便获取
引用数据类型:使用#{}获取值的时候必须要使用对象的属性名
2.如果是多个参数:
我们在获取参数值的时候,就不能简单的通过#{}来获取了,只能通过arg0,arg1...或paraml,param2...这样的方式来获取
原因在于,mybatis在传入参数的时候,会将这些参数封装到一个map,此时map中的key就是{arg0,arg1},{param1,param2}这些值,但是很明显这样的传值方式很不友好
因此,我们可以使用如下的方式来指定参数的key是什么
Emp selectEmpByNoAndName(@Param("empno") Integer empno, @Param("ename") String ename);
                也就是通过@Param来指定存入map中的key值是什么
3.自定义map结构
//自定义map
        Map<String, Object> map = new HashMap<>();
        map.put("sal",4000);
        map.put("deptno",10);
        Emp emp = mapper.selectEmpBySalAndDeptno2(map);
 
当需要返回的结果是一个Map的时候,同时map中包含多个对象,那么此时必须要在dao的方法上添加@MapKey注解,来标识到底是哪一个属性值作为key
 
在使用mybatis的时候,有些情况下,我们需要封装结果集,一般情况下mybatis会帮我们自动封装,但是如果字段名跟属性值不匹配的话,就需要自定义了
自定义使用resultMap
 <resultMap id="dog" type="com.guaguauu.bean.Dog">
        <id column="id" property="id"></id>
        <id column="dname" property="name"></id>
        <id column="dage" property="age"></id>
        <id column="dgender" property="gender"></id>
    </resultMap>
    
  <select id="selectDogByid" resultMap="dog">
 
联合查询
association 
collection 
 
关联查询的分步
<association property="dept" select="com.mashibing.dao.DeptDao.getDeptAndEmpsBySimple" column="deptno">
 
如果数据量大可以用单表分步做,但是条件查询的话适合联合查询
 
懒加载:如果联合查询,只需要查其中一个表的话,开启懒加载,可以减少工作量
 
 
动态sql
 
sql语句里加if或循环
if      <where>可以自动添加and
choose  when otherwise
 
trim  截取字符串,相当于可以自定义where的格式 prefix:前缀 prefixOverrides:去除整体sql语句前面多余的字符串
suffixOverride:去除sql语句后面的多余字符串
 
foreach:遍历集合中的元素
collection:指定要遍历的集合
separator:分割符
open:以什么开始
close:以什么结束
item:遍历过程中的每一个元素值
index:表示索引
 
缓存cache
cacheEnable
缓存分类:
一级缓存:sqlsession级别的缓存,每次查询的时候会开启一个会话,此会话相当于一次连接,关闭之后自动失效,所以默认情况下是开启的
在同一个会话之内,如果执行了多个相同的sql语句,那么除第一个之外,所以的数据都是从缓存中进行的查询
 
在某些情况下,一级缓存可能会失效?
1.在同一个方法中,可能会开启多个会话,此时需要注意,不是同一个会话的话就会失效,跟在哪个方法无关
2.当传递对象的时候,如果对象的属性不同,缓存会失效
3.如果修改了表数值,缓存会失效
4.如果在一个会话中,手动清空缓存,那缓存也会失效
 
二级缓存:全局缓存,必须要等到 一级缓存sqlsession关闭后才会生效
默认是不开启的,如果要开启的话,需要添加如下配置
1、修改全局配置文件,在settings中添加配置
cacheEnable
2.dao.xml中加<cache></cache>
3.对应的java实体类必须要实现序列号接口
 
一级缓存和二级缓存会同时存在吗?
不会,因为要等sqlsession关闭才有二
 
当查询数据的时候,我们先查询一级缓存还是先查询二级缓存?
先查询二级,二级没有再一级,一级没有再查数据库,有的话就直接命中返回了
 
第三方缓存:集成第三方的插件来充当缓存
 
逆向工程generator
 
 

0 个评论

要回复文章请先登录注册