mybatis初接触
mybatis 是一个数据库操作的持久层框架,能够执行普通的 SQL 查询,消除了几乎所有的 jdbc 代码和参数的手工设置,取而代之的是较为简洁的 XML 文件或注解,总的来说是一个优秀的数据库操作框架。
mybatis 的初步使用
1、引入 mybatis 的相关 jar 包 或者依赖注入
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.5</version> </dependency>
2、建立 mybatis-configuration.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <!--id属性必须和上面的default一样 --> <environment id="development"> <!--事务管理器 一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围 二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期 比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样, 因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如: <transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager> --> <transactionManager type="JDBC"/> <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://xxxxxxx/abcd?useUnicode=true"/> <property name="username" value="xxxx"/> <property name="password" value="xxx"/> </dataSource> </environment> </environments> </configuration>
可以看到,mybatis-configuration.xml 主要是配置了事物管理器和数据库的连接设置。
3、创建一个实例类,类与所需获取的表中的要查询的字段一一对应,以一个 survey 表为例, 这个表总共有如下这些字段
@Data @NoArgsConstructor public class SurveyBean { public String questId; public String sceneId; public String surveyId; public String name; public String version; public String seq; public String type; public String required; public String createTime; }
4、创建一个操作 survey 表的的 xml 文件 surveyMapper.xml
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.study.hugy.surveyMapper"> <select id="selectAllSurvey" resultType="com.study.hugy.modal.SurveyBean"> SELECT survey_id 'surveyId', quest_id 'questId', scene_id 'sceneId', quest_name 'name', version, quest_seq 'seq', quest_type 'type', required FROM survey_quest </select> <select id="selectByCondition" resultType="com.study.hugy.modal.SurveyBean" parameterType="string"> SELECT survey_id 'surveyId', quest_id 'questId', scene_id 'sceneId', quest_name 'name', version, quest_seq 'seq', quest_type 'type', required FROM survey_quest WHERE quest_id = #{id} </select> <update id="updateByCondition" parameterType="com.study.hugy.modal.SurveyBean"> UPDATE survey_quest SET quest_name = #{name}, version = #{version} WHERE quest_id = #{questId} </update> </mapper>
5、添加 mapper 文件到 mybatis-configuration.xml 文件
<configuration> <mappers> <mapper resource="surveyMapper.xml"/> </mappers> </configuration>
6、编写测试文件
public class SurveyMapperTest { SqlSession session; @Before public void beforeLoadXml() { InputStream inputStream = SurveyMapperTest.class. getClassLoader().getResourceAsStream("mybatis-configuration.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); session = sqlSessionFactory.openSession(); } @Test public void testSelect() { String statement = "com.study.hugy.surveyMapper.selectAllSurvey"; List<SurveyBean> bean = session.selectList(statement); session.close(); } @Test public void testSelectByCondition () { String statement = "com.study.hugy.surveyMapper.selectByCondition"; String id = "101"; List<SurveyBean> beans = session.selectList(statement, id); session.close(); } @Test public void testUpdateByCondition () { String statement = "com.study.hugy.surveyMapper.updateByCondition"; SurveyBean bean = new SurveyBean(); bean.setQuestId("101"); bean.setName("这是测试哦"); bean.setVersion("321"); session.update(statement, bean); session.commit(); session.close(); } }
以上基本就可以将 mybatis 使用起来了,附上项目的目录文件结构
插个题外话,如何使用 log4j 在控制台打印 mybatis 要执行的SQL?
1) 添加依赖
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
2)新建 log4j.properties 文件
### Log4j配置 ###
### 与Spring结合需要在web.xml中指定此文件位置,并添加监听器 ###
#定义log4j的输出级别和输出目的地(目的地可以自定义名称,和后面的对应)
#[ level ] , appenderName1 , appenderName2
log4j.rootLogger=DEBUG,console,file
#-----------------------------------#
#1 定义日志输出目的地为控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
####可以灵活地指定日志输出格式,下面一行是指定具体的格式 ###
#%c: 输出日志信息所属的类目,通常就是所在类的全名
#%m: 输出代码中指定的消息,产生的日志具体信息
#%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#-----------------------------------#
#2 文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.file = org.apache.log4j.RollingFileAppender
#日志文件输出目录
log4j.appender.file.File=log/tibet.log
#定义文件最大大小
log4j.appender.file.MaxFileSize=10mb
###输出日志信息###
#最低级别
log4j.appender.file.Threshold=ERROR
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#-----------------------------------#
#3 druid
log4j.logger.druid.sql=INFO
log4j.logger.druid.sql.DataSource=info
log4j.logger.druid.sql.Connection=info
log4j.logger.druid.sql.Statement=info
log4j.logger.druid.sql.ResultSet=info
#4 mybatis 显示SQL语句部分
log4j.logger.org.mybatis=DEBUG
#log4j.logger.cn.tibet.cas.dao=DEBUG
#log4j.logger.org.mybatis.common.jdbc.SimpleDataSource=DEBUG#
#log4j.logger.org.mybatis.common.jdbc.ScriptRunner=DEBUG#
#log4j.logger.org.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG#
#log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3)在 web.xml 添加监听
<listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener>
4)在 mybatis-configuration.xml 中使用 log4j
<settings> <setting name="logImpl" value="LOG4J"></setting> </settings>
注意一点 mybatis-configuration.xml 中添加的标签是有顺序的,顺序错误会导致加载此配置文件报错。
然后再来看看如何使用注解来实现 mybatis 的使用。
步骤 1,2,3 不变,有变化是从第四步开始, 使用注解需要 XxxMapper.xml 文件, 取而代之的是一个 interface --- XxxMapper
public interface SurveyMapper { @Select("SELECT * FROM survey_quest") List<SurveyBean> selectAllQuest(); @Select("SELECT * FROM survey_quest WHERE quest_id = #{id}") List<SurveyBean> selectByCondition(String id); @Select("UPDATE survey_quest SET quest_name = #{name}, version=#{version} WHERE quest_id = #{questId}") void updateByCondition(SurveyBean bean); }
然后在 mybatis-configuration.xml 文件中注册此 mapper 类
<mapper class = "com.study.hugy.mapper.SurveyMapper"/>
使用的话,如下所示:
@Test public void selectAllSurvey () { SurveyMapper mapper = session.getMapper(SurveyMapper.class); List<SurveyBean> list = mapper.selectAllQuest(); session.close(); } @Test public void selectByCondition() { SurveyMapper mapper = session.getMapper(SurveyMapper.class); List<SurveyBean> list = mapper.selectByCondition("101"); session.close(); } @Test public void updateByCondition () { SurveyMapper mapper = session.getMapper(SurveyMapper.class); SurveyBean bean = new SurveyBean(); bean.setQuestId("101"); bean.setName("这是注解啊"); bean.setVersion("321"); mapper.updateByCondition(bean); session.commit(); session.close(); }
了解了这些,mybatis 的就能使用起来了,总结一下需要注意的几点:
1、关于 sql 中参数的设置,如果只有一个,可以随意设置,但是如果有多个(一个实例类), sql 中的命名一定要与实例类的属性名称一致;
2、如果遇到乱码问题,检查页面的编码和数据库操作的编码是否一致,如页面使用的是 utf-8 ,添加数据库的 url 的时候可以在后面加上 ?useUnicode=true&characterEncoding=utf-8;
3、就是上面提到过的 mybatis-configuration.xml 中标签的顺序问题,不要弄错,否则会报错的;
---- mybatis 进阶应用 动态 sql 问题
所谓的动态 sql ,就是根据不同的情况, 条件会发生变化的 sql 语句, 针对这种情况 mybatis 在 mapper.xml 文件中提供了一些标签来解决;
1、 if 标签
SELECT * FROM STUDENT WHERE 1 = 1 <if test="studentId !=null"> AND STUDENT_ID = #{studentId} </if> <if test = "studentName != null"> AND STUDENT_NAME = #{studentName} </if>
2、 foreach 标签
foreach 标签是一个循环用的标签,在传入的参数中有集合的时候使用, 可以将集合中的条目方便的取出
INSERT INTO STUDENT (STUDENT_ID, STUDENT_NAME) VALUES <foreach collection="students" item="item" index="index" separator=","> (#{item.studentId}, #{item.studentName}) </foreach>
3、choose/when/otherwise
相当于 java 中的 if ... else if ... else
SELECT * FROM STUDENT WHERE 1= 1 <choose> <when test="studentId != null"> AND STUDENT_ID = #{studentId} </when> <when test="studentName != null"> AND STUDNET_NAME = #{studentName} </when> <otherwise> AND STUDENT_AGE BETWEEN 1 AND 3 </otherwise> </choose>
还有一些生成动态 sql 的标签,可以参考一下的网址: http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html
也写一些使用时的注意事项吧:
使用 SqlSession 传参数的时候 如果参数是一个常量类型 在 sql 中可以直接使用 #{1} 之类的来调用
使用 SqlSession 传递引用类型的参数, sql 中能拿到的值一定是 此参数的属性值,比如 你传递了一个 STUDENT 对象 ,名为 zhangsan ,你在 sql 中使用 #{zhangsan.studentName} 是拿不到值的,必须使用 #{studentName}, 所以如果使用 foreach 标签做循环的时候,如果只是传入一个集合, 记得要将他封装一层,不然你是拿不到的(好麻烦)
关于 mybatis 就讲到这里了。勤于学习,勤于总结!!!