MyBatis学习笔记

MyBatis笔记

 

输入参数:parameterType

  1. 类型为 简单类型(8个基本类型+String)
  1. #{}  ${}

#{任意值}

${value},其中的标识符只能是value

  1. #{}自动给String类型加上’’(自动类型转换)

${} 原样输出,但是适合于动态排序(动态字段)

Select stno,stuname,stuage from student where stuname=#{value}

Select stuno,stuname,stuage from student where stuname=’${value}’

动态排序:

Select stuno,stuname,stuage from student order by ${value} asc

  1. #{}可以防止SQL输入

${}不可以

  1. ${} #{} 相同之处:
  1. 都可以 获取对象的值(嵌套类型对象)
  1. 获取对象值:

模糊查询,方式一

Select stuno,stuname,stuage from student where stuage=#{stuAge} or stuname like #{stuName}

Student student=new Student();

Student.setStuAge(24);

Student.setStuName(“%w%”);

List< student> studentList= mapper.queryStudent Like(Student);    

模糊查询,方式二

Select stuno,stuname,stuage from student where stuage=#{stuAge} or stuname like ‘%${stuName}%’

Student student=new Student();

Student.setStuAge(24);

Student.setStuName(“w%”);

List< student> studentList= mapper.queryStudent Like(Student);    

 

j. 嵌套类型对象

2.对象类型

#{属性名}

${属性名}

输入对象为HashMap:

Where stuage=#{stuAge}

用map中key的值匹配 占位符#{stuAge},如果匹配成功就用map的value替换占位符

 

输入对象为HashMap:

Where stuage=#{stuAge}

用map中key的值匹配 占位符#{stuAge},如果匹配成功就用map的value替换占位符

 

Mybatis调用存储过程

  1. 查询某个年级的学生总数

<select id="queryCountByAge" statementType="CALLABLE" resultType="int">
    {
     CALL  queryCountByAge(
     #{@age,jdbcType=INTEGER,mode=IN},
     #{@count,jdbcType=INTEGER,mode=OUT}
     )
    }
</
select>

 

  1. 根据学号删除学生
<delete id="deletePersonById" statementType="CALLABLE" parameterType="HashMap" >

    {

    CALL  deletePersonById(

    #{@id,jdbcType=INTEGER,mode=IN}

    )

    }

</delete>

其中通过 statementType=”CALLABLE”设置SQL的执行方式是存储过程。存储过程的输入参数gName需要通过HashMap传值,在使用时,通过hashmap的put方法传入输入参数的值;通过hashmap的Get方法获取输出参数的值。要注意Jar问题:ojdbc6.jar不能l在调用存储过程市打回车、tab,但是ojdbc7.jar可以。

如果报错:No enum constant org.apache.ibatis.type.JdbcType.xx,则说明mybatis不支持**类型,需要查存储过程无论输入参数是什么值,语法上都需要用map来传递改值;只要是<transactionManager type=”JDBC”/>,则增删改都需要commit

 mapper.xml ->mapper接口-》测试方法

 

输出参数resultType

  1. 简单类型(8个基本+String)
  2. 输出参数未实体对象类型
  3. 输出参数未实体对象类型集合:虽然输出类型为集合,但ResultType依然写集合的元素类型
  4. 输出参数类型为HashMap

---HashMap本身是一个集合,可以存放多个元素,但是根据提示发现 返回值为HashMap时,查询结果只能是一个学生

结论是一个HashMap对应一个学生的多个元素

resultType

resultMap:实体类的属性、数据表的字段:类型、名字不同时(stuno,id)

注意:当属姓名和字段名不一致时,除了使用resultMap以外,还可以使用ResultType+HashMap:

  1. resultMap
  2. resultType+HashMap

注意:如果10个字段,但发现某一个字段结果始终为默认值(0,0.0,null)则可能是表的字段和类的属性名字写错

//查询全部学生

String statement=”select stno,stuname from student”;

 

<where>会自动处理第一个<if>标签中的and,但不会处理之后的<if>中的and

<foreach>

查询学号为1、2、53的学生信息

Ids={1,2,53};

Select stuno,stuname from student where stuno in(1,2, 53)

<foreach>迭代的类型:数组、集合、属性(Grade类:List<Integer> ids)、对象数组

 

简单类型数组

无论编写代码时,传递的是什么参数名,在mapper.xml中,必须用array代替数组。

 

集合:

无论编写代码时,传递的是什么参数名(stuNos),在mapper.xml中,必须用list代替该数组。

 

对象数组:

Student[] students={student0,student1,student2}每个student包含一个学号属性。

注意几点:

parameterType=“Object[]”

 

SQL片段:

Java:方法

数据库:存储过程、存储函数

Mybatis:SQL片段

  1. 提取相似代码
  2. 引用

如果SQL片段和引用处不在同一个文件中,则需要在refid引用时加上namespace

 

关联查询

一对一:

  1. 业务扩展类

核心:用resultType指定类的属性 包含 多表查询的所有字段

  1. resultMap

