03.mybatis的CRUD操作

mybatis的CRUD操作

注意,数据库配置最好加上编码utf-8


mybatis测试表结构.png

一、基本的增删改查

1.增加操作

  1. dao层代码
public interface UserDao {

    /** 添加操作 */
    public void create(User user);
}
  1. 对应的配置文件UserDao.xml
    • parameterType:方法签名的类型
    • #{xxx}:根据javaBean封装sql语句的参数!
<mapper namespace="com.itheima.dao.UserDao">
    <insert id="create" parameterType="com.itheima.domain.User">
        insert into user(username,birthday,sex,address)
        value (#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>
  1. 测试
    • 注意:Junit测试需要手动提交事务!
public class UserDaoTest {
    InputStream in;
    SqlSessionFactoryBuilder builder;
    SqlSessionFactory sessionFactory;
    SqlSession session;

    @Before
    public void init() throws IOException {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        builder = new SqlSessionFactoryBuilder();
        sessionFactory = builder.build(in);
        session = sessionFactory.openSession();
    }

    @After
    public void destory() throws IOException {
        in.close();
        session.close();
    }

    @Test
    public void test2() {
        UserDao mapper = session.getMapper(UserDao.class);

        Integer integer = mapper.create(new User(0, "晓庆", new Date(), "女", "重庆"));
        System.out.println(integer);
        session.commit();
    }
}

2.更新操作

  1. dao
public interface UserDao {

    /** 更新操作 */
    public void update(User user);
}
  1. 对应的UserDao.xml
<mapper namespace="com.itheima.dao.UserDao">
    <update id="update" parameterType="com.itheima.domain.User">
        update user set username=#{username},address=#{address} where id = #{id}
    </update>
</mapper>
  1. 测试类【其他代码同上插入部分!】
...
@Test
public void test3() {
    UserDao mapper = session.getMapper(UserDao.class);

    Integer integer = mapper.update(new User(49, "晓庆", new Date(), "女", "重庆"));
    System.out.println(integer);
    session.commit();
}
...

3.删除操作

  1. dao层
public interface UserDao {

    /** 删除操作 */
    public void deleteUser(Integer userId);
}
  1. UserDao.xml
    • 参数只有一个,下面的sql中对应 名字随便取,只是一个占位的
    • 下面的parameterType类型为整形:可以写INTEGER/Integer/INT/int/java.lang.Integer
<mapper>
    <delete id="deleteUser" parameterType="Integer">
        delete from user where id = #{uid};
    </delete>
</mapper>

4.查询

  1. dao
public interface UserDao {

    /** 查询一个 */
    public User findOne(Integer id);
}
  1. UserDao.xml
<mapper>
    <select id="findOne" parameterType="Integer" resultType="com.itheima.domain.User">
        select * from user where id = #{uid}
    </select>
</mapper>
  1. 测试
...
@Test
public void test5() {
    UserDao mapper = session.getMapper(UserDao.class);
    System.out.println(mapper.findOne(43));
}
...

二、复杂的增删改查

1.模糊查询

  1. dao
public interface UserDao {

    /** 模糊查询 */
    public List<User> findLike(String name);
}
  1. UserDao.xml
<mapper>
    <select id="findLike" parameterType="String" resultType="com.itheima.domain.User">
        select * from user where username like #{uname}

        <!-- select * from user where username like '%${value}%'
         如果这样写,调用传参的时候就不需要%%,但是不建议这样写!
         '%${value}%'是固定写法,底层就把参数赋值给了value!
         -->

    </select>
</mapper>
  1. 测试类
...
@Test
public void test6() {
    UserDao mapper = session.getMapper(UserDao.class);
    List<User> like = mapper.findLike("%王%");
    for (User user : like) {System.out.println(user);}
}
...

2.插入数据的一个细节

执行mysql语句之后,查询select last_insert_id();会将之前插入的记录的id返回

  1. dao
public interface UserDao {

    /** 插入之后,拿到插入的id封装到user中! */
    public void insert(User user);
}
  1. UserDao.xml
<mapper>
    <insert id="insert" parameterType="com.itheima.domain.User">
        -- 配置插入操作后,获取插入数据的id
        -- keyProperty的属性对应着实体类中的属性
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,birthday,sex,address)
        values (#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>
  1. 测试
...
@Test
public void test7() {
    UserDao mapper = session.getMapper(UserDao.class);
    User user = new User(null, "晓庆", new Date(), "女", "重庆");
    System.out.println("前id:" + user.getId()); // 前id:null
    mapper.insert(user);
    System.out.println("后id:" + user.getId()); // 后id:53
}
...

三、OGNL表达式(Object Graphic Navigation Language)对象图导航语言

通过对象的取值方法来获取数据。在写法上把get给省略了。pojo包装对象就是javaBean对象

1. 案例:获取用户的名称

- 类中的写法:user.getUsername();
- OGNL表达式写法:user.username;

2. mybatis中能够直接写username,是因为在parameterType中已经提供了属性所属的类,默认就是该对象的属性!

在实际开发中,有时候一个pojo提供的字段不足以支撑业务的查询,可能需要多个pojo类或者其他矫健,这时就需要自己封装一些类来作为查询条件,发挥ognl表达式的威力,很简单;就是把需要用的属性通过点点点的形式就查出来了!

3. 自定义封装对象进行查询

  1. QueryVo
public class QueryVo {
    private User user;
    public User getUser() { return user; }
    public void setUser(User user) { this.user = user; }
}
  1. dao
public interface UserDao {

    /** 使用封装pojo进行查询 */
    public List<User> queryLike(QueryVo queryVo);
}
  1. UserDao.xml
<mapper>
    <select id="queryLike" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
        select * from user where username like #{user.username}
    </select>
</mapper>

{user.username}里面的user就为QueryVo中的属性

  1. 测试类
...
@Test
public void test8() {
    UserDao mapper = session.getMapper(UserDao.class);
    QueryVo queryVo = new MyUser();
    User user = new User();
    user.setUsername("%王%");
    queryVo.setUser(user);
    List<User> users = mapper.queryLike(queryVo);
    for (User user1 : users) {
        System.out.println(user1);
    }
}
...

四、 resultMap结果类型

如果pojo中的属性与数据库的字段名不一致,会导致查询或者更新出现字段不匹配的现象,有两种解决方案;
注意:数据库查询的结果集中,不管是通过去别名还是原始的字段名字,只要与被封装的类的属性名【或者】get方法属性名相同,都可以进行封装!

1. 查询语句上可以给字段起别名,比如

select id as userId, username as userName...

2. 采用mybatis配置方式

  1. 修改User.class的属性以及get/set方法
...
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
...
  1. 添加结果匹配标签
--
  配置查询结果的列名和实体类的属性名的对应关系
    id是一个唯一标识,名字随便取,以便具体操作取用
    type是返回类型
 -->
<resultMap id="userMap" type="com.itheima.domain.User">
    <!-- 主键字段的对应
    这里还有有javaType=和jdbcType属性,一般业务中类型都一样,可以忽略不谢
        property:是pojo中的属性名
        column:是mysql对应的字段名
    -->
    <id property="userId" column="id" ></id>
    <!-- 非主键字段的对应 -->
    <result property="userName" column="username"></result>
    <result property="userBirthday" column="birthday"></result>
    <result property="userSex" column="sex"></result>
    <result property="userAddress" column="address"></result>
</resultMap>

<!-- 具体的操作方法就需要调用上面定义的resultMap
 此时就不能使用resultType了
 -->
<select id="findAll" resultMap="userMap">
    select * from user
</select>

  1. 测试案例(略)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容