mybati的Dao代理
Posted 小马Mark
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybati的Dao代理相关的知识,希望对你有一定的参考价值。
一些类的介绍
-
Resources: mybatis中的一个类, 负责读取主配置文件
InputStream in = Resources.getResourceAsStream("mybatis.xml");
-
SqlSessionFactoryBuilder : 创建SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //创建SqlSessionFactory对象 SqlSessionFactory factory = builder.build(in);
-
SqlSessionFactory : 重量级对象, 程序创建一个对象耗时比较长,使用资源比较多。
在整个项目中,有一个就够用了。SqlSessionFactory是一个接口,接口实现类: DefaultSqlSessionFactory SqlSessionFactory作用: 获取SqlSession对象。SqlSession sqlSession = factory.openSession(); openSession()方法说明: 1. openSession() :无参数的, 获取是非自动提交事务的SqlSession对象 2. openSession(boolean): openSession(true) 获取自动提交事务的SqlSession. openSession(false) 非自动提交事务的SqlSession对象
-
SqlSession:
SqlSession接口:定义了操作数据的方法 例如:selectOne() ,selectList() ,insert(),update(), delete(), commit(), rollback() SqlSession接口的实现类DefaultSqlSession 使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象。 在执行完sql语句后,需要关闭它,执行SqlSession.close(). 这样能保证他的使用是线程安全的。
Dao代理实现CRUD
开发规则:
- 在Mapper.xml中将namespace设置为UserDao.java接口的全限定名称
- 将Mapper.xml中statement的id和UserDao.java接口的方法名保持一致
- 将Mapper.xml中statement的parameterType和UserDao.java接口的方法输入参数类型保持一致
- 将Mapper.xml中statement的resultType和UserDao.java接口的方法输出结果类型保持一致
- 注意结合业务层动态代理提交事务
动态代理的使用方式:
- 使用
SqlSession.getMapper(dao接口.class)
获取这个dao接口的对象
以查询为例:
@Test
public void test1()
SqlSession sqlSession = MyBatisUtil.getSqlSession(); // 使用工具类获取sqlSession对象
// 使用getMapper(dao接口.class)动态代理来实现dao接口
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
// 调用dao接口里的方法
List<Account> accounts = accountDao.selectAccount();
accounts.forEach(account -> System.out.println(account));
sqlSession.close();
参数的理解
parameterType
-
接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis可以推断出具体传入语句的参数,默认值为未设置( unset)
-
写在mapper文件中的 一个属性。 表示dao接口中方法的参数的数据类型。
-
sql语句获取参数的值使用#或者$
-
(1)使用基本数据类型(包括String)为参数
(2)使用引用数据类型为参数
(3)使用map为参数
别名 | 映射类型 |
---|---|
_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 |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
一个简单参数
Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 # 任意字符 ,和方法的参数名无关。
// dao接口中一方法
int deleteAccount(int id);
<!--mapper文件-->
<delete id="deleteAccount">
delete from account where id = #id;
</delete>
多参数传递
-
使用@Param:
- 当Dao接口方法多个参数,需要通过名称使用参数。在方法形参前面加入
@Param(“自定义参数名”)
,mapper文件使用#自定义参数名。
// dao接口中一方法 List<Account> selectByParam(@Param("accountId") int id,@Param("accountName") String name);
<!--mapper文件--> <select id="selectByParam" resultType="com.maj.domain.Account"> select id, name, money from account where id = #accountId or name = #accountName <!-- #这里必须与方法中的自定义的相同 --> </select>
- 当Dao接口方法多个参数,需要通过名称使用参数。在方法形参前面加入
-
使用对象
- 使用java对象传递参数,java的属性值就是sql需要的参数值。每一个属性就是一个参数。
- 语法格式:
#property,javaType=java中数据类型名,jdbcType=数据类型名称
- 常用格式:
#property
。javaType,jdbcType的类型MyBatis可以检测出来,一般不需要设置。
// dao接口中一方法 int insertAccount(Account account);
<!--mapper文件--> <insert id="insertAccount"> insert into account values (#id,#name,#money); </insert>
支持的 JDBC 类型:
BIT | FLOAT | CHAR | TIMESTAMP | OTHER | UNDEFINED |
---|---|---|---|---|---|
TINYINT | REAL | VARCHAR | BINARY | BLOB | NVARCHAR |
SMALLINT | DOUBLE | LONGVARCHAR | VARBINARY | CLOB | NCHAR |
INTEGER | NUMERIC | DATE | LONGVARBINARY | BOOLEAN | NCLOB |
BIGINT | DECIMAL | TIME | NULL | CURSOR | ARRAY |
- 按位置
- 参数位置从0开始,引用参数语法
#arg位置
,第一个参数是#arg0,第二个是#arg1 - 注意:mybatis-3.3版本和之前的版本使用
#0,#1
方式,从mybatis3.4开始使用#arg0
方式。
- 参数位置从0开始,引用参数语法
- 使用Map
- Map集合可以存储多个值,使用Map向mapper文件一次传入多个参数。
- Map集合使用String的key,Object类型的值存储参数。
- mapper文件使用
#key
引用参数值。
#和$
使用在sql语句中的符号
- #:表示占位符,可以有效防止sql注入。使用#设置参数无需考虑参数的类型。
- 更安全,更迅速,通常也是首选做法,
-
:
表
示
拼
接
符
,
无
法
防
止
s
q
l
注
入
。
使
用
:表示拼接符,无法防止sql注入。使用
:表示拼接符,无法防止sql注入。使用设置参数必须考虑参数的类型。
- 主要用在替换表名,列名,不同列排序等操作。
输出结果集
resultType
执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。
注意:
- 如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。
- resultType 和 resultMap,不能同时使用
返回类型:
-
简单类型:
// 接口方法 int countAccount();
<!-- mapper文件 --> <select id="countAccount" resultType="int"> select count(*) from Account; </select>
-
对象类型:
Account selectById(int id);
<select id="selectById" resultType="com.maj.domain.Account"> select id,name,money from account where id = #id; </select>
-
Map类型:
sql 的查询结果作为 Map 的 key 和 value。
推荐使用 Map<Object,Object>。
注意: Map 作为接口返回值, sql 语句的查询结果最多只能有一条记录。 大于一条记录是错误。
Map<Object,Object> selectReturnMap(int id);
<select id="selectReturnMap" resultType="map"> select id,name,money from account where id = #id; </select>
resultMap
resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。
常用在列名和 java 对象属性名不一样的情况
使用方式:
- 先定义 resultMap,指定列名和属性的对应关系。
- 在
<select>
中把 resultType 替换为 resultMap。
List<Account> selectUseResultMap(@Param("n") String name, @Param("m") Double money);
<!-- mapper文件 -->
<!--
创建resultMao标签:
id:自定义的唯一名称,用于<select>使用
type: 期望转为的java对象的全限定名称或别名
-->
<resultMap id="accountMap" type="com.maj.domain.Account">
<!-- 主键字段使用id标签 -->
<id column="id" property="id"/>
<!-- 非主键字段使用result标签 -->
<result column="name" property="name" />
<result column="money" property="money" />
</resultMap>
<select id="selectUseResultMap" resultMap="accountMap">
select id,name,money from account where name = #n or money=#m;
</select>
模糊like
模糊查询的实现有两种方式:
-
java 代码中给查询数据加上“%”
<select id="..." resultType="com.maj.domain.Account"> select id,name,money from account where name = #n; <!--这里直接传一个参数进来即可:"%何%" --> </select>
-
在 mapper 文件 sql 语句的
<select id="..." resultType="com.maj.domain.Account"> select id,name,money from account where name = "%" #name "%"; <!--这里直接传一个参数进来即可:"何" --> </select>
以上是关于mybati的Dao代理的主要内容,如果未能解决你的问题,请参考以下文章
02.MyBatis在DAO层开发使用的Mapper动态代理方式