mybatis连接池,动态的Sql语句,多表查询一对多,多对多
mybatis汇总
1.mybatis连接池与实务
1.1mybatis连接池
可以看出 Mybatis 将它自己的数据源分为三类:
-
UNPOOLED
不使用连接池的数据源 -
POOLED
使用连接池的数据源 -
JNDI
使用 JNDI 实现的数据源(基本淘汰)
MyBatis 在初始化时,根据的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例(使用多次)
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例(只能用一次)
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用
<?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>
<properties resource="database.properties">
</properties>
<!--typeAliases配置别名,它只能配置domain中的别名-->
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="hehe" type="com.xiao.domain.User"/>
<!--批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以)-->
<package name="com.xiao.domain"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- <mapper url="file:///E:/CodeSeniorJava/mybatis_04_CRUD_demo02/src/main/resources/com/xiao/dao/UserDao.xml"/>-->
<!--package标签能够用于指定dao接口所在的包,当指定了之后就不需要再写mapper以及resource以及class了-->
<package name="com.xiao.dao"/>
</mappers>
</configuration>
1.2mybatis事务管理
1.2.1手动提交事务
Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制。
这是我们的 Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进
行事务的提交,原因是 setAutoCommit()方法,在执行时它的值被设置为 false 了,所以我们在 CUD 操作中,
必须通过 sqlSession.commit()方法来执行提交操作。
public class UserDaoImpl implements UserDao {
private SqlSessionFactory factory ;
public UserDaoImpl(SqlSessionFactory factory){
this.factory = factory;
}
public List<User> findAll() {
//创建sqlSession
SqlSession sqlSession = factory.openSession();
//传入类型
List<User> users = sqlSession.selectList("com.xiao.dao.UserDao.findAll");
sqlSession.close();
return users;
}
public void saveUser(User user) {
//创建sqlSession
SqlSession sqlSession = factory.openSession();
//传入类型
sqlSession.insert("com.xiao.dao.UserDao.saveUser",user);
//提交事务
sqlSession.commit();
sqlSession.close();
}
/**
* 创建资源
* @throws Exception
*/
@Before
public void Init() throws Exception{
//加载配置文件
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
//创建工厂对象的工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//通过配置文件来创建工厂对象
SqlSessionFactory factory = builder.build(is);
//创建UserDaoImpl对象传入工厂对象,获取到实现类中的方法
userDao = new UserDaoImpl(factory);
}
/**
* 关闭资源
* @throws Exception
*/
@After
public void destroy() throws Exception{
//关闭输入流
is.close();
}
/**
* 查询所有用户信息用户
* @throws Exception
*/
@Test
public void saveUserTest() throws Exception{
User user= new User();
user.setUsername("李四 test");
user.setAddress("仙桃");
user.setBirthday(new Date());
user.setSex("男");
System.out.println("添加之前:"+user);
userDao.saveUser(user);
System.out.println("添加之后:"+user);
}
1.2.2自动提交事务
@Before//在测试方法执行之前执行
public void init()throws Exception {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.创建 SqlSession 工厂对象
factory = builder.build(in);
//4.创建 SqlSession 对象
session = factory.openSession(true);
//5.创建 Dao 的代理对象
userDao = session.getMapper(IUserDao.class);
}
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
//7.释放资源
session.close();
in.close();
}
所对应的 DefaultSqlSessionFactory 类的源代码:
我们发现,此时事务就设置为自动提交了,同样可以实现CUD操作时记录的保存。虽然这也是一种方式,但就 编程而言,设置为自动提交方式为
false再根据情况决定是否进行提交,这种方式更常用。因为我们可以根据业务 情况来决定提交是否进行提交。
2.mybatis动态的Sql语句
2.1动态SQL之< if >标签
持久层dao
/**
* 通过名字查询
* @param user
* @return
*/
List<User> findByName(User user);
持久层dao的映射配置
<!--模糊查询-->
<!--
<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用~!
-->
<!---->
<select id="findByName" parameterType="User" resultType="User">
<include refid="defaultSql"></include>
<!--可以去掉where 1=1 加上 where标签-->
<where>
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="address != null and address != ''">
and address like #{address}
</if>
</where>
</select>
测试
@Before
public void innit() throws Exception {
//加载配置文件
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
factory = factoryBuilder.build(is);
sqlSession = factory.openSession();
userDao = sqlSession.getMapper(UserDao.class);
}
@After
public void destroy() throws IOException {
sqlSession.close();
is.close();
}
@Test
public void findByName(){
String name = "%王%";
User user= new User();
user.setAddress("%仙桃%");
user.setUsername(name);
List<User> users = userDao.findByName(user);
for (User user1 : users) {
System.out.println(user1);
}
}
2.2< where >标签
为了简化上面 where 1=1 的条件拼装,我们可以采用< where >
标签来简化开发
注意 sql语句后面需要加空格否则会报错
2.3< for each >标签
传入多个 id 查询用户信息,用下边两个 sql 实现: SELECT * FROM USERS WHERE username LIKE
‘%张%’ AND (id =10 OR id =89 OR id=16) SELECT * FROM USERS WHERE
username LIKE ‘%张%’ AND id IN (10,89,16)
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。 这样我们将如何进行参数的传递?
<!-- 查询所有用户在 id 的集合之中 -->
<select id="findInIds" resultType="user" parameterType="queryvo">
<!-- select * from user where id in (1,2,3,4,5); -->
<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>
SQL 语句:
select 字段 from user where id in (?)
标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
2.4简化SQL片段
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。
<!-- 抽取重复的语句代码片段 -->
<sql id="defaultSql">
select * from user
</sql>
<!-- 配置查询所有操作 -->
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
<!-- 根据 id 查询 -->
<select id="findById" resultType="UsEr" parameterType="int">
<include refid="defaultSql"></include>
where id = #{uid}
</select>
3.mybatis多表查询一对多
4.mybatis多表查询多对多
上一篇: Mybatis 多表查询之多对多(八)
下一篇: MyBatis多表连接一对一与一对多