主流框架一:Mybatis框架(3)Mybatis的CRUD操作

一:Mybatis基于代理Dao的CRUD操作

1.CRUD的实现步骤:

(1)在持久层接口(IUserDao)添加对应的方法
例如:

    /**
     * 用户的持久层接口
     * @author Mango
     */
    public interface IUserDao {
    
        /**
         * 查询所有操作
         * @return
         */
        List<User> findAll();

(2)然后在**用户映射配置文件(IUserDao.xml)**中配置

    <!--    配置查询所有-->
    <!--    dao的方法名称,会把结果集封装到User-->
        <select id="findAll" resultType="com.itheima.domain.User">
            select * from user;
        </select>

细节:
resultType 属性:用于指定结果集(返回值)的类型。 parameterType 属性:用于指定传入参数的类型。
sql 语句中使用#{} 字符 :它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。#{} 中内容的写法:由于数据类型是基本类型,所以此处可以随意写。

(1)ognl 表达式:

它是 apache 提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言
它是按照一定的语法格式来获取数据的。语法格式就是使用 #{对象.对象}的方式.

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

(3)测试类测试

    private InputStream in;
        private SqlSession sqlSession;
        private IUserDao userDao;
    
        /**
         * 用于在测试方法之前执行
         * @throws Exception
         */
        @Before
        public void init() throws Exception{
            //1.读取环境里面的总体配置文件(里面参数)
            in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = builder.build(in);
            //3.使用工厂生产一个SqlSession对象
            sqlSession = factory.openSession();
            //4.使用SqlSession创建Dao接口的代理对象
            userDao = sqlSession.getMapper(IUserDao.class);
        }
        /**
         * 用于在测试方法之后执行
         * @throws Exception
         */
        @After
        public void destory() throws Exception{
            //提交事务
            sqlSession.commit();
    
            //6.释放资源
            sqlSession.close();
            in.close();
        }
    
    
        @Test
        public void testFindAll() {
            //使用代理对象执行方法
            List<User> users = userDao.findAll();
            for (User user : users) {
                System.out.println(user);
            }
        }

(2)提交事务:session.commit();

打开 Mysql 数据库发现并没有添加任何记录,原因是什么?这一点和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交那么在 mybatis 中可以使用:session.commit();来实现事务提交。

(3)新增用户 id 的返回值

新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相当于我们要在新增后将自动增长 auto_increment 的值返回。

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

(4)#{} 与${} 的区别

    #{} 表示一个占位符号
    通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值,#{}括号中可以是 value 或其它名称。
    
    ${}表示拼接字符串
    通过${}可以将 parameterType 传入的内容拼接在 sql中且不进行 jdbc 类型转换,$ {}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。

(5)Mybatis 与 与 JDBC 编程的比较

1.数据库链接(Connection)创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:
在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。

2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
解决:
将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。,只改变外部的sql语句

3.向sql语句传参数麻烦,因为sql语句的where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:
Mybatis自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。

4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对
象解析比较方便。

解决:
Mybatis自动将 sql执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的类型。

二:Mybatis 的参数深入(parameterType属性)

parameterType 属性来设定。该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)同时也可以使用实体类的包装类(QueryVo)

QueryVo

/**
 * @author Mango
 * 实体类的包装类
 */
public class QueryVo {
    private User user;

    public User getUser() {
        return user;
    }

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

dao层接口映射文件

<!-- 根据用户名称模糊查询,参数变成一个 QueryVo 对象了 -->
<select id="findByVo" resultType="com.itheima.domain.User"
parameterType="com.itheima.domain.QueryVo">
select * from user where username like #{user.username};
</select>

三:Mybatis 的输出结果封装

resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型
需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须使用全限定类名。例如:我们的实体类(User)此时必须是全限定类名

同时,当是实体类名称是,还有一个要求,实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装。

<!--    配置查询所有-->
<!--    dao的方法名称,会把结果集封装到User-->
    <select id="findAll" resultType="com.itheima.domain.User">
        select * from user;
    </select>

resultMap 结果类型

resultMap 标签**可以建立查询的列名和实体类的属性名称不一致时建立对应关系。**从而实现封装。在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。

type 属性:指定实体类的全限定类名
id 属性:给定一个唯一标识,是给查询 select 标签引用用的。

<!--    配置查询结果的列名和实体类的属性名的对应关系-->
    <resultMap id="userMap" type="com.itheima.domain.User">
        <!--  主键字段的对应 -->
        <id property="id" column="id"></id>
        <!--  主键字段的对应 -->
        <result property="userName" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
    </resultMap>
<!--    每个dao独立的配置文件-->

<!--    配置查询所有-->
<!--    dao的方法名称,会把结果集封装到User-->
    <select id="findAll" resultMap="userMap">
        select * from user;
    </select>

四:Mybatis dao实现类开发(了解)

使用 Mybatis 开发 Dao,通常有两个方法,即原始 Dao开发方式和 Mapper 接口代理开发方式。而现在主流的开发方式是接口代理开发方式,这种方式总体上更加简便。

dao接口实现类:

/**
 * @author Mango
 * dao 的实现类
 */
public class UserDaoImpl implements IUserDao {
    
    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }
    @Override
    public List<User> findAll() {
        SqlSession session = factory.openSession();
        List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");
        session.close();
        return users;
    }

}

持久层映射配置

<!-- 配置查询所有操作 -->
<select id="findAll" resultType="com.itheima.domain.User">
select * from user
</select>
<!-- 根据 id 查询 -->
<select id="findById" resultType="com.itheima.domain.User" parameterType="int">
select * from user where id = #{uid}
</select>

五:SqlMapConfig.xml 配置文件

(1)properties属性

在使用 properties 标签配置时,我们可以采用两种方式指定属性配置。

在 在 classpath 下定义 jdbc.properties 文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xxx
jdbc.username=root
jdbc.password=1234

可以保存到本地,通过url进行索引

<!--    配置properties  支持放到外部配置文件 然后下面再引用

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

    url属性:是要求按照url的写法来写地址
    URL:Uniform Resource Locator 统一资源定位符,它是可以唯一表示一个资源的位置
    它的写法:
        http://localhost:8080/mybatisservert/demolServlet
        协议 主机 端口 URI
    URI:Uniform Resource Identifier 统一资源标识符。它是在应用中可以唯一定位一个资源的
    -->
    <properties url="file:///C:/Users/Mango/Desktop/jdbcConfig.properties"></properties>

(2)typeAliases属性

在前面我们讲的 Mybatis 支持的默认别名,我们也可以采用自定义别名方式来开发。
在 SqlMapConfig.xml 中配置:

<!--    使用typeAliases配置别名,它只能配置domain中类的别名-->
    <typeAliases>
<!--        typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就别再区分大小写-->
<!--        <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>-->
        
<!--        用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
        <package name="com.itheima.domain.User"/>
    </typeAliases>
<!--    指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
    <mappers>
<!--        <mapper resource="com/itheima/dao/IUserDao.xml"/>-->
        
<!--        package标签用于指定dao接口所在的包  当指定后不需要再写mapper以及resource或者class-->
        <package name="com.itheima.dao"/>
        
    </mappers>

注意:此种方法要求 mar pper 接口名称和 r mapper 映射文件名称相同,且放在同一个目录中。

发布了47 篇原创文章 · 获赞 18 · 访问量 4878

猜你喜欢

转载自blog.csdn.net/qq_43605085/article/details/96877069