mybatis学习笔记(二)
mybatis的连接池
mybatis将他自己的数据源分为三类:
- UNPOOLED: 不使用连接池的数据源
- POOLED:使用链接池的数据源
- JNDI:使用 JNDI 实现的数据源
mybatis内部分别实现了 java.sql.DataSource 接口的 UnpooledDataSource,PooledDataSource 类来表示 UNPOOLED,POOLED 类型的数据源。PooledDataSource 持有一个 UnpooledDataSource 的引用,当PooledDataSource 需要创建 java.sql.Connection 实例对象时,还是通过 UnpooledDataSource 来创建。PooledDataSource 只是提供一种缓存连接池机制。
mybatis 是通过工厂模式来创建数据源 DataSource 对象的,mybatis 定义了抽象工厂接口org.apache.ibatis.datasource.DataSourceFactory ,通过其 getDataSource () 方法返回数据源 DataSource 。
PooledDataSource 工作流程图:
最后发现,真正连接打开的时间点,只是在执行 SQL 语句时,才会进行。其实这样做也可以进一步发现,数据库连接是最为宝贵的资源,只有在要用到的时候,才去获取并打开连接,当用完了就再立即将数据库连接归还到连接池中。
JNDI:Java Naming and Directory Interface。是SUN公司推出的一套规范,属于JavaEE技术之一。目的是模仿windows系统中的注册表。
- 在maven的war工程的webapp目录下创建META-INF目录
- 在META-INF目录下创建context.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
<Resource
name="jdbc/mybatis02" 数据源的名称
type="javax.sql.DataSource" 数据源类型
auth="Container" 数据源提供者
maxActive="20" 最大活动数
maxWait="10000" 最大等待时间
maxIdle="5" 最大空闲数
username="root" 用户名
password="1234" 密码
driverClassName="com.mysql.jdbc.Driver" 驱动类
url="jdbc:mysql://localhost:3306/mybatis02" 连接url字符串
/>
-->
<Resource
name="jdbc/mybatis02"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mybatis02"
/>
</Context>
- 在resource目录下创建SqlMapConfig.xml配置文件
<?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>
<!--配置mybatis环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务-->
<transactionManager type="JDBC"/>
<!--配置连接池-->
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/mybatis02" />
</dataSource>
</environment>
</environments>
<!--配置映射文件位置-->
<mappers>
<mapper resource="com/leihui/dao/UserDao.xml"/>
</mappers>
</configuration>
mybatis动态sql
if标签
多条件查询
<select id="findUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username = #{username}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</select>
注意: <if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用~!
where标签
简化 where 1=1
<select id="findUser" resultType="user" parameterType="user">
select * from user
<where>
<if test="username!=null and username != '' ">
and username = #{username}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
</where>
</select>
foreach标签
范围查询
SELECT * FROM USERS WHERE username = ‘zhangsan’ AND id IN (10,14,16)
<!-- 查询所有用户在 id 的集合之中 -->
<select id="findIds" resultType="user" parameterType="queryvo">
select * from user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in ( " close=")" item="uid"
separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
注意:SQL 语句:select 字段 from user where id in (?)
< foreach > 标签用于遍历集合,它的属性:
- collection : 代表要遍历的集合元素,注意编写时不要写 # {}
- open : 代表语句的开始部分
- close : 代表结束部分
sql标签
Sql 标签可将重复的 sql 提取出来,使用时用 include 标签引用即可,最终达到 sql 重用的目的。
<sql id="defaultSql">
select * from user
</sql>
<!-- 查询所有用户在 id 的集合之中 -->
<select id="findIds" resultType="user" parameterType="queryvo">
<!-- select * from user -->
<include refid="defaultSql"></include>
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in ( " close=")" item="uid"
separator=",">
#{uid}
</foreach>
</if>
</where>
</select>