Mybatis学习(二)

Mybatis学习(二)

基于代理Dao实现CRUD操作

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


在测试类中添加初始化方法
    private InputStream in;
    private SqlSession sqlSession;
    private UserDao userDao;
    /**
     * 定义初始化方法
     */
    @Before
    public void init() throws Exception{
        //读取配置文件,生成字节输入流
         in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //获取SqlsessionFactory对象
         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //获取Sqlsession对象
         sqlSession = factory.openSession();
        //获取dao代理对象
         userDao = sqlSession.getMapper(UserDao.class);
    }
    @After
    public void destroy() throws Exception{

        //提交事务
        sqlSession.commit();

        //.释放资源
        sqlSession.close();
        in.close();
    }

查询所有内容的方法

在持久层接口中添加findAll方法
    /**
     * 查找所有
     * @return
     */
    List<User> findAll();
在映射配置文件中配置
    <!--查询用户-->
    <select id="findAll" resultType="com.itcast.domain.User">
        select * from user;
    </select>

resultType属性:用于指定结果集的类型

在测试类中添加测试
public void testFindAll() throws Exception{

        //执行查询所有方法
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

添加方法

在持久层接口中添加addUser方法
    /**
     * 添加用户
     * @param user
     */
    void addUser(User user);
在映射配置文件中配置
    <insert id="addUser" parameterType="com.itcast.domain.User">
        insert into user(username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday});
    </insert>

parameterType属性:代表参数的类型,因为我们要传入的是一个类的对象,所以就写类的全名称

sql语句中使用#{ }字符:
    它代表占位符,相当于jdbc部分所学的?,都是用于执行语句时替换实际的数据的
    具体的数据由#{ }里面的内容所决定

#{ }中具体的写法:
    由于我们保存方法的参数是一个User对象,,此处要写User对象中的属性名称
    它用的是ognl表达式
ognl表达式:
    它是apache提供的一种表达式语言,全称是:
    Object Graphic Navigation Language  对象图导航语言
    它是按照一定的语法格式来获取数据的
    语法格式是#{对象.对象}的方式


在测试类中添加测试
    /**
     * 测试添加方法
     */
    @Test
    public void testAdd() throws Exception{
        User user =new User();
        user.setUsername("dddd_last");
        user.setAddress("北京");
        user.setSex("男");
        user.setBirthday(new Date());
        //执行查询所有方法
        userDao.addUser(user);
    }
新增用户的id返回值
</select>
    <!--添加用户-->
    <insert id="addUser" parameterType="com.itcast.domain.User">
    <!-- 配置保存时获取插入的 id -->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday});
    </insert>

修改用户

在持久层中添加updateUser方法
    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);

在映射配置文件中配置
    <!--修改用户-->
    <update id="updateUser" parameterType="com.itcast.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(49);
        user.setUsername("ddd update");
        user.setAddress("北京");
        user.setSex("女");
        user.setBirthday(new Date());


        //执行查询所有方法
        userDao.updateUser(user);
    }

删除用户

在持久层中添加delUser方法
    /**
     * 根据id删除用户
     * @param userid
     */
    void delUser(Integer userid);
   

在映射配置文件中配置
    <!--删除用户-->
    <delete id="delUser" parameterType="Integer">
        delete from user where id = #{uid};
    </delete>

在测试类中添加测试
    /**
     * 测试删除方法
     */
    @Test
    public void testDel() throws Exception{
        userDao.delUser(49);
    }

根据id查询用户

在持久层中添加findById方法
    /**
     * 根据id查询用户
     * @param userid
     */
    User findById(Integer userid);

在映射配置文件中配置
    <!--根据id查询用户信息-->
    <select id="findById" parameterType="Integer" resultType="com.itcast.domain.User">
        select * from user where id = #{uid};
    </select>

在测试类中添加测试
    /**
     * 测试根据id查询用户信息方法
     */
    @Test
    public void testFindById() throws Exception{
        User user = userDao.findById(48);
        System.out.println(user);
    }

根据名称模糊查询用户信息

在持久层中添加findByName方法
    /**
     * 根据名称模糊查询用户信息
     * @param username
     * @return
     */
   List<User> findByName(String username);

在映射配置文件中配置
   <!--根据名称模糊查询-->
    <select id="findByName" parameterType="string" resultType="com.itcast.domain.User">
        select * from user where username like #{name};
    </select>

