mybatis连接池,动态的Sql语句,多表查询一对多,多对多

1.mybatis连接池与实务

1.1mybatis连接池

可以看出 Mybatis 将它自己的数据源分为三类:

  1. UNPOOLED 不使用连接池的数据源
  2. POOLED 使用连接池的数据源
  3. 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多表查询多对多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值