NO.2 Mybatis 实际项目的使用
2017-11-04 21:55
267 查看
NO.2 Mybatis 实际项目的使用
依旧采用MVC的编程模式,分三个层,Controller,Service,Dao,Dao层用接口定义,UserDaoImpl实现接口Dao。
那么我们来考虑一个问题,是注入一个SqlSession还是注入一个SqlSessionFactory?
如果注入session可能存在资源的抢占,session过程中可能关闭,如果同时进行另一操作,可能因资源已关闭而报错(线程问题)。因此,应该注入factory,每次打开session,再关闭资源。
然而,每个方法中都要打开关闭资源,我们可以让mybatis自动生成模板,进行代理。
对传统Dao层代码需求:
1>在Dao层实现类中,存在大量模板方法,能否将其提炼模板方法,减少工作量。
2>将statementId硬编码到了Dao层实现类。
硬编码:指将可变变量用一个固定值来代替的方法。然而,若不是采用配置的方法,若想修改,必须修改源代码再进行编译。大部分程序语言里,可以将一个固定数值定义为一个标记,然后用这个特殊标记来取代变量名称。
在做足了应用准备工作后,下面我们举出具体的例子进行说明。
首先我们定义一个Dao层接口
然后,写一个Dao层的实现类
从以上的方法中,我们能够看到存在大量模板方法,而我们的工作也是正在一步步减少代码的繁杂,多余,重复,这正是我们经常提及的提高代码服用性(去重思想)。
为了满足需求一,我们采用代理类Mapper来开发Mybatis。
采用mapper代理的方式进行dao层的开发,需要有几个约定(约定大于配置)
1:XXXMapper.xml中(sql所在的配置文件)的namespace值需要与Dao接口中的全类名相同 (确定了哪一个XXXMapper.xml配置文件)。
2:XXXMapper.java接口中的方法名与XXXMapper.xml中的statementId相同(确定了使用哪个sql)。
3:XXXMapper.java接口中的方法输入参数需要与XXXMapper.xml中的ParameterType定义的类型相同。
4:XXXMapper.java接口中的方法返回值类型需要与XXXMapper.xml中的resultType定义的类型相同。
(约定大于配置,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。本质是说,开发人员仅需规定应用中不符约定的部分。)
类似的,首先我们定义一个Mapper接口
然后,写一个Mapper的实现类
类似于上一篇博客中的sql语句的xml文件,我们同样的写一个userMapper.xml
依旧采用MVC的编程模式,分三个层,Controller,Service,Dao,Dao层用接口定义,UserDaoImpl实现接口Dao。
那么我们来考虑一个问题,是注入一个SqlSession还是注入一个SqlSessionFactory?
如果注入session可能存在资源的抢占,session过程中可能关闭,如果同时进行另一操作,可能因资源已关闭而报错(线程问题)。因此,应该注入factory,每次打开session,再关闭资源。
然而,每个方法中都要打开关闭资源,我们可以让mybatis自动生成模板,进行代理。
对传统Dao层代码需求:
1>在Dao层实现类中,存在大量模板方法,能否将其提炼模板方法,减少工作量。
2>将statementId硬编码到了Dao层实现类。
硬编码:指将可变变量用一个固定值来代替的方法。然而,若不是采用配置的方法,若想修改,必须修改源代码再进行编译。大部分程序语言里,可以将一个固定数值定义为一个标记,然后用这个特殊标记来取代变量名称。
在做足了应用准备工作后,下面我们举出具体的例子进行说明。
首先我们定义一个Dao层接口
package com.xt.mybatis.hi.user.dao; import com.xt.mybatis.hi.user.entity.UserInfo; public interface UserDao { public UserInfo queryUserInfoById(Integer userId); public void insertUserInfo(UserInfo ui); public void deleteUserInfoById(Integer userId); public void updateUserInfo(UserInfo ui); }
然后,写一个Dao层的实现类
package com.xt.mybatis.hi.user.dao; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import com.xt.mybatis.hi.user.entity.UserInfo; public class UserDaoImpl implements UserDao{ private SqlSessionFactory sqlSessionFacory; public UserInfo queryUserInfoById(Integer userId) { SqlSession ss = sqlSessionFacory.openSession(); //sqlSession调用的方法,返回的是泛型,没有强转,即使参数传入错误,依旧能编译,只是不能执行 UserInfo ui = ss.selectOne("com.xt.mybatis.queryUserInfoById",1); ss.close(); return ui; } public void insertUserInfo(UserInfo ui) { SqlSession ss = sqlSessionFacory.openSession(); ss.update("com.xt.mybatis.insertUserInfo",ui); ss.commit(); ss.close(); } public void deleteUserInfoById(Integer userId) { SqlSession ss = sqlSessionFacory.openSession(); ss.update("com.xt.mybatis.deleteUserInfoById",4); ss.commit(); ss.close(); } public void updateUserInfo(UserInfo ui) { SqlSession ss = sqlSessionFacory.openSession(); ss.update("com.xt.mybatis.updateUserInfo",4); ss.commit(); ss.close(); } public SqlSessionFactory getSqlSessionFacory() { return sqlSessionFacory; } public void setSqlSessionFacory(SqlSessionFactory sqlSessionFacory) { this.sqlSessionFacory = sqlSessionFacory; } }
从以上的方法中,我们能够看到存在大量模板方法,而我们的工作也是正在一步步减少代码的繁杂,多余,重复,这正是我们经常提及的提高代码服用性(去重思想)。
为了满足需求一,我们采用代理类Mapper来开发Mybatis。
采用mapper代理的方式进行dao层的开发,需要有几个约定(约定大于配置)
1:XXXMapper.xml中(sql所在的配置文件)的namespace值需要与Dao接口中的全类名相同 (确定了哪一个XXXMapper.xml配置文件)。
2:XXXMapper.java接口中的方法名与XXXMapper.xml中的statementId相同(确定了使用哪个sql)。
3:XXXMapper.java接口中的方法输入参数需要与XXXMapper.xml中的ParameterType定义的类型相同。
4:XXXMapper.java接口中的方法返回值类型需要与XXXMapper.xml中的resultType定义的类型相同。
(约定大于配置,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。本质是说,开发人员仅需规定应用中不符约定的部分。)
类似的,首先我们定义一个Mapper接口
package com.xt.mybatis.hi.user.mapper; import java.util.List; import java.util.Map; import com.xt.mybatis.hi.user.entity.UserInfo; public interface UserMapper { public List<UserInfo> queryUserInfoById(Integer userId); public List<UserInfo> queryUserInfo(Map<String,String> map); public void insertUserInfo(UserInfo ui); public void deleteUserInfoById(Integer userId); public void updateUserInfo(UserInfo ui); }
然后,写一个Mapper的实现类
package com.xt.mybatis.hi.user.mapper; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import or ba3a g.junit.Test; public class UserMapperTest { SqlSession ss = null; @Before public void myBatisInit(){ try { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis/mybatis-config.xml")); ss = sqlSessionFactory.openSession(); } catch (IOException e) { e.printStackTrace(); } } @Test public void queryUserInfoById(){ UserMapper um = ss.getMapper(UserMapper.class); System.out.println("UserInfo----------->" + um.queryUserInfoById(2)); ss.close(); } @Test public void queryUserInfo(){ UserMapper um = ss.getMapper(UserMapper.class); Map<String,String> map = new HashMap<String,String>(); map.put("userName", "jj"); map.put("telNo", "12414"); System.out.println("userInfo==============>" + um.queryUserInfo(map)); ss.close(); } }
类似于上一篇博客中的sql语句的xml文件,我们同样的写一个userMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xt.mybatis.hi.user.mapper.UserMapper"> <!-- 如果查询语句中的字段名与输出属性不一样,不能实现映射也就查询不到数据,但每次都要规定。 为了提高代码复用性,可以在userMapper.xml中配置resultMap——数据字段名与输出属性的一个对应。 type:代表输出的javaBean类型 主键<id column="数据库中的字段名" property="属性名"/> 当有多个查询条件时,可以将其封装到map中,传入参数为一个map,map一般声明在最上方。 --> <resultMap type="com.xt.mybatis.hi.user.entity.UserInfo" id="userInfoMap"> <id column="user_id" property="userId" /> <result column="user_name" property="userName"/> <result column="tel_no" property="telNo"/> </resultMap> <select id="queryUserInfoById" parameterType="map" resultMap="userInfoMap"> select * from user_info where user_id = #{userId} </select> <select id="queryUserInfo" parameterType="string" resultMap="userInfoMap"> select * from user_info where user_name like '%${userName}%' and tel_no = #{telNo} </select> <insert id="insertUserInfo" parameterType="com.xt.mybatis.hi.user.entity.UserInfo"> insert into user_info values (#{userId},#{userName},password(#{passwd}),#{telNo},#{email}) </insert> <update id="updateUserInfo" parameterType="com.xt.mybatis.hi.user.entity.UserInfo"> update user_info set user_name = #{userName},tel_no = #{telNo},email = #{email} where user_id = #{userId} </update> <delete id="deleteUserInfoById" parameterType="int"> delete from user_info where user_id = #{value} </delete> </mapper>
相关文章推荐
- 在实际项目中使用mybatis获取距离和查周边的实现
- [转帖]实际项目中可使用的性能需求
- 实际项目中使用Postsharp
- log4j 日志服务器_项目实际使用日记
- (android 互联网开发)2 访问https接口,进行数据交互(已在实际项目中使用)
- (7)java5线程并发库的应用(线程池) 以及在实际项目中的使用。。
- 分享.NET开发中经常使用到的代码片段 完全从实际项目中提取出来,也可被反反复复的重复借用
- log4j在web项目中的实际使用
- Nodejs, MemCacheD 在实际项目中的使用
- 方法描述Mybatis使用之NEIS项目
- 关于CListCtrl 实际项目中的一些简单使用
- Map String数组的使用(业务逻辑)---实际项目中的问题
- boost 在实际项目中的使用
- 访问https接口,进行数据交互(已在实际项目中使用)
- Nhibernate在实际项目中的使用
- boost在实际项目中的使用
- 实际项目中简单工厂及委托的继承的使用
- Nodejs, MemCacheD 在实际项目中的使用
- log4j在web项目中的实际使用与jboss冲突
- log4j 日志服务器_项目实际使用日记