Mybatis学习

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习相关的知识,希望对你有一定的参考价值。

5.Mybatis开发dao

Mybatis在项目中主要使用的地方就是开发dao(数据访问层),所以下面讲解一下Mybatis开发dao的方法.有两种方式:原始dao开发方式、mapper代理开发方式(推荐).

5.1 需求

1.根据用户ID查询用户信息

2.根据用户名称模糊查询用户列表

3.添加用户

5.2 原始dao开发方式

及开发dao接口和dao实现

5.2.1 dao接口

 

技术分享
 1 package com.jxdd.mybatis.service;
 2 
 3 import java.util.List;
 4 
 5 import com.jxdd.mybatis.po.User;
 6 
 7 public interface UserDao {
 8     //1.根据用户ID查询用户信息
 9     public User findUserById(int id);
10     //2.根据用户名称模糊查询用户列表
11     public List<User> findUserByName(String name);
12     //3.添加用户
13     public void insertUser(User user);
14 }
UserDao

 

5.2.2 dao实现类

通过入门程序,大家可以看出,在测试代码中,有大量的重复代码。所以我们第一反应就是想给它抽取出共性的部分,但是SqlSession、SqlSessionFactory、SqlSessionFactoryBuilder有着各自的生命周期,因为这些生命周期的不同,抽取时要有针对性的处理。

所以在抽取之前,我们先来了解并总结下它们三个的生命周期。

1.SqlSessionFactoryBuilder

它的作用只是通过配置文件创建SqlSessionFactory,所以只要创建出SqlSessionFactory,它就可以销毁了。所以说,它的生命周期是在方法之内。

2.SqlSessionFactory

 

它的作用是创建SqlSession的工厂,工厂一旦创建,除非应用停掉,不要销毁。所以说它的生命周期是在应用范围内。这里可以通过单例模式来管理它。在mybatis整合spring之后,最好的处理方式是把SqlSessionFactory交由spring来做单例管理。

3.SqlSession

SqlSession是一个面向用户(程序员)的接口,它的默认实现是DefaultSqlSession。

Mybatis是通过SqlSession来操作数据库的。SqlSession中不仅包含要处理的SQL信息,还包括一些数据信息,所以说它是线程不安全的,因此它最佳的生命周期范围是在方法体之内。

技术分享
 1 package com.jxdd.mybatis.service.impl;
 2 
 3 import java.util.List;
 4 
 5 import org.apache.ibatis.session.SqlSession;
 6 import org.apache.ibatis.session.SqlSessionFactory;
 7 
 8 import com.jxdd.mybatis.po.User;
 9 import com.jxdd.mybatis.service.UserDao;
10 
11 public class UserDaoImpl implements UserDao {
12     //外部注入sqlSessionFactory实例
13     private SqlSessionFactory sqlSessionFactory;
14     
15     public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
16         this.sqlSessionFactory = sqlSessionFactory;
17     }
18 
19     @Override
20     public User findUserById(int id) {
21         SqlSession sqlSession = sqlSessionFactory.openSession();
22         //通过sqlsession调用增删改查方法
23         //第一个参数:statement的唯一标识,写法:namespace+"."+statementId
24         //第二个参数:输入参数
25         User user = sqlSession.selectOne("findUserById", id);
26         System.out.println(user);
27         //关闭资源
28         sqlSession.close();
29         return user;
30     }
31 
32     @Override
33     public List<User> findUserByName(String name) {
34         SqlSession sqlSession = sqlSessionFactory.openSession();
35         //通过sqlsession调用增删改查方法
36         //第一个参数:statement的唯一标识,写法:namespace+"."+statementId
37         //第二个参数:输入参数
38         List<User> user = sqlSession.selectList("test.findUsersByName", name);
39         System.out.println(user);
40         //关闭资源
41         sqlSession.close();
42         return user;
43     }
44 
45     @Override
46     public void insertUser(User user) {
47         SqlSession sqlSession = sqlSessionFactory.openSession();
48         //通过sqlsession调用增删改查方法
49         //第一个参数:statement的唯一标识,写法:namespace+"."+statementId
50         //第二个参数:输入参数
51         sqlSession.insert("test.insertUser", user);
52         //注意一定要commit
53         sqlSession.commit();
54         //关闭资源
55         sqlSession.close();
56     }
57 
58 }
UserDaoImpl

 

5.2.3 测试方法

 

技术分享
 1 package com.jxdd.mybatis.test;
 2 
 3 import java.io.InputStream;
 4 
 5 import org.apache.ibatis.io.Resources;
 6 import org.apache.ibatis.session.SqlSessionFactory;
 7 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 8 import org.junit.Before;
 9 import org.junit.Test;
