关于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 <=#{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类型。
持续更新…
- 关于mybatis使用的几个小问题
- 关于索引使用的几个小问题
- 关于mybatis的小问题
- 关于directx sdk 使用的几个小问题
- 关于使用kettle4.3版本的几个小问题
- 关于使用mybatis几个功能的实现
- 关于几个小问题
- 关于几个计算机系统的小问题
- 关于wince的几个小问题
- 关于PHP的几个小问题
- 关于索引的几个小问题
- 关于Qt的几个小问题
- 关于NASM的几个小问题
- 链表中关于环的几个小问题
- 关于mysql的几个小问题
- 关于openSessionInViewFilter的几个小问题
- 关于expdp的几个小问题
- 关于面试的几个小问题
- 洛谷 P1251 餐巾计划问题
- 中文乱码问题和拦截器
- goahead之GoAction实现
- 今天总结
- 哈理工 oj 2293 棋盘村 【基础dp】
- 关于mybatis使用的几个小问题
- 相机标定(Camera calibration)原理、步骤
- tree下subtree.node NotImplementedError: Use label() to access a node label.报错
- 临时表
- 我对小班研讨课的感受
- bzoj3261 最大异或和(可持久化Trie)
- D-数圈圈(数位dp)
- 爬虫防爬措施
- ssh