在测试类中添加测试
    /**
     * 测试模糊查询
     */
    @Test
    public void testFindByName(){
        List<User> users = userDao.findByName("%王%");
        for (User user : users) {
            System.out.println(user);
        }
    }

查询数据库中记录的数目

在持久层中添加findTotal方法
    /**
     * 查询数据库中记录的数目
     * @return
     */
   int findTotal();

在映射配置文件中配置
    <!--查询数据条数-->
    <select id="findTotal" resultType="int">
        select count(id) from user;
    </select>

在测试类中添加测试
    /**
     * 测试查询记录条数
     */
    @Test
    public void testFindTotal(){
        int total = userDao.findTotal();
        System.out.println(total);
    }

使用自定义包装类作为查询对象

编写QueryVo
public class QueryVo {
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

编写持久层接口
    /**
     * 根据QueryVo中的条件查询用户
     * @param vo
     * @return
     */
   List<User> findByVo(QueryVo vo);

编写持久层接口的映射文件
<!--根据QueryVo来查询用户信息-->
    <select id="findByVo" parameterType="com.itcast.domain.QueryVo" resultType="com.itcast.domain.User">
        select * from user where username like #{user.username};
    </select>

测试包装类作为参数
    /**
     * 测试使用QueryVo作为查询条件
     */
    @Test
    public void testFindByVo(){
        QueryVo queryVo = new QueryVo();
        User user = new User();
        user.setUsername("%王%");
        queryVo.setUser(user);

        List<User> byVo = userDao.findByVo(queryVo);
        for (User user1 : byVo) {
            System.out.println(user1);
        }
    }

Mybatis结果集封装

当实体类属性和数据库表的列名不一致时候

第一种方法:在查询时使用别名查询

<!-- 配置查询所有操作 -->
 <select id="findAll" resultType="com.itheima.domain.User">
	select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as userAddress from user;
</select>

第二种方法:定义resultMap

<!-- 建立 User 实体和数据库表的对应关系
	type 属性:指定实体类的全限定类名
	id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
--> 
<resultMap type="com.itheima.domain.User" id="userMap"> 
	<id column="id" property="userId"/>
	<result column="username" property="userName"/>
	<result column="sex" property="userSex"/>
	<result column="address" property="userAddress"/>
	<result column="birthday" property="userBirthday"/>
</resultMap>

id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称


使用Dao接口的实现类进行开发

持久层Dao接口
import java.util.List;

public interface UserDao {
    /**
     * 查找所有
     * @return
     */
    List<User> findAll();

    /**
     * 添加用户
     * @param user
     */
    void addUser(User user);

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

    /**
     * 根据id删除用户
     * @param userid
     */
    void delUser(Integer userid);

    /**
     * 根据id查询用户
     * @param userid
     */
    User findById(Integer userid);

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

    /**
     * 查询数据库中记录的数目
     * @return
     */
   int findTotal();


}


持久层Dao实现类
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

public class UserDaoImpl implements UserDao {

    private SqlSessionFactory factory;

    /**
     * 添加构造方法在创建dao实现类时传入SqlSessionFactory
     * @param factory
     */
    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    /**
     * 查询所有方法
     * @return
     */
    public List<User> findAll() {
        SqlSession sqlSession = factory.openSession();

        List<User> users = sqlSession.selectList("com.itcast.dao.UserDao.findAll");

        sqlSession.close();
        return users;
    }

    /**
     * 添加用户方法
     * @param user
     */
    public void addUser(User user) {
        SqlSession sqlSession = factory.openSession();

        sqlSession.insert("com.itcast.dao.UserDao.addUser",user);

        sqlSession.commit();

        sqlSession.close();


    }

    /**
     * 更新用户方法
     * @param user
     */
    public void updateUser(User user) {
        SqlSession sqlSession = factory.openSession();

        sqlSession.update("com.itcast.dao.UserDao.updateUser",user);

        sqlSession.commit();

        sqlSession.close();
    }

    /**
     * 删除用户方法
     * @param userid
     */
    public void delUser(Integer userid) {
        SqlSession sqlSession = factory.openSession();

        sqlSession.delete("com.itcast.dao.UserDao.delUser",userid);

        sqlSession.commit();

        sqlSession.close();
    }