一对一 association

一对多 collection(多对多,多对一本质上一对多的变化)

  1. 通过 属性成员将2个类建立起联系

 

日志:Log4j

SLF4J—》Apache Commons Logging->Log4j 2 ->Log4j ->JDK logging

  1. Log4j: log4j.jar
  2. 开启日志,conf.xml
  3. 编写配置日志输出文件

Log4j.properties

日志级别:DEBUG<INFO<WARN<ERROR

如果设置为info,则只显示info 及以上级别的信息:

建议:在开发时设置debug,在运行时设置为info或以上。

 

可以通过日志信息,详细的而阅读mybatis执行情况(观察mybatis实际执行sql的语句,以及sql中的参数和返回结果)

 

延迟加载:

一对一、一对多、多对一、多对多

一对多:班级-学生

如果不采用延迟加载,(立即加载)查询时会将 一和多都查询,班级、班级中的所有学生

 

如果想要 暂时只查询1的一方,而多的一方先不查询 而是在需要的时候再去查询—》

 

使用延迟加载的方法

1.在config.xml配置

<settings>

    <setting name="logImpl" value="LOG4J"/>

    <setting name="lazyLoadingEnabled" value="true"/>

    <setting name="aggressiveLazyLoading" value="false"/>

</settings>
如果增加了mapper.xml,需要修改config.xml配置文件(将新增的mapper.xml加载进去)
  1. 在mapping.xml

<select id="queryPersonCard_lazy" parameterType="int" resultMap="person_card_lazyload_map">
    select * from Person
</
select>
<resultMap id="person_card_lazyload_map" type="Person">
    <id property="id" column="id"/>
    <result property="pName" column="pName"/>
    <result property="age" column="age"/>
    <association property="card" javaType="PersonCard" select="com.lifen.mapper.personCardMapper.queryCardById" column="cardid">
      </association>
</resultMap>

增加mapping.xml文件

<select id="queryCardById" parameterType="int" resultType="PersonCard">

    select * from personCard where cardid=#{cardid}

</select>

 

  1. 查询缓存

一级缓存:同一个SQLSession对象

Mybatis 默认开启一级缓存,如果用同样的SqlSession对象查询相同的数据,则只会在第一次查询时向数据库发送SQL语句,并将查询的结果放入到SQLSession中(作为缓存),后续在此查询该同样的对象时,则直接从缓存中查询改对象即可(即省略了数据库的访问)

 

 

二级缓存

   MyBatis默认没有开启二级缓存,需要手工打开

  1. config.xml
  2. 在具体的mapper.xml中声明开启(studentMapper.xml中)

<mapper namespace=”org.langqiao.mapper.StudentMapper”>

<!—声明namespace 开启二级缓存->

<cache/>

根据异常提示:NotSerializableException 可知,MyBatis的二级缓存是对象放入磁盘序列化

序列化:内存—》硬盘

反序列化:硬盘--》内存

准备缓存的对象必须实现序列化

   MyBatis自带二级缓存:同一个namespace 生成的mapper对象,则他们共享缓存。

只要产生的XXXMapper对象来自于同一个namespace,则此对象共享同一个缓存。

禁用二级缓存:select标签中useCache="false"

清理:a. commit()

  在二级缓存里,不能是自身的缓存

     b.在select标签中 增加属性flushCache=”true”

命中率 zs:0%

 

 

   三方提供的二级缓存:

ehcache、memcache

a.下载jar包

Ehcache-core.jar

Mybatist-Ehcache.jar

Slf4j-api.jar

   b.编写ehcache配置文件Ehcache.xml

   c.开启EhCache缓存 <cache type=”org.mybatis.caches.ehcache.EhcaheCache”>

<perperty name=”” value=”’/>

</cache>

 

 

  1. 逆向工程

表、类、接口、mapper.xml四者密切相关,因此当知道一个的时候,其他三个应该可以自动生成。

表----》其他三个

 

实现步骤:

A、mybatis-generator-core.jar、mybatis.jar 、 ojdbc.jar

B、逆向工程的配置文件generator.xml

C、测试类执行

 

 

数据库的环境切换

a. 切换environment

b.配置数据库支持类Provider别名

<databaseIdProvider type="DB_VENDOR">
    <property name="MySQL" value="mysql"/>
    <property name="Oracle" value="oracle"/>
    <property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>

 

c.写不同数据库的SQL语句

d.在mapper.xml中通过databaseId指定别名

 

2.注解方式

推荐使用xml

A.将sql语句写在接口的方法上@Select(“”);

B.将借口的全类名写入<mapper>,让mybatis知道sql语句

此时是存储在接口中

注解/xml都支持批量引入<package name=”com.yuanqun.mapper”/>

3.增删改的返回值问题

返回值可以是void、Integer、Long、Boolean 如何操作:只需要再接口中 修改返回值即可

 

4.事务提交

  手动提交:

sessionFactory.openSession();

session.commit();

自动提交:每个dml语句 自动提交

