MyBatis DAY2:基本使用
发布日期:2021-07-01 05:17:43 浏览次数:2 分类:技术文章

本文共 19404 字,大约阅读时间需要 64 分钟。

一、Mybatis基于代理Dao的单表CRUD操作

1、数据库
CREATE TABLE `user` (  `id` int(11) NOT NULL auto_increment,  `username` varchar(32) NOT NULL COMMENT '用户名称',  `birthday` datetime default NULL COMMENT '生日',  `sex` char(1) default NULL COMMENT '性别',  `address` varchar(256) default NULL COMMENT '地址',  PRIMARY KEY  (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在这里插入图片描述

2、实体类:User.java

路径:src/main/java/top/onefine/domain/User.java

package top.onefine.domain;import java.io.Serializable;import java.util.Date;public class User implements Serializable {
// JavaBean,这个类应是可序列化的——实现serializable接口。 private Integer id; private String username; private String address; private String sex; private Date birthday; # 省略get/set和tostring方法}
3、DAO:IUserDao.java

路径:src/main/java/top/onefine/dao/IUserDao.java

package top.onefine.dao;import top.onefine.domain.User;import java.util.List;public interface IUserDao {
List
findAll(); // 查询所有用户 void saveUser(User user); // 保存用户 void updateUser(User user); // 更新用户 void deleteUser(Integer userId); // 删除用户——根据id User findById(Integer userId); // 查询用户信息——根据id List
findByName(String username); // 根据名称模糊查询用户信息 int findTotal(); // 查询总用户数}
4、配置文件:IUserDao.xml

路径:src/main/resources/top/onefine/dao/IUserDao.xml

insert into user(username, address, sex, birthday) values(#{username}, #{address}, #{sex}, #{birthday})
update user set username=#{username}, address=#{address}, sex=#{sex}, birthday=#{birthday} where id=#{id}
delete from user where id = #{id}
5、测试类:MyBatisTest.java

路径:src/test/java/top/onefine/test/MyBatisTest.java

package top.onefine.test;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 top.onefine.dao.IUserDao;import top.onefine.domain.User;import java.io.InputStream;import java.util.Date;import java.util.List;public class MyBatisTest {
private InputStream is; private SqlSession session; private IUserDao userDao; @Before // 用于在测试方法执行之前执行 public void init() throws Exception {
is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); session = factory.openSession(); userDao = session.getMapper(IUserDao.class); } @After // 用于在测试方法执行之后执行 public void destroy() throws Exception{
session.commit(); // 增删改一定要提交事务 session.close(); is.close(); } /** * 测试查询所有 * @throws Exception */ @Test public void testFindAll() throws Exception {
List
users = userDao.findAll(); for (User user: users) System.out.println(user); //快捷键sout } /** * 测试保存操作 */ @Test public void testSave() {
User user = new User(); user.setUsername("one fine"); user.setAddress("云南省 昆明市"); user.setSex("男"); user.setBirthday(new Date()); userDao.saveUser(user); // 执行保存方法 } /** * 测试更新操作 */ @Test public void testUpdate() {
User user = new User(); user.setId(48); user.setUsername("one fine up"); user.setAddress("云南省 红河州"); user.setSex("男"); user.setBirthday(new Date()); userDao.updateUser(user); // 执行 } /** * 测试删除操作 */ @Test public void testDelete() {
userDao.deleteUser(43); } /** * 测试查询一个用户的方法 */ @Test public void testFindOne() {
User user = userDao.findById(49); System.out.println(user); } /** * 测试模糊查询操作 */ @Test public void testFindByName() {
List
users = userDao.findByName("%王%"); // List
users = userDao.findByName("王"); // 另一种方式 for (User user : users) System.out.println(user); } /** * 测试查询总记录条数 */ @Test public void testFindTotal() {
int count = userDao.findTotal(); System.out.println(count); }}
5、拓展

问题:关于自增长类型新增id的返回值,MySQL中查询方法:

# 对于自增长类型查询刚刚插入的idINSERT INTO user(username, address, sex, birthday) VALUES('testUser', '云南省昆明市', '男', '2020-01-02');SELECT LAST_INSERT_ID();

keyProperty代表要返回的属性值id名称,对应实体类

keyColumn是数据库id的列名,对应数据库,可省略 keyColumn="id"
order:取值为AFTER,表示是插入后的行为,即插入后执行获取id的操作
resultType代表返回值的类型

select last_insert_id()
insert into user(username, address, sex, birthday) values(#{username}, #{address}, #{sex}, #{birthday})

测试类:

/**     * 测试保存操作,同时返回插入数据库的id     */    @Test    public void testSaveBackId() {
User user = new User(); user.setUsername("one test save back id"); user.setAddress("云南省 昆明市test"); user.setSex("女"); user.setBirthday(new Date()); System.out.println("保存操作之前:" + user); // 打印结果:保存操作之前:User{id=null, username='one test save back id', address='云南省 昆明市test', sex='女', birthday=Wed Jan 08 09:41:15 CST 2020} userDao.saveUser(user); // 执行保存方法 System.out.println("保存操作之后:" + user); // 打印结果:保存操作之后:User{id=53, username='one test save back id', address='云南省 昆明市test', sex='女', birthday=Wed Jan 08 09:41:15 CST 2020} }

二、MyBatis的参数和返回值

【一】、MyBatis的参数输入——传递 pojo 包装对象

上面已经介绍了 SQL 语句传参,使用标签的parameterType 属性来设定。该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类,这里将介绍如何使用实体类的包装类作为参数传递。

基 本 类 型 和 String 我 们 可 以 直 接 写 类 型 名 称 , 也 可 以 使 用 包 名 . 类 名 的 方 式 , 例 如 :java.lang.String

实体类类型,目前我们只能使用全限定类名。

究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,而我们的是实体类并没有注册别名,所以必须写全限定类名。后面将讲解如何注册实体类的别名。

- 基本类型# 第一类:整型 byte short int long# 第二类:浮点型 float double# 第三类:逻辑型 boolean(它只有两个值可取true false)# 第四类:字符型 char- 引用类型:如new出来的对象- 实体类型:关于POJO和JavaBean的区别详:https://blog.csdn.net/kobexiaol/article/details/78195856# 简要说明# POJO其实是比javabean更纯净的简单类或接口。POJO严格地遵守简单对象的概念,而一些JavaBean中往往会封装一些简单逻辑。# POJO主要用于数据的临时传递,它只能装载数据, 作为数据存储的载体,而不具有业务逻辑处理的能力。# Javabean虽然数据的获取与POJO一样,但是javabean当中可以有其它的方法。- 实体类的包装类

OGNL表达式:Object Graphic Navigation Language,对象图导航语言

它是通过对象的取值方法来获取数据。在写法上把get给省略了。比如:我们获取用户的名称

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

mybatis中为什么能直接写username,而不用user.呢:因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名。


开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

Pojo 类中包含 pojo。

需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。

1、编写 QueryVo:QueryVo.java

位置:src/main/java/top/onefine/domain/QueryVo.java

package top.onefine.domain;public class QueryVo {
private User user; // 必须提供get/set方法,ognl处理 public User getUser() {
return user; } public void setUser(User user) {
this.user = user; }}
2、编写持久层接口:IUserDao.java

路径:src/main/java/top/onefine/dao/IUserDao.java

public interface IUserDao {
List
findUserByVo(QueryVo vo); // 根据queryVo中的条件查询用户}
3、持久层接口的映射文件:IUserDao.xml

路径:src/main/resources/top/onefine/dao/IUserDao.xml

4、测试
/**     * 测试使用QueryVo作为查询条件     */    @Test    public void testFindByVo() {
QueryVo vo = new QueryVo(); User user = new User(); user.setUsername("%王%"); vo.setUser(user); List
users = userDao.findUserByVo(vo); for (User u : users) System.out.println(u); }

【二】、Mybatis 的输出结果封装

一个现象:

1、数据库

在这里插入图片描述

2、实体类:User.java

路径:src/main/java/top/onefine/domain/User.java

package top.onefine.domain;import java.io.Serializable;import java.util.Date;public class User implements Serializable {
// JavaBean,这个类应是可序列化的——实现serializable接口。 private Integer userId; private String userName; private String userAddress; private String userSex; private Date userBirthday; // 省略get/set和tostring方法}
3、配置文件:IUserDao.xml

路径:src/main/resources/top/onefine/dao/IUserDao.xml

select last_insert_id()
insert into user(username, address, sex, birthday) values(#{userName}, #{userAddress}, #{userSex}, #{userBirthday})
update user set username=#{userName}, address=#{userAddress}, sex=#{userSex}, birthday=#{userBirthday} where id=#{userId}
delete from user where id = #{userId}
4、测试

路径:src/test/java/top/onefine/test/MyBatisTest.java

/**     * 测试查询所有     * @throws Exception     */    @Test    public void testFindAll() throws Exception {
List
users = userDao.findAll(); for (User user: users) System.out.println(user); //快捷键sout }
5、结果

在这里插入图片描述

6、分析

在这里插入图片描述

mysql在windows下不区分大小写,但linux下严格区分大小写,所以username字段能填充,其他不能。

7、解决
7.1 法一:取别名(效率最高)——resultType 配置结果类型

resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。在前面的 CRUD 案例中已经对此属性进行过应用了。

需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名;没有注册过的必须使用全限定类名。例如:我们的实体类此时必须是全限定类名(后面会讲解如何配置实体类的别名)

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

实现封装。

在这里插入图片描述

7.2 法二:采用由MyBatis提供的配置的方式——resultMap 结果类型

resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。

在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。

由于法二要多解析一次xml,所以执行效率没有第一种方法快。但是好处是开发效率变高,因为所有的查询操作都可以将resultType改为resultMap,而可以继续使用实体类的属性名。

三、Mybatis 传统 DAO 层开发

1、实体类:User.java

路径:src/main/java/top/onefine/domain/User.java

package top.onefine.domain;import java.io.Serializable;import java.util.Date;public class User implements Serializable {
// JavaBean,这个类应是可序列化的——实现serializable接口。 private Integer id; private String username; private String address; private String sex; private Date birthday; // 省略get/set和tostring方法 }}
2、DAO:IUserDao.java

路径:src/main/java/top/onefine/dao/IUserDao.java

package top.onefine.dao;import top.onefine.domain.User;import java.util.List;public interface IUserDao {
List
findAll(); // 查询所有用户 void saveUser(User user); // 保存用户 void updateUser(User user); // 更新用户 void deleteUser(Integer userId); // 删除用户——根据id User findById(Integer userId); // 查询用户信息——根据id List
findByName(String username); // 根据名称模糊查询用户信息 int findTotal(); // 查询总用户数}
3、DAO实现:UserDaoImpl.java

路径:src/main/java/top/onefine/dao/impl/UserDaoImpl.java

package top.onefine.dao.impl;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import top.onefine.dao.IUserDao;import top.onefine.domain.User;import java.util.List;public class UserDaoImpl implements IUserDao {
private SqlSessionFactory factory; public UserDaoImpl(SqlSessionFactory factory) {
this.factory = factory; } public List
findAll() {
// 1. 根据factory获取SqlSession对象 SqlSession session = factory.openSession(); // 2. 调用SqlSession中的方法,实现查询列表;参数就是能获取配置信息的key List
users = session.selectList("top.onefine.dao.IUserDao.findAll"); // 3. 释放资源 session.close(); return users; } public void saveUser(User user) {
SqlSession session = factory.openSession(); session.insert("top.onefine.dao.IUserDao.saveUser", user); session.commit(); // 提交事务 session.close(); } public void updateUser(User user) {
SqlSession session = factory.openSession(); session.update("top.onefine.dao.IUserDao.updateUser", user); session.commit(); // 提交事务 session.close(); } public void deleteUser(Integer userId) {
SqlSession session = factory.openSession(); session.delete("top.onefine.dao.IUserDao.deleteUser", userId); // delete和insert实际上执行的是update session.commit(); // 提交事务 session.close(); } public User findById(Integer userId) {
SqlSession session = factory.openSession(); User user = session.selectOne("top.onefine.dao.IUserDao.findById", userId); session.close(); return user; } public List
findByName(String username) {
SqlSession session = factory.openSession(); List
users = session.selectList("top.onefine.dao.IUserDao.findByName", username); session.close(); return users; } public int findTotal() {
SqlSession session = factory.openSession(); Integer count = session.selectOne("top.onefine.dao.IUserDao.findTotal"); session.close(); return count; }}
4、配置文件:IUserDao.xml

路径:src/main/resources/top/onefine/dao/IUserDao.xml

select last_insert_id()
insert into user(username, address, sex, birthday) values(#{username}, #{address}, #{sex}, #{birthday})
update user set username=#{username}, address=#{address}, sex=#{sex}, birthday=#{birthday} where id=#{id}
delete from user where id = #{id}
5、测试类:MyBatisTest.java

路径:src/test/java/top/onefine/test/MyBatisTest.java

package top.onefine.test;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 top.onefine.dao.IUserDao;import top.onefine.dao.impl.UserDaoImpl;import top.onefine.domain.User;import java.io.InputStream;import java.util.Date;import java.util.List;public class MyBatisTest {
private InputStream is; private SqlSession session; private IUserDao userDao; @Before // 用于在测试方法执行之前执行 public void init() throws Exception {
is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); // session = factory.openSession(); // userDao = session.getMapper(IUserDao.class); // 3. 使用工厂对象,创建dao对象 userDao = new UserDaoImpl(factory); } @After // 用于在测试方法执行之后执行 public void destroy() throws Exception{
// session.commit(); // 增删改一定要提交事务 // session.close(); is.close(); } /** * 测试查询所有 * @throws Exception */ @Test public void testFindAll() throws Exception {
List
users = userDao.findAll(); for (User user: users) System.out.println(user); //快捷键sout } /** * 测试保存操作 */ @Test public void testSave() {
User user = new User(); user.setUsername("one fine4"); user.setAddress("云南省 昆明市4"); user.setSex("男"); user.setBirthday(new Date()); userDao.saveUser(user); // 执行保存方法 } /** * 测试保存操作,同时返回插入数据库的id */ @Test public void testSaveBackId() {
User user = new User(); user.setUsername("one test save back id"); user.setAddress("云南省 昆明市test3"); user.setSex("女"); user.setBirthday(new Date()); System.out.println("保存操作之前:" + user); // 打印结果:保存操作之前:User{id=null, username='one test save back id', address='云南省 昆明市test', sex='女', birthday=Wed Jan 08 09:41:15 CST 2020} userDao.saveUser(user); // 执行保存方法 System.out.println("保存操作之后:" + user); // 打印结果:保存操作之后:User{id=53, username='one test save back id', address='云南省 昆明市test', sex='女', birthday=Wed Jan 08 09:41:15 CST 2020} } /** * 测试更新操作 */ @Test public void testUpdate() {
User user = new User(); user.setId(48); user.setUsername("one fine up up"); user.setAddress("云南省 红河州"); user.setSex("男"); user.setBirthday(new Date()); userDao.updateUser(user); // 执行 } /** * 测试删除操作 */ @Test public void testDelete() {
userDao.deleteUser(57); } /** * 测试查询一个用户的方法 */ @Test public void testFindOne() {
User user = userDao.findById(49); System.out.println(user); } /** * 测试模糊查询操作 */ @Test public void testFindByName() {
List
users = userDao.findByName("%王%"); // List
users = userDao.findByName("王"); // 另一种方式 for (User user : users) System.out.println(user); } /** * 测试查询总记录条数 */ @Test public void testFindTotal() {
int count = userDao.findTotal(); System.out.println(count); }}

四、SqlMapConfig.xml配置文件

【一】、properties标签中resource属性和url属性

1、jdbcConfig.properties

路径:src/main/resources/jdbcConfig.properties

jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://192.168.47.128:3306/eesy_mybatis?characterEncoding=UTF-8jdbc.username=rootjdbc.password=123456
2、SqlMapConfig.xml

路径:src/main/resources/SqlMapConfig.xml

【二】、typeAliases和package标签

typeAliases(类型别名):Mybatis 支持的默认别名,可以采用自定义别名方式来开发。

1、SqlMapConfig.xml

路径:src/main/resources/SqlMapConfig.xml

2、IUserDao.xml

路径:src/main/resources/top/onefine/dao/IUserDao.xml

select last_insert_id()
insert into user(username, address, sex, birthday) values(#{username}, #{address}, #{sex}, #{birthday})
update user set username=#{username}, address=#{address}, sex=#{sex}, birthday=#{birthday} where id=#{id}
delete from user where id = #{id}

转载地址:https://onefine.blog.csdn.net/article/details/103885256 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:MyBatis DAY3:深入和多表
下一篇:MyBatis DAY1:入门

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月21日 03时33分05秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章