10 
11 import com.jxdd.mybatis.po.User;
12 import com.jxdd.mybatis.service.UserDao;
13 import com.jxdd.mybatis.service.impl.UserDaoImpl;
14 
15 public class UserDaoTest {
16     private SqlSessionFactory sqlSessionFactory;
17     @Before
18     public void setUp() throws Exception{
19         //1.加载配置文件
20         InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
21         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
22     }
23     @Test
24     public void findUserByIdTest(){
25         //创建UserDao的对象
26         UserDao userDao = new UserDaoImpl(sqlSessionFactory);
27         userDao.findUserById(1);
28     }
29 }
test

 

5.2.4 问题总结

原始dao开发存在一些问题:

存在一定量的模板代码.比如:通过SqlSessionFactory创建SqlSession;调用SqlSession的方法操作数据库;关闭Sqlsession.

存在一些硬编码.调用SqlSession的方法操作数据库时,需要指定statement的id,这里存在硬编码.  

 

5.3 Mapper代理开发方式(推荐)

 

Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可。Mybatis会自动的为mapper接口生成动态代理实现类。

 

不过要实现mapper代理的开发方式,需要遵循一些开发规范。

5.3.1 开发规范

1.mapper接口的全限定名要和mapper映射文件的namespace的值相同.

2.mapper接口的方法名称要和mapper映射文件中的statement的id相同.

3.mapper接口的参数只能有一个,且类型要和mapper映射文件中的statement的parameterType的值保持一致.

4.mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap的type值保持一致.

 

通过规范式的开发mapper接口,可以解决原始dao开发当中存在的问题:

 

1. 模板代码已经去掉;

 

2.剩下去不掉的操作数据库的代码,其实就是一行代码。这行代码中硬编码的部分,通过第一和第二个规范就可以解决。

5.3.2 mapper接口

技术分享
 1 package com.jxdd.mybatis.service;
 2 
 3 import java.util.List;
 4 
 5 import com.jxdd.mybatis.po.User;
 6 
 7 public interface UserMapper {
 8     //1.根据用户ID查询用户信息
 9     public User findUserById(int id);
10     //2.根据用户名称模糊查询用户列表
11     public List<User> findUserByName(String name);
12     //3.添加用户
13     public void insertUser(User user);
14 }
UserMapper

5.3.3 mapper映射文件

技术分享
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper    
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.jxdd.mybatis.service.UserMapper">
 6     <!-- 根据用户id查询用户信息 -->
 7     <select id="findUserById" parameterType="int" resultType="com.jxdd.mybatis.po.User">
 8         SELECT * FROM USER WHERE id = #{id}
 9     </select>