    /**
     * 根据id查找用户方法
     * @param userid
     * @return
     */
    public User findById(Integer userid) {
        SqlSession sqlSession = factory.openSession();

        User user = sqlSession.selectOne("com.itcast.dao.UserDao.findById", userid);

        sqlSession.commit();

        sqlSession.close();

        return user;
    }

    /**
     * 根据名称模糊查询用户信息
     * @param username
     * @return
     */
    public List<User> findByName(String username) {
        SqlSession sqlSession = factory.openSession();

        List<User> users = sqlSession.selectList("com.itcast.dao.UserDao.findByName", username);

        sqlSession.commit();

        sqlSession.close();

        return users;
    }

    /**
     * 查询数据记录条数
     * @return
     */
    public int findTotal() {
        SqlSession sqlSession = factory.openSession();

        Integer i = sqlSession.selectOne("com.itcast.dao.UserDao.findTotal");

        sqlSession.commit();

        sqlSession.close();

        return i;
    }
}


持久层测试类
import org.apache.ibatis.io.Resources;
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 UserDao userDao;
    /**
     * 定义初始化方法
     */
    @Before
    public void init() throws Exception{
        //读取配置文件,生成字节输入流
         in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //获取SqlsessionFactory对象
         SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //获取dao代理对象
         userDao = new UserDaoImpl(factory);
    }
    @After
    public void destroy() throws Exception{

        in.close();
    }

    @Test
    public void testFindAll() throws Exception{

        //执行查询所有方法
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }

    }

    /**
     * 测试添加方法
     */
    @Test
    public void testAdd() throws Exception{
        User user =new User();
        user.setUsername("dddd_last");
        user.setAddress("北京市");
        user.setSex("男");
        user.setBirthday(new Date());
        System.out.println(user);
        //执行查询所有方法
        userDao.addUser(user);
        System.out.println(user);
    }

    /**
     * 测试更新方法
     */
    @Test
    public void testUpdate() throws Exception{
        User user =new User();
        user.setId(50);
        user.setUsername("ddd update");
        user.setAddress("北京市");
        user.setSex("女");
        user.setBirthday(new Date());


        //执行查询所有方法
        userDao.updateUser(user);
    }

    /**
     * 测试删除方法
     */
    @Test
    public void testDel() throws Exception{
        userDao.delUser(50);
    }

    /**
     * 测试根据id查询用户信息方法
     */
    @Test
    public void testFindById() throws Exception{
        User user = userDao.findById(48);
        System.out.println(user);
    }

    /**
     * 测试模糊查询
     */
    @Test
    public void testFindByName(){
        List<User> users = userDao.findByName("%王%");
        for (User user : users) {
            System.out.println(user);
        }
    }

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

}


SqlMapConfig.xml配置文件

配置properties

    可以在标签内部配置连接数据库的信息,也可以通过属性引用外部信息

<properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy"/>
        <property name="username" value="root"/>
        <property name="password" value="000000"/>
    </properties>


<typeAliases>
        <!--<typeAlias type="com.itcast.domain.User" alias="user"></typeAlias>-->
        <package name="com.itcast.domain"/>
    </typeAliases>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    resource属性:常用的
      用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下

    url属性:
      是要求按照url的写法来写地址

    URL:Uniform Resource Locator 统一资源定位符,它是可以唯一标识一个资源的位置
      它的写法:
        http://localhost:8080/mybatisserver/demo1Serlet
        协议  主机  端口  URI

    URI:Uniform Resource Identifier 统一资源标识符 他是在应用中唯一定位一个资源的

typeAliases

    使用typeAliases配置别名,它自能配置domain中类的别名

    typeAliases用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定别名就不再区分大小写了

    package
      用于指定配置别名的包,当指定之后,该包下的实体类都会注册别名,而且类名就是别名,不再区分大小写

    mappers里面的package标签
      package标签是用于指定dao接口所在的包,当中指定了之后就不再需要写mapper以及resource或者class了

 	<typeAliases>
        <!--<typeAlias type="com.itcast.domain.User" alias="user"></typeAlias>-->
        <package name="com.itcast.domain"/>
    </typeAliases>
	<mappers>
	    <package name="com.itcast.dao"/>
	</mappers>

上一篇:2.9(基于XML的两种装配实例化对象的方式)、(基于annotation的装配方式)、(自动装配)


下一篇:Spring中的Bean——装载