1.原始Dao开发方式
原始Dao开发方法需要程序员编写Dao接口和Dao实现类。
1.映射文件:(user.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="test">
<select id="findUserById" parameterType="int" resultType="com.huihui.pojo.User">
select * from user where id=#{id}
</select>
<select id="findUserByUsername" parameterType="java.lang.String" resultType="com.huihui.pojo.User">
select * from user where username like '%${value}%'
</select>
<insert id="insertUser" parameterType="com.huihui.pojo.User" >
insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
</insert>
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
<update id="updateUser" parameterType="com.huihui.pojo.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
2.Dao接口:
package com.huihui.dao;
import java.util.List;
import com.huihui.pojo.User;
public interface UserDao {
public User findUserById(int id) throws Exception;
public List<User> findUserByName(String name) throws Exception;
public void insertUser(User user) throws Exception;
public void deleteUser(int id) throws Exception;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
3.Dao接口实现类:
package com.huihui.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.huihui.pojo.User;
public class UserDaoImpl implements UserDao{
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.close();
return user;
}
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser", id);
sqlSession.commit();
sqlSession.close();
}
@Override
public List<User> findUserByName(String name) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.selectList("test.findUserByUsername", name);
sqlSession.close();
return null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
4.加载user.xml文件
修改SqlMapConfig.xml文件:
<mappers>
<mapper resource="sqlmap/user.xml"/>
</mappers>
5.测试代码:
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception{
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserById(1);
System.out.println(user);
}
@Test
public void testFindUserByName() throws Exception{
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
List<User> list = userDao.findUserByName("张");
System.out.println(list.size());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
分析原始Dao开发方式存在的问题:
原始Dao开发中存在以下问题:
- Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
- 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不利于开发维护。
- 调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
2.mapper动态代理的方法
实现原理
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
- Mapper.xml文件中的namespace与mapper接口的类路径相同。
- Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
- Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
- Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
只有遵循以上规范,mybatis才可以自动生成mapper接口的实现类代理对象。
其实以上的规范主要为了相对于dao实现类中的以下方法进行了自动生成:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
sqlSession.delete("test.deleteUser", id);
sqlSession.selectList("test.findUserByUsername", name);
...
1.映射文件(UserMapper.xml文件):
定义mapper映射文件UserMapper.xml(内容同User.xml一样),需要修改namespace的值为UserMapper接口路径。将UserMapper.xml放在classpath下mapper目录下。
<?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.huihui.mapper.UserMapper">
<select id="findUserById" parameterType="java.lang.Integer" resultType="com.huihui.pojo.User">
select * from user where id=#{id}
</select>
<select id="findUserByUsername" parameterType="java.lang.String" resultType="com.huihui.pojo.User">
select * from user where username like '%${value}%'
</select>
<insert id="insertUser" parameterType="com.huihui.pojo.User" >
insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
</insert>
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
<update id="updateUser" parameterType="com.huihui.pojo.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
2.接口(UserMapper.Java文件)
接口定义有如下特点:
- Mapper接口方法名和Mapper.xml中定义的statement的id相同
- Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
- Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
package com.huihui.mapper;
import java.util.List;
import com.huihui.pojo.User;
/**
* mapper接口,相当于dao接口
* 用户管理
* @author 62347
*
*/
public interface UserMapper {
public User findUserById(int id) throws Exception;
public List<User> findUserByUsername(String name) throws Exception;
public void insertUser(User user) throws Exception;
public void deleteUser(int id) throws Exception;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
3.加载UserMapper.xml文件
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
4.测试代码:
package com.huihui.mapper
import java.io.InputStream
import java.util.Date
import java.util.List
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 org.junit.Test
import com.huihui.pojo.User
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory
@Before
//此方法是运行下面的测试用例的方法之前执行的
public void setUp() throws Exception{
//创建sqlSessionFactory
//mybatis配置文件路径
String resource = "SqlMapConfig.xml"
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource)
//创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)
}
@Test
public void testFindUserById() throws Exception {
//通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession()
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)
User user = userMapper.findUserById(30)
System.out.println(user)
sqlSession.close()
}
@Test
public void testFindUserByName() throws Exception {
//通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession()
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)
List<User> list = userMapper.findUserByUsername("张")
System.out.println(list.size())
sqlSession.close()
}
@Test
public void testInsertUser() throws Exception {
//通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession()
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)
User user = new User()
user.setSex("2")
user.setBirthday(new Date())
user.setAddress("北京丰台")
user.setUsername("哒哒哒")
userMapper.insertUser(user)
sqlSession.commit()
sqlSession.close()
}
@Test
public void testDeleteUser() throws Exception {
//通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession()
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)
userMapper.deleteUser(30)
sqlSession.commit()
sqlSession.close()
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
重点说明:
- selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。 - mapper接口输入参数只能有一个,是否不利于系统扩展维护?
系统框架中,dao层的代码是被业务层公用的。即使mapper接口中只有一个参数,也可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层中方法的参数可以是包装类型(eg:map,…..),但是service方法中不建议使用包装类型(原因:不利于业务层的可扩展)。