10     <!-- 根据用户名称模糊查询用户列表 -->
11     <select id="findUsersByName" parameterType="java.lang.String" resultType="com.jxdd.mybatis.po.User">
12         SELECT * FROM USER WHERE username LIKE ‘%${value}%‘
13     </select>
14     <!-- 添加用户 -->
15     <insert id="insertUser" parameterType="com.jxdd.mybatis.po.User">
16         INSERT INTO USER(username,sex,birthday,address) VALUES (#{username},#{sex},#{birthday},#{address})
17     </insert>
18 </mapper>
UserMapper.xml

5.3.4 加载映射文件

1 <mappers>
2     <mapper resource="sqlmap/User.xml"/>
3     <mapper resource="mapper/UserMapper.xml"/>
4 </mappers>

5.3.5 测试

技术分享
 1 package com.jxdd.mybatis.test;
 2 
 3 import java.io.InputStream;
 4 
 5 import org.apache.ibatis.io.Resources;
 6 import org.apache.ibatis.session.SqlSession;
 7 import org.apache.ibatis.session.SqlSessionFactory;
 8 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 9 import org.junit.Before;
10 import org.junit.Test;
11 
12 import com.jxdd.mybatis.po.User;
13 import com.jxdd.mybatis.service.UserMapper;
14 
15 public class UserMapperTest {
16     private SqlSessionFactory sqlSessionFactory;
17     @Before
18     public void setUp() throws Exception{
19         //1.加载配置文件
20         InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
21         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
22     }
23     @Test
24     public void findUserById(){
25         //创建SqlSession对象
26         SqlSession sqlSession = sqlSessionFactory.openSession();
27         //通过mybatis得到mapper接口的代理实现类
28         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
29         User user = userMapper.findUserById(1);
30         System.out.println(user);
31         //关闭资源
32         sqlSession.close();
33     }
34 }
test

 

6.Mybatis全局配置文件

SqlMapConfig.xml是mybatis的全局配置文件,它的名称可以是任意命名的.

6.1全部配置内容

SqlMapConfig.xml的配置内容和顺序如下(顺序不能打乱)

Properties(属性)

Settings(全局参数设置)

typeAliases(类型别名)

typeHandler(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境信息集合)

  environment(单个环境信息)

    transactionManager(事务管理)

    dataSource(数据源)

mappers(映射器)

6.2 常用配置详解

6.2.1 Properties

SqlMapConfig.xml文件中可以应用java属性文件中的配置信息

dp.properties 配置信息如下

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
db.username=root
db.password=root

SqlMapConfig.xml使用properties标签后,如下所示:

技术分享
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6 <properties resource="db.properties"/>
 7 <!-- 配置mybatis的环境信息 -->
 8 <environments default="development">
 9     <environment id="development">
10         <!-- 配置JDBC事务控制,由mybatis进行管理 -->
11         <transactionManager type="JDBC"></transactionManager>
12         <!-- 配置数据源,采用dbcp连接池 -->
13         <dataSource type="POOLED">
14             <property name="driver" value="${db.driver}"/>
15             <property name="url" value="${db.url}"/>
16             <property name="username" value="${db.username}"/>
17             <property name="password" value="${db.password}"/>
18         </dataSource>
19     </environment>
20 </environments>
21 <mappers>
22     <mapper resource="sqlmap/User.xml"/>
23     <mapper resource="mapper/UserMapper.xml"/>
24 </mappers>
25 </configuration>
SqlMapConfig.xml

如果在<properties></properties>中添加<property name="db.username" value="123"/>

其运行结果也不会有影响

使用${},可以引用已经加载的java配置文件中的信息。

注意:mybatis将按照下面的顺序加载属性:

1.Properties标签体内定义的属性首先被读取

2.Properties引用的属性会被读取,如果发现上面已经有同名的属性了,那后面会覆盖前面的值

3.parameterType接收的值会最后被读取,如果发现上面已经有同名的属性了,那后面会覆盖前面的值

所以说,mybatis读取属性的顺序由高到低分别是:parameterType接收的属性值、properties引用的属性、properties标签内定义的属性。

6.2.2 Settings

mybatis全局配置参数,全局参数将会影响mybatis的运行行为。

技术分享

技术分享

技术分享

6.2.3 typeAliases

 

别名是使用是为了在映射文件中,更方便的去指定入参和结果集的类型,不再用写很长的一段全限定名。

6.2.3.1 MyBatis支持的别名

别名	         映射的类型
_byte 	           byte 
_long 	       long 
_short 	       short 
_int 	       int 
_integer 	  int 
_double 	  double 
_float 	      float 
_boolean 	  boolean 
string 	      String 
byte 	      Byte 
long 	      Long 
short 	      Short 
int 	      Integer 
integer 	  Integer 
double 	      Double 
float 	      Float 
boolean 	  Boolean 
date 	      Date 
decimal 	  BigDecimal 
bigdecimal 	  BigDecimal 

6.2.3.2 自定义别名

SqlMapConfig.xml配置信息如下:

1 <!-- 定义别名 -->
2     <typeAliases>
3         <!-- 单个定义别名 -->
4         <typeAlias type="com.jxdd.mybatis.po.User" alias="user"/>
5         
6         <!-- 批量定义别名(推荐) -->
7         <!-- [name]:指定批量定义别名的类包,别名为类名(首字母大小写都可) -->
8         <package name="com.jxdd.mybatis.po"/>
9     </typeAliases>

6.2.4 mappers

6.2.4.1 <mapper resource=’’/>

使用相对于类路径的资源

如:<mapper resource="sqlmap/User.xml" />

6.2.4.2 <mapper url=’’/>

使用完全限定路径

如:<mapper url="file:///D:\\workspace_spingmvc\\mybatis01\\config\\sqlmap\\User.xml" />

6.2.4.3 <mapper class=’’/>

使用mapper接口的全限定名

如:<mapper class="com.jxdd.mybatis.mapper.UserMapper"/>

注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下

6.2.4.5 <package name=’’/>(推荐)

 

注册指定包下的所有映射文件

 

如:<package name="com.jxdd.mybatis.mapper"/>

 

注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下

 







以上是关于Mybatis学习的主要内容,如果未能解决你的问题,请参考以下文章

markdown [mybatis参考]关于mybatis #mybatis的一些片段

Mybatis 学习笔记总结

Mybatis学习笔记:动态SQL

SSM-MyBatis-05:Mybatis中别名,sql片段和模糊查询加getMapper

mybatis动态sql片段与分页,排序,传参的使用

MyBatis动态SQL标签用法