sessionFactory.openSession(true);

5.自增问题

   Mysql支持自增

在mapper.xml标签里增加 userGeneratedKeys=”true” keyProperty=”stuNo”就可以获取回写的自增长id值

 

Oracle默认不支持:通过序列模拟自增

Create sequence myseq increment by 1 start with1;

序列自带两个属性

Nextval:当前序列的下一个值

Currval:序列当前的值

Insert into student(myseq.nextval(),’zs’,23,’al’);

<selectKey keyProperty=”stuNo” resultType=”Integer” order=”before”>

Select myseq.nextval from dual

</selectKey>

Insert into student(stuno,stuName,stuAge,graName)

Value(#{stuNo},#{stuName},#{stuAge},#{graName})

 

 

<selectKey keyProperty=”stuNo” resultType=”Integer” order=”after”>

Select myseq.currval from dual

</selectKey>

Insert into student(stuno,stuName,stuAge,graName)

Value(myseq.nextval,#{stuName},#{stuAge},#{graName})

 

6.参数问题

  目前是将多个对象封装在一个javabean对象,然后使用该对象传值。

a.传入多个参数时,不用再Mapper.xml中编写parameterType

只能用 arg0,arg1……或者 param1,param2…..

b.命名参数

 可以在接口中通过Param(“”)指定sql中参数的名字

c.综合使用

Integer addStudent(@Param(“stuNo”) Interger stuNo,@Param(“stu”)Student student)

<insert id="insert" databaseId="mysql" >

  insert into person ( id,pName, age,

  sex, homeAddress, workAddress,

  cardid)

  values (#{id} ,#{per.pname}, #{per.age},

  #{per.sex}, #{per.homeaddress}, #{per.workaddress},

  #{per.cardid})

</insert>

7.增加 null

Oracle:如果输入的参数是null,则提示输入Other而不是null

Mysql:如果插入的字段是Null,可以正常执行(没有约束)

原因:

      各个数据库在mybatis中对各种数据库类型的默认值不一致。

Mybatis中,jdbcTypeForNull(如果是null),则默认值OTHER。Other来说 MySQL能够处理(NULL),但Oracle不行。

解决

Oracle:null->OTHER,需要手工告诉Oracle: other-》null

a. 当某个数据类型Oracle·无法处理时候,,告诉它用默认值null

<insert id="insert" databaseId="oracle" >

  insert into person ( id,pName, age,

  sex, homeAddress, workAddress,

  cardid)

  values (#{id} ,#{per.pname,jdbcType=NULL}, #{per.age},

  #{per.sex}, #{per.homeaddress}, #{per.workaddress},

  #{per.cardid})

</insert>

b.配置mybatis全局配置文件conf.xml

<setting name="jdbcTypeForNull" value="NULL"/>

 

 

8.返回值为HashMap的情况

<select id="selectByPrimaryKeyHashMap" parameterType="java.lang.Integer" resultType="HashMap">

  select stuNo, stuName, stuAge, classId

  from student

  where stuNo = #{stuno,jdbcType=INTEGER}

</select>

 

@MapKey("stuNo")

HashMap<String,Student> selectAllHashMap();

 

9.ResultMap 字段和属性名的对应关系

 

 

10.鉴别器和别名的问题

在resultMap中 还可以使用鉴别器:对相同sql 中不同字段值进行判断,从而进行不同处理

<discriminator javaType="Integer" column="stuAge">
  <case value="20" resultType="com.lifen.entity.Student">
    <result column="nickName" property="stuname"/>
  </case>
  <case value="52" resultType="com.lifen.entity.Student">
    <result column="stuName" property="stuname"/>
  </case>
</discriminator>

 

11.<where> <trim> 标签

<where>只能处理开头的

<trim>可以处理开头和结尾的sql where 拼接

<trim prefix=’where’ suffixOverrides=’and’> 给拼接的SQL加prefix=’where’ 处理结尾的多余的and

<select id="selectByTrim" parameterType="Student" resultMap="BaseResultMap">

  select stuNo, stuName, stuAge, classId,nickName

  from student

  <trim prefix="where" suffixOverrides="and">

    <if test="stuname!=null and stuname!=''">

       stuName like '%${stuname}%' and

    </if>

    <if test="stuage!=null and stuage!=''">

       stuAge=#{stuage} and

    </if>

  </trim>

</select>

<trim prefix=’where’ prefixOverrides=’and’> 给拼接的SQL加prefix=’where’ 处理开头的多余的and

Prefix:拼接

prefixOverrides:删除

 

 

12.内置参数

   _parameter:代表mybatis的输入参数。

   _databaseId:当前数据库类型的名字

 

13.模糊查询

a.${}:        原样输出  N‘%${}%’%

  #{}:自动添加引号

b.传值时,直接传%x%

  student.setStuName(“%s%”);

  stuName like #{stuName}

c.bind参数

<bind name=”_queryName” value=”’%’+stuName+’%’”/>

通过bind将传入的stuName进行了处理

  14.逆向工程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值