关于mybatis使用的几个小问题

来源:互联网 发布:怎么申请淘宝直播 编辑:程序博客网 时间:2024/05/19 05:40

最近学习web框架做了一些小项目,因为经验不足找bug浪费的时间还是很多的,下面我总结下我遇到的问题,让大家避免踩到同样的坑。
一.框架简述
想到哪写到哪吧。mybatis一共四个核心组件,SQLSessionFactoryBuilder,SqlSessionFactory,SqlSession,和SQL Mapper,我们最常使用的是后两个,对于获取到,SqlSession,如果不用sping整合,我建议写一个工具类,这样测试什么的都比较方便,下面是我写的工具类

public class MybatisUtil {public static SqlSession getSession(){//mybatis配置文件    String resource = "sqlMapConfig.xml";    InputStream inputStream = null;    SqlSession sqlSession = null;    try {    //以流的方式读入        inputStream = Resources.getResourceAsStream(resource);        //构建factory,这里采取的是建造者模式        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //工厂类得到sqlsession        sqlSession =  sqlSessionFactory.openSession();    } catch (IOException e) {        e.printStackTrace();    }    return sqlSession;}

}
这就是固定的模式,所有获取sqlSession都是这么写的,当然,关于构建的过程,还是用到一些设计模式比较复杂的,今天先不说这个。对于mybatis的总配置文件,要注意,mybatis的configuration标签提供大量的可以自定义的配置方式,但是一般情况下用默认的就好,数据库的连接,和mapper这两个一定要自己配置的,如果忘了,会出错。

//数据库连接配置 <environments default="development">        <environment id="development">            <transactionManager type="JDBC"/>            //采用内部提供的连接池的方式                <dataSource type="POOLED">                    <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>                    <property name="url" value="jdbc:oracle:thin:@localhost:1521:LOVE"/>                    <property name="username" value="scott"/>                    <property name="password" value="tiger"/>                                   </dataSource>        </environment>    </environments>    //mapper包的导入    <mappers>        <package name="com.easy.Mapper"/>    </mappers>

其他的还可以定义一些别名神马额特殊功能,如果有特殊需求,可以参照官方API。
二.一些细节问题
1.数据表名和类名对应,字段名和类的字段名最好相同
对于这个问题,我是强烈建议都写成一样的,其实,按道理来讲怎么写都行,但是当表字段等一多,放个比较复杂的查询,如果你不用mybatis提供的自动映射的方式,自己写mapper,那么我跟你说,这是极其浪费时间的,而且很容易出错。记得前几天我因为这个问题浪费了一晚上时间,所以尽量减少这种冗余的配置代码。
2.传递参数方式的选择
根据我的体会,如果不是基本数据类型,那么就采用javabean的方式,这样符合面向对象的思想,又可以通过这种方式传递多个参数。但是有一种情况

int deletePL(@Param("i") int[] ids);
<delete id="deletePL" parameterType>        delete from book where id in        <foreach collection="i" open="(" close=")" separator="," item="id">            #{id}        </foreach>    </delete>

这个我做练习图书管理的批量删除部分代码,像这种要传递一个数组,就要用@Param注解了,因为mybatis没有提供数组类型的parameterType类型,但是用注解这种形式,就不用声明类型,Mybatis会自动扫描typeHandler,关于typehandler我之后再说。mybatis还提供了一种map方式传参的方式,本人不太喜欢。javabean的形式是推荐使用的。
3.model类的所有属性必须提供getter,setter方法
mybatis映射结果集,数据库中插入数据,就是调用的getter,setter方法,然后根据typehandler进行。
4.包名写全

<typeAliases>    <package name="com.easy.model"/></typeAliases> 

在mybatis配置文件中插入这段代码,在写mapper时可以省略包名,但是我真的不建议这么做,有的时候回莫名奇妙的出现类型找不到的问题,那么在检查代码时,又要考虑是不是类所在的包路径不对?包名冲突?况且这样写,当类包变得多时,维护起来很麻烦。所以,包名写全。
5.sql要数量,在sqldeveloper调试好
因为sql是以字符串的形式存在的,如果在mybatis中测试,那么出错的可能性很大,而且这种问题找起来很浪费时间,所以建议在熟练使用sql的情况下,在数据库客户端调试好。

6.sql问题

<select id="selectAllBooks" resultType="com.easy.model.Book">    select id,name,author,press,pressdate from(     select rownum r,id,name,author,press,pressdate      from book )     where r >=#{begin} and r &lt;=#{end} </select>

也是截取我项目中的一个例子,在XML中,’<’符号后被读成标签的结束符号,这里需要用XML提供的<代替<。
还有一个问题,Oracle数据库跟mysql数据库在sql上有一些区别,在做分页时,Oracle会稍微复杂一些,关于sql和分页的总结,我整理完,分享给大家。
7.级联问题
这个我要说的是,在实践前要把表的结构设计好,级联的数量不要抄过三级。如果级联的数量过多,配置会非常复杂,容易出错,而且性能也会变得非常低。
下面说几个标签

<association></association>:取一个我项目中的部分:
 <resultMap type="com.easy.model.Book" id="c">        <id column="id" property="id"/>        <result column="name" property="name"/>        <result column="author" property="author"/>        <result column="press" property="press"/>        <result column="pressdate" property="pressdate"/>        <association property="store" javaType="com.easy.model.Store">            <id column="store_id" property="store_id"/>            <result column="name" property="name"/>            <result column="address" property="address"/>           </association>    </resultMap>

这个是配置级联的关键标签,这里我建议将要配置的属性都写出来,而用他提供的select标签,会引发N+1问题,我不喜欢用,用这种方式,看着也比较清晰

<collection></collection>这个是配置集合用的标签,注意元素类型用的是oftype<disciminator></discriminator>mybatis提供的鉴别器,个人觉得挺好用

8.动态sql
mybatis相对于前几年流行的hibernate,提供强大的动态sql的功能。
8.1 where,if 标签:

<select id="selectAll" resultType="com.easy.model.Book" parameterType="com.easy.model.Book">                select book_id,book_name,authorfrom book                     <where>                        <if test="book_name != null and book_name != ''">                             book_name like #{book_name}                        </if>                        <if test="author != null and author != ''">                              and author like #{author}                        </if>                    </where>             </select>

这里举了个例子,这个标签是非常重要的,我建议尽量都写成动态sql的这种形式,我记得我开始因为没用动态sql进行判断,插入数据时一直报错,说javaType类型找不到,我废了好长时间,最后看底层原理最终才明白,实际上,每当插入数据时,mybatis会根据插入的数据自动找到合适的TypeHandler进行java类型和sql类型转换,而如果插入null,那么mybatis就会找不到对应的TypeHandler,那么当然报类型找不到的错啦,所以,为了防止这种事情发生,就用动态sql判断。另外,where这个标签还会自动的将第一个and去掉,非常方便。
8.2 自定义主键
selectKey标签:

 <insert id="add" parameterType="com.easy.model.Book">        <selectKey order="BEFORE" keyProperty="book_id" >            select seq_bookid.nextval from dual        </selectKey>            INSERT INTO BOOK(BOOK_ID,BOOK_NAME,AUTHOR,PUBLISHER)             VALUES(#{book_id},#{book_name},#{author},#{publisher})    </insert>
这个标签用来处理自定义主键,要注意,在Oracle中,主键不默认自增,与mysql不同,他提供了序列这样一个对象,相信大家都很熟悉了。

8.3 foreach标签

<delete id="deletePL">            delete from book where book_id in                 <foreach collection="i" open="(" close=")" separator="," item="id">                        #{id}                </foreach>        </delete>这个就是用来遍历集合或数组的,上面已经介绍过了

9.日期处理
日期处理在开发中很常见,以前用Date类型转来转去很容易出错,我觉得这样处理比较好。

    <update id="update" parameterType="Book">            update book set book_name=#{book_name},            author=#{author},            publisher=#{publisher},            pubdate=to_date(#{pubdate},'yyyy-mm-dd')            where book_id=#{book_id}    </update>

如上所示,sql中提供了一个to_Date(,’yyyy-mm-dd’)函数,第一个参数是字符串类型,第二个参数是格式,可以自己指定。这个函数可以将字符串类型转换为Sql中的Date类型,我建议将所有的日期都写成String,然后用这个函数,sql中还提供了to_String()hans函数,但是我测试直接使用select也没出错,应该是自动转换成String类型。
持续更新…

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩有口臭怎么办这几天不想吃饭 七个月宝宝口臭不想吃饭怎么办啊 老公工作累想要辞职不上班怎么办 药物流产后第6天咋下坠的怎么办 药流第一天胎囊没有掉下来怎么办 药流还有一点没流干净怎么办 3个月的宝宝被电了一下怎么办 宝宝吃奶粉过敏下巴红有疙瘩怎么办 小孩牙齿没掉又长出新牙怎么办 8个月婴儿地包天怎么办 欠别人很多钱 要告我怎么办 ps意外的遇到文件尾损坏了怎么办 长期作息不规律引起的头疼怎么办 退休年龄到了社保没满15年怎么办 要退休了单位把我工资表丢了怎么办 非工伤单位不支付病假工资怎么办 十个月宝宝咳嗽有痰怎么办崔玉涛 怀孕五个月胎儿脐带绕颈怎么办 6个月宝宝白天睡眠不好怎么办 22个月宝宝身高才79公分怎么办 宝宝十个月了还没长牙怎么办 腰椎间盘突出翻身都困难了怎么办 上课很困怎么办犯困快速清醒的绝招 孩子上小学放学早父母上班怎么办 想玩滑冰鞋的手受伤了怎么办? 美团酒店商家入住没审核通过怎么办 顺丰离职人员被列入黑名单怎么办 洗了衣服晾起来衣服被拉长了怎么办 宝宝拉肚子半个月了还不好怎么办 宝宝咳嗽半个月了还不好怎么办 顾客试了一大堆衣服不买怎么办 宝宝屁屁用尿布捂的红的怎么办? 车被别人撞了人跑了怎么办 在无锡小孩超龄上不了学怎么办 我把共享单车二维码弄坏了怎么办 车里坐垫整上柴油了怎么办 双人骑自行车车坐压往后仰了怎么办 穿高帮钉鞋踢人造草出现水泡怎么办 耐克大吕布鞋面上的标志起来怎么办 国三柴油车环保查尾气超标怎么办 手上被玻璃手上扎进玻璃丝怎么办