java——MyBatis(1)
比较不负责任得说:MyBatis就是将Dao层我们需要与数据库交互的sql语句进行一个规范化地包装并储存在映射配置文件中,方便我们进行修改语句,也避免需要在Dao层编写大量的sql语句;
首先:编写一个主配置文件,这个主配置文件就包括驱动连接数据库并连接各种映射文件;
其次:正常编写servlet接受页面传来数据并将这些数据传入开发好的各种操作中;
再其次,也是MyBatis的作用,Dao层通过配置文件调取SqlSession,然后 用于SqlSession对象提供的方法进行操作;很关键的点就是映射文件,映射文件既要定义好各种操作方法、sql语句,还要定义好数据库各个字段对应好相应对象的各个属性;
最后就是service层,其实这个主要是为了减少servlet的工作量,对传入来的数据或者传出去的数据进行逻辑处理,比如对数据进行一个判断或格式化数据等等的操作,servlet所调用的方法也来自service层,而service层的方法是以Dao层所提供的与数据库进行操作的方法为基础后稍作好逻辑修改形成的;
下面就用一个实例来加深理解:
如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.0</version> </dependency>
一、配置主配置文件
<?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"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///micro_message?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/imooc/config/sqlxml/Message.xml"/> <mapper resource="com/imooc/config/sqlxml/Command.xml"/> <mapper resource="com/imooc/config/sqlxml/CommandContent.xml"/> </mappers> </configuration>
<mapper/>标签对应各个实体类的映射文件;
选其中的Command.xml来解析:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="Command"> <resultMap type="com.imooc.bean.Command" id="Command"> <id column="C_ID" jdbcType="INTEGER" property="id"/> <result column="NAME" jdbcType="VARCHAR" property="name"/> <result column="DESCRIPTION" jdbcType="VARCHAR" property="description"/> <collection property="contentList" resultMap="CommandContent.Content"/> </resultMap> <select id="queryCommandList" parameterType="com.imooc.bean.Command" resultMap="Command"> select a.ID C_ID,a.NAME,a.DESCRIPTION,b.ID,b.CONTENT,b.COMMAND_ID from command a left join command_content b on a.ID = b.COMMAND_ID; <where> <if test="name!=null&&!"".equals(name.trim())">and a.NAME =#{name}</if> <if test="description!=null&&!"".equals(description.trim())">and a.DESCRIPTION like '%' #{description} '%'</if> </where> </select> </mapper>
在Dao层会使用SqlSession对象并调用方法读取这个xml文件:
commandList = sqlSession.selectList("Command.queryCommandList",command);
其中的Command.queryCommandList为标识,分别对应namespace和语句中的id标签;command为实例化后的实体类对象;resultMap标签里column为查询出来的字段名,property为对象里的属性名,为了配置一对多的关系,使用到了collection标签,property同样为对象里一个属性,这个属性为一个集合类,映射包含了另一个对象映射文件xml里的resultMap:
而映射文件里的sql语句就需要借助OGNL表达式和各种标签来达到业务的需求:
对象映射文件xml常用标签总结:
Dao层定义了与数据库操作方法:
package com.imooc.dao; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.ibatis.session.SqlSession; import com.imooc.bean.Command; import com.imooc.bean.Message; import com.imooc.db.DBAccess; public class CommandDao { public List<Command> queryCommandList(String name,String description){ DBAccess dbAccess = new DBAccess(); List<Command> commandList = new ArrayList<Command>(); SqlSession sqlSession = null; try { sqlSession = dbAccess.getSqlSession(); Command command = new Command(); command.setName(name); command.setDescription(description); commandList = sqlSession.selectList("Command.queryCommandList",command); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(sqlSession!=null) { sqlSession.close(); } } return commandList; } }
包含其创建方法的类DBAccess文件为:
package com.imooc.db; import java.io.IOException; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class DBAccess { public SqlSession getSqlSession() throws IOException { //读取配置文件 Reader reader = Resources.getResourceAsReader("com/imooc/config/Configuration.xml"); //构建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); //构建数据库会话SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } }
service层再调用Dao层的方法并做逻辑处理:
package com.imooc.service; import java.util.ArrayList; import java.util.List; import java.util.Random; import com.imooc.bean.Command; import com.imooc.bean.CommandContent; import com.imooc.bean.Message; import com.imooc.dao.CommandDao; import com.imooc.dao.MessageDao; import com.imooc.util.Iconst; /** * 查询相关的业务功能 */ public class QueryService { public List<Message> queryMessageList(String command,String description) { MessageDao messageDao = new MessageDao(); return messageDao.queryMesssageList(command, description); } /** * 通过指令查询自动回复的内容 * @param command 指令 * @return 自动回复的内容 */ public String queryByCommand(String command) { CommandDao commandDao = new CommandDao(); List<Command> commandList = new ArrayList<Command>(); if(Iconst.HELP_COMMAND.equals(command)) { commandList = commandDao.queryCommandList(null, null); StringBuilder result = new StringBuilder(); for(int i = 0; i < commandList.size(); i++) { if(i != 0) { result.append("<br/>"); } result.append("回复[" + commandList.get(i).getName() + "]可以查看" + commandList.get(i).getDescription()); } return result.toString(); } commandList = commandDao.queryCommandList(command, null); if(commandList.size() > 0) { List<CommandContent> contentList = commandList.get(0).getContentList(); int i =new Random().nextInt(contentList.size()); return contentList.get(i).getContent(); } return Iconst.NO_MATCHING_CONTENT; } }
servlet层只做最简单的页面跳转或数据存储或输出:
package com.imooc.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.imooc.service.QueryService; /** * 自动回复功能控制层 */ @SuppressWarnings("serial") public class AutoReplyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); QueryService queryService = new QueryService(); out.write(queryService.queryByCommand(req.getParameter("content"))); out.flush(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
至此,一个简单的Mybatis实例操作完毕!
运行过程:
1、根据web.xml配置的servlet文件对应相应的访问路径,跳转到JSP文件中;
2、JSP会提供各种方法类似查询、删除、增加等等,其实是会再访问到对应的servlet文件;
3、被访问到的servlet层会调用service层,service层会访问Dao层,Dao层再联系对象映射文件操作数据库并执行相应的sql语句,层层递进地执行;
4、执行完后再跳转到对应的JSP页面访问给用户以供继续操作!
Mybatis重点是运用好各种OGNL表达式和各种标签来完成sql语句的拼接,包括一对多或者多对一的配置,对映射文件xml的编写才是Mybatis的重点和难点!!!
queryCommandList