part2mybatis的CRUD(基于代理dao)

知识点

回顾Mybatis的环境搭建-实现查询所有功能
Mybatis的CRUD-保存操作
Mybatis的CRUD-修改和删除操作
Mybatis的CRUD-查询一个和模糊查询
Mybatis的CRUD-查询返回一行一列和占位符分析

目标

能够搭建mybatis环境,并查询所有用户
能够完成保存用户的操作
能够完成修改用户和根据id删除用户操作	
能够完成根据id查询用户和模糊查询
能够总记录条数的查询,掌握占位符的用法

使用要求:

  • 持久化接口和持久层接口的映射配置必须在相同的包下
  • 吃据此映射配置中mapper标签的namespace属性取值必须是持久层接口的全限定类名
  • SQL语句的配置标签的id属性必须和持久层接口的方法名相同

新建工程day02_eesy_01mybatisCRUD一切粘贴day01_eesy_01mybatis!!!
1.保存测试 2、更新(更新)和删除 3.查询一个和模糊查询 4、查询返回一行一列和占位符分析

1、保存操作

在IUserDao中添加保存方法

 /**
     * 保存方法
     */
    void saveUser(User user);

在IUserDao中添加

 <!--保存用户-->
    <insert id="saveUser" parameterType="com.it.domain.User">
        insert into user(username,address,sex,birthday)value(#{username},#{address},#{sex},#{birthday});

    </insert>
  • #{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用
    getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.
    而直接写 username
package com.it.test;

import com.it.dao.IUserDao;
import com.it.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

//入门案例
public class MybatisTest {
    private InputStream in;
    private SqlSession sqlSession;
    private  IUserDao userDao;

    @Before  //用于在测试方法执行之前执行
    public void init()throws Exception{
        //1、读取配置文件,为了把SqlMapConfig里的信息加载
        in = Resources.getResourceAsStream("SqlMapConfig.xml");//连接数据库
        //2、创建SqlSessionFactory工厂(工厂模式)

        SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(in);
        //3、使用工厂生产一个SqlSession对象
        sqlSession=factory.openSession();
        //4、使用SqlSession创建接口的代理对象,
        userDao=sqlSession.getMapper(IUserDao.class);

    }

    @After //用于在测试方法执行之后执行
    public void destroy()throws Exception{
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }

    @Test
    public void testFindAll(){

        List<User> users=userDao.findAll();//实现功能
        for(User user : users){
            System.out.println(user);
        }

    }
    /**
     * 测试保存操作
     */
    @Test
    public void testSave() throws Exception{
        User user=new User();
        user.setUsername("mybatis saveruser");
        user.setAddress("北京");
        user.setSex("男");
        user.setBirthday(new Date());
    userDao.saveUser(user);

    //提交事务
        sqlSession.commit();
        //5、执行保存方法
            }
}

其中注意保存操作中要提交事务和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交,还有@Test@After@Before的位置分别执行即可

注意:映射文件的sql !这个 sql 语句中使用#{}字符,#{}代表占位符,我们可以理解是原来 jdbc 部分所学的“?“,它们都是代表占位符, 具体的值是由User 类的 username属性来决定的。 parameterType属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。 注意: 这 种 方 式 要 求 , 同 时 还 要求,,,这些标签中的 id属性一定与代理接口中的方法名相同。

2、删除(更新)和删除操作

在IUserDao中添加

/**
    *更新用户
     */
    void updateUser(User user);

IUserDao.xml添加

<!--更新用户-->
    <update id="updateUser" parameterType="com.it.domain.User">
            update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id};
    </update>

主测试文件中添加

 /**
     * 测试更新操作
     */
    @Test
    public void testUpdate() throws Exception{
        User user=new User();
        user.setId(48);
        user.setUsername("mybatis update");
        user.setAddress("北京");
        user.setSex("男");
        user.setBirthday(new Date());
        userDao.updateUser(user);
}

在IUserDAO中添加

/**
     * 根据id删除用户
     */
    void deleteUser(Integer userId);
    

注意,parameterType的参数是一个简单类型(基本类型8种+String)的时候,#{}中的值可以任意写,如果是一个对象(例如User),则必须使用属性名称
IUserDao中添加

 <!--根据id删除用户-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id=#{uid}<!--此处id命名随意-->
    </delete>

主测试文件中添加


    /**
     * 测试删除
     */
    @Test
    public void testDelete(){
        userDao.deleteUser(46);
    }

3、查询一个和模糊查询

在IUserDao中添加

/**
     * 根据id查询用户信息
     */
    User findById(Integer userId);

IUserDao.xml添加

<!--根据id查询用户-->
    <select id="findById" parameterType="INT" resultType="com.it.domain.User">
        select * from user where id=#{uid};
    </select>

主测试文件中添加

 /**
     * 测试一个 方法
     */
    @Test
    public void testfindOne(){
        userDao.findById(49);
    }

在IUserDao中添加

/**
     * 根据名称模糊查询用户信息
     */
    List<User> findByName(String username);

IUserDao.xml添加

<!--根据名称模糊查询id-->
    <select id="findByName" parameterType="string" resultType="com.it.domain.User">
        select * from user where username like #{name}  /*用的是PrePaareStatement参数占位符形式,都是用于执行语句是替换实际的数据。具体的数据是由#{}里面的内容决定的*/
        /*select * from user where username like '%${value}%' Statement对象的字符串拼接SQL*/
    </select>

主测试文件中添加

 /**
     * 测试根据名称查询方法
     */
    @Test
    public void testFindByName(){
        List<User> users = userDao.findByName("%王%");
        //List users=user.Dao.fondByName("王");
        for(User user:users){
        System.out.print(users);
    }}

#{}和${}的区别

  • #{} 表示一个占位符;通过#{}可实现preparedStatement向占位符中设置值,自动进行java类型转换,#{}可以有效防止sql注入。#{}可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其他名称。
  • ** ∗ ∗ 表 示 拼 接 s q l 串 ; 通 过 {}**表示拼接sql串;通过 sql{}可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换, 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值, pojoparameterType{}括号中只能是value。

4、查询返回一行一列和占位符分析

查询总数
在IUserDao中添加

  /**
     * 查询总用户数
     */
    int findTotal();

IUserDao.xml添加

<!--获用户的总记录条数-->
    <select id="findTotal" resultType="int">
        select count(id) from user;
    </select>

主测试文件中添加

 /**
     * 查询总记录条数
     */
    @Test
    public void testFindTotal(){
        int count=userDao.findTotal();
        System.out.println(count);
    }

拓展,如何达到保存操作插入的user的id?
新增用户后,同时还要返回当前新增用户的id值,因为id是由数据库的自动增长来实现的,所以就相当于我们要在新增后将自动增长auto_increment的值返回。
Mysql自增长主键的返回,配置如下:

insert id="saveUser" parameterType="com.it.domain.User">
	<!--  配置保存时获取插入的 id -->
	<!-- 配置后,获取插入数据的id-->
	<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
		select last_insert_id();
	</selectKey>
	insert into user(username,birthday,sex,address)
	values(#{username},#{birthday},#{sex},#{address})
</insert>

然后在测试类中打印user,结果如下:
part2mybatis的CRUD(基于代理dao)_第1张图片
Mybatis 与 与 JDBC 编程的比较

1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:
在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
解决:
将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
3.向sql语句传参数麻烦,因为sql语句的where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:
Mybatis自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的
类型。
4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对
象解析比较方便。
解决:
Mybatis自动将 sql执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的
类型。

你可能感兴趣的:(part2mybatis的CRUD(基于代理dao))