MyBatis小记_three

目录

注解开发

环境搭建

1.创建Maven工程

2.创建实体类

3.提供接口,并提供增删改查的方法

4.编写SqlMapConfig.xml 主配置文件

5.采用注解的方式,来进行增删改查

6.测试

7.测试保存用户的方法

8.测试更新用户

9.测试删除一个用户

10.根据id查询一个用户

11.根据姓名模糊查询

12.查询所有用户的个数

当实体类的属性名和表中的字段名不一致时,采用注解怎么配置

1.修改实体类的属性名

2.配置实体类的属性和表中字段的映射关系

使用注解进行多表查询

一对一的关系查询:比如查询该账户所对应的用户信息

1.提供账户的实体类

2.提供账户的接口

3.给账户接口上的方法,添加注解,先查询出所有账户

4.测试

5.上面还只是一个单表查询的测试,下来我们要进行多表查询,查询一个账户所对应的用户信息

6.在账户的接口中添加注解,来进行一对一的查询

7.测试

一对多的查询

1.我在User的接口中进行一对多的配置

2.在账户的接口中提供一个方法,以便查询该用户对应的账户时,使用

3.测试

一级缓存的演示


注解开发

@Insert:实现新增 
@Update:实现更新 
@Delete:实现删除 
@Select:实现查询 
@Result:实现结果集封装 
@Results:可以与@Result 一起使用,封装多个结果集 
@ResultMap:实现引用@Results 定义的封装 
@One:实现一对一结果集封装 
@Many:实现一对多结果集封装 
@SelectProvider: 实现动态 SQL 映射 

环境搭建

1.创建Maven工程

1.在pom.xml中 引入以下jar包
​
<dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

2.创建实体类

public class User implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;//get set 方法略 自己补上}

3.提供接口,并提供增删改查的方法

public interface IUserDao {//查询所有的方法List<User> findAll();//保存用户的方法void saveUser(User user);//更新用户void updateUser(User user);//删除一个用户void deleteUser(Integer id);//根据id查询出一个用户User selectUserById(Integer id);//根据姓名模糊查询List<User> selectUserByName(String name);//查询所有用户的个数int selectAllUser();
}

4.编写SqlMapConfig.xml 主配置文件

<configuration>
<!--properties 用来加载外部的jdbc的配置文件    --><properties resource="jdbcConfig.properties"/><typeAliases>
<!--给该包下所有的类,都起别名,别名可以是类名的小写,大写--><package name="org.westos.domain"/></typeAliases>
​<environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"></transactionManager><!--配置数据源(连接池)--><dataSource type="POOLED">
<!--                需要用${jdbc配置文件中的键名}--><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><!--扫描该包下所有的接口,所对应的映射文件--><package name="org.westos.dao"/></mappers>
</configuration>

5.采用注解的方式,来进行增删改查

1.在接口的查询所有方法上添加 @select 注解
​
public interface IUserDao {//查询所有的方法@Select(value = "select * from user")List<User> findAll();}

6.测试

@Testpublic void testFindAll() throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession sqlSession = factory.openSession();IUserDao dao = sqlSession.getMapper(IUserDao.class);List<User> list = dao.findAll();for (User user : list) {System.out.println(user);}}

7.测试保存用户的方法

1.在接口中的保存用户方法上面,添加 @insert 注解public interface IUserDao {//保存用户的方法@Insert(value = "insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})")void saveUser(User user);
​
}
2. 测试
​@Testpublic void test() throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession sqlSession = factory.openSession();IUserDao dao = sqlSession.getMapper(IUserDao.class);User user = new User();user.setUsername("金城武");user.setSex("男");user.setBirthday(new Date());user.setAddress("陕西西安");dao.saveUser(user);//提交事务sqlSession.commit();
​in.close();sqlSession.close();

8.测试更新用户

1.在接口中的更新用户方法上添加  @Update 的注解
public interface IUserDao {//更新用户@Update("update user set username=#{username},address=#{address} where id=#{id}")void updateUser(User user);
​
}
​@Testpublic void test() throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession sqlSession = factory.openSession();IUserDao dao = sqlSession.getMapper(IUserDao.class);User user = new User();user.setId(66);user.setUsername("金巧巧");user.setAddress("陕西咸阳");dao.updateUser(user);
​//提交事务sqlSession.commit();
​in.close();sqlSession.close();
​
​
​}

9.测试删除一个用户

1.在接口中的方法上 添加@Delete注解
​
//删除一个用户@Delete("delete from user where id=#{id}")void deleteUser(Integer id);2.测试:IUserDao dao = sqlSession.getMapper(IUserDao.class);dao.deleteUser(66);//提交事务sqlSession.commit();

10.根据id查询一个用户

1.在接口中的方法上,添加注解
​//根据id查询出一个用户@Select(value = "select * from user where id=#{uid}")User selectUserById(Integer id);2.测试IUserDao dao = sqlSession.getMapper(IUserDao.class);User user = dao.selectUserById(66);System.out.println(user);//提交事务sqlSession.commit();

11.根据姓名模糊查询

1.在接口的方法上添加注解//根据姓名模糊查询@Select(value = "select * from user where username like #{name}")List<User> selectUserByName(String name);2.测试IUserDao dao = sqlSession.getMapper(IUserDao.class);List<User> list = dao.selectUserByName("%沈%");for (User user : list) {System.out.println(user);}

12.查询所有用户的个数

1.在接口的方法上添加注解//查询所有用户的个数@Select(value = "select count(*) from user")int selectAllUser();2.测试IUserDao dao = sqlSession.getMapper(IUserDao.class);int i = dao.selectAllUser();System.out.println(i);

当实体类的属性名和表中的字段名不一致时,采用注解怎么配置

1.修改实体类的属性名

public class User implements Serializable {private Integer myid;private String myusername;private Date mybirthday;private String mysex;private String myaddress;//get set 方法略 自己补上}  说明:当我们实体类的属性名和表中字段名不一致后,我们查询用户时,就封装不到实体类当中了那么我们就得进行配置

2.配置实体类的属性和表中字段的映射关系

1.我们就在接口中的查询所有方法上使用 @Results 注解 来配置 实体类属性名和表中字段名的映射关系,配好之后,我们查询所有用户,就可以封装进实体类中了
​
​
public interface IUserDao {//查询所有的方法@Select(value = "select * from user")@Results(id = "userMap", value = {//配置主键字段 id = true 表示这是主键字段@Result(id = true, property = "myid", column = "id"),//配置其他普通字段@Result(property = "myusername", column = "username"),@Result(property = "mybirthday", column = "birthday"),@Result(property = "mysex", column = "sex"),@Result(property = "myaddress", column = "address")})List<User> findAll();}  2. 我们接口中还有一个根据id查询单个用户,也要将查询出的用户封装到实体类中,所以这个方法,也要配置 映射关系,但是,我们不是把上面配置好的映射关系,再复制一份,而是通过上面配置的 id名 引用一下即可,那么就使用 @ResultMap 来引用配置好的映射关系//根据id查询出一个用户@Select(value = "select * from user where id=#{uid}")@ResultMap(value = "userMap")  //引用上面配置好的映射关系User selectUserById(Integer id);

使用注解进行多表查询

一对一的关系查询:比如查询该账户所对应的用户信息

1.提供账户的实体类

public class Account implements Serializable {private Integer id;private Integer uid;private Double money;//get set 方法略 自己补上}   

2.提供账户的接口

public interface IAccountDao {//查询所有账户,以及该账户所对应的用户信息List<Account> findAll();
}

3.给账户接口上的方法,添加注解,先查询出所有账户

public interface IAccountDao {//查询所有账户,以及该账户所对应的用户信息@Select("select * from account")List<Account> findAll();
}

4.测试

public class TestAccount {public static void main(String[] args) throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession sqlSession = factory.openSession();IAccountDao dao = sqlSession.getMapper(IAccountDao.class);List<Account> list = dao.findAll();for (Account account : list) {System.out.println(account);}in.close();sqlSession.close();}
}

5.上面还只是一个单表查询的测试,下来我们要进行多表查询,查询一个账户所对应的用户信息

1.用户表和账户表之间,他是一对多的关系,但是我们站在账户表角度看,那么一个账户就是属于一个用户,也就是说,多对一的关系,在MyBatis中看来就是一对一的关系
​
2.首先,在账户的实体类中,维护一个用户的对象,来描述这个一对一的关系
​public class Account implements Serializable {private Integer id;private Integer uid;private Double money;//在多方维护一个一方的对象,来体现一对一的关系private User user;// get set 方法略 自己补上
}

6.在账户的接口中添加注解,来进行一对一的查询

1.我们先配置账户实体类和账户表的映射关系
2.再配置账户和用户的 一对一的关系
​
public interface IAccountDao {//查询所有账户,以及该账户所对应的用户信息@Select("select * from account")@Results(id = "accountMap", value = {@Result(id = true, property = "id", column = "id"),@Result(property = "uid", column = "uid"),@Result(property = "money", column = "money"),//配置一对一的关系@Result(property = "user", column = "uid", one = @One(select = "org.westos.dao.IUserDao.selectUserById", fetchType = FetchType.EAGER))})List<Account> findAll();
}
​
说明://配置一对一的关系 那么在@Result注解中有一个one属性可以配置一对一/** property = "user" 多方维护的一方的对象*  column = "uid" 多方表中通过uid这个字段跟一方产生关系*  one 一对一关系的配置select = "org.westos.dao.IUserDao.selectUserById" 查询依据 使用的是用户接口中通过id查询单个用户的这个方法fetchType = FetchType.EAGER  加载模式,使用的立即加载一般一对一的查询使用立即加载一对多 使用延迟加载* */
​

7.测试

public class TestAccount {public static void main(String[] args) throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession sqlSession = factory.openSession();IAccountDao dao = sqlSession.getMapper(IAccountDao.class);List<Account> list = dao.findAll();for (Account account : list) {System.out.println(account);//获取该账户对应得用户信息User user = account.getUser();System.out.println(user);}in.close();sqlSession.close();}
}
​

一对多的查询

我们站在用户的角度,那么一个用户肯定有多个账户
我们在用户的实体类中维护一个集合来描述这个一对多的关系
​
public class User implements Serializable {private Integer myid;private String myusername;private Date mybirthday;private String mysex;private String myaddress;//提供一个集合来描述一对多的关系private List<Account> accounts;//get set 方法略 自己 补上  }   

1.我在User的接口中进行一对多的配置

public interface IUserDao {//查询所有的方法@Select(value = "select * from user")@Results(id = "userMap", value = {//配置主键字段 id = true 表示这是主键字段@Result(id = true, property = "myid", column = "id"),//配置其他普通字段@Result(property = "myusername", column = "username"),@Result(property = "mybirthday", column = "birthday"),@Result(property = "mysex", column = "sex"),@Result(property = "myaddress", column = "address"),//配置一对多的关系@Result(property = "accounts",column = "id",many = @Many(select = "org.westos.dao.IAccountDao.findAccountById",fetchType = FetchType.LAZY 
​))})List<User> findAll();
​//根据id查询出一个用户@Select(value = "select * from user where id=#{uid}")@ResultMap(value = "userMap")User selectUserById(Integer id);}
​
说明: //配置一对多的关系//  property = "accounts", 一方维护的集合名//  column = "id"  一方 id 这个字段跟多方产生关系@Result(property = "accounts",column = "id",many = @Many(//查询依据,使用账户接口中的方法根据uid查询该用户对应的账户select = "org.westos.dao.IAccountDao.findAccountById",fetchType = FetchType.LAZY //延迟加载
​))

2.在账户的接口中提供一个方法,以便查询该用户对应的账户时,使用

public interface IAccountDao {//查询所有账户,以及该账户所对应的用户信息@Select("select * from account")@Results(id = "accountMap", value = {@Result(id = true, property = "id", column = "id"),@Result(property = "uid", column = "uid"),@Result(property = "money", column = "money"),@Result(property = "user", column = "uid", one = @One(select = "org.westos.dao.IUserDao.selectUserById", fetchType = FetchType.EAGER))})List<Account> findAll();
​//提供一个根据uid查询账户的方法//注意是根据uid查询@Select("select * from account where uid=#{uid}")Account findAccountById(Integer id);
}
​

3.测试

    @Testpublic void test() throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession sqlSession = factory.openSession();IUserDao dao = sqlSession.getMapper(IUserDao.class);List<User> list = dao.findAll();for (User user : list) {System.out.println(user);//获取改用户所对应的账户信息List<Account> accounts = user.getAccounts();System.out.println(accounts);}
​in.close();sqlSession.close();
​}

一级缓存的演示

1、什么是缓存存在于内存中的临时数据。为什么使用缓存减少和数据库的交互次数,提高执行效率。什么样的数据能使用缓存,什么样的数据不能使用适用于缓存:经常查询并且不经常改变的。 省市区数据的正确与否对最终结果影响不大的。小软文,自媒体写的花边新闻不适用于缓存:经常改变的数据数据的正确与否对最终结果影响很大的。例如:商品的库存,银行的汇率,股市的牌价。
​

Mybatis中的一级缓存一级缓存:它指的是Mybatis中SqlSession对象的缓存。当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。当SqlSession对象消失时,mybatis的一级缓存也就消失了。
​
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。
​
public interface IUserDao2 {//更新用户@Update("update user set username=#{username},address=#{address} where id=#{id}")void updateUser(User user);//根据id查询出一个用户@Select("select * from user where id=#{uid}")User selectUserById(Integer id);
}
public class TestUserDao {public static void main(String[] args) throws IOException {//加载主配置文件InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");//构建SessionFactorySqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);//获取sqlSessionSqlSession sqlSession = sessionFactory.openSession();//获取接口的代理对象IUserDao dao = sqlSession.getMapper(IUserDao.class);
​//第一次查询,根据id查询出一个用户User user = dao.selectUserById(59);System.out.println(user); //不要重写toString方法,打印一下地址值
​//sqlSession.clearCache();清空一级缓存//第一次查询出用户后,我们更新用户,也会清空一级缓存//user.setUsername("张全蛋");//user.setAddress("陕西咸阳");//dao.updateUser(user);//再进行第二次查询,如果之前没有清空缓存,就会从缓存中查询,如果清空了,就从数据库中查询User user2 = dao.selectUserById(59);System.out.println(user2); //System.out.println(user2==user); //对比两次查询的对象是否是同一个对象sqlSession.commit();
​//释放资源in.close();sqlSession.close();}
}
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/16726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中小企业如何低成本实施MES管理系统

中小企业在市场竞争中需要有高效的管理体系来支持其运营和发展。中小企业MES管理系统是一种先进的管理系统&#xff0c;可以提升工厂智能化水平&#xff0c;提高生产效率&#xff0c;是中小企业必须采取的有效管理工具。然而&#xff0c;由于资金和技术的限制&#xff0c;中小企…

【C#常用操作】

excel相关操作 using Excel Microsoft.Office.Interop.Excel;public Excel.Application app; public Excel.Workbooks wbs; public Excel.Workbook wb; public Excel.Worksheets wss; public Excel.Worksheet ws;/// <summary> /// 取得打开excel句柄 /// </summary…

【SpringBoot系列】- 四大核心之actuator(程序监控器)

【SpringBoot系列】- 四大核心之actuator(程序监控器) 文章目录 【SpringBoot系列】- 四大核心之actuator(程序监控器)一、概述二、Spring Boot Actuator应用2.1 在项目POM文件中导入Actuator2.2 application配置2.3 配置详解2.3.1 Sensor 类 endpoints2.3.2 Actuator 类 endpo…

反转链表(JS)

反转链表 题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&…

MySQL初探

Background 通过阅读小林coding&#xff0c;大致了解了mysql数据库的种种特点&#xff0c;与之前学的数据库实现大体思路相同&#xff0c;感觉学习不能停留在理论层面&#xff0c;要调研生产级别的中间件实现。 一条代码运行在mysql上的流程 1. 连接的过程需要先经过 TCP 三次…

php://filter绕过死亡exit

文章目录 php://filter绕过死亡exit前言[EIS 2019]EzPOP绕过exit 参考 php://filter绕过死亡exit 前言 最近写了一道反序列化的题&#xff0c;其中有一个需要通过php://filter去绕过死亡exit()的小trick&#xff0c;这里通过一道题目来讲解 [EIS 2019]EzPOP 题目源码&#…

C语言每日一题:9.《数据结构》链表的中间节点+链表的倒数第k个节点。

第一题&#xff1a; 题目链接&#xff1a; >思路一&#xff1a; 1.第一遍遍历链表&#xff0c;直到找到尾结束第一次遍历&#xff0c;遍历的过程中记录链表长度。定义长度为k。 2.确定中间是第几个节点&#xff0c;计算是k/21根据题目要求。 3.再一次去遍历我们的数组&…

实战!聊聊工作中使用了哪些设计模式

实战&#xff01;聊聊工作中使用了哪些设计模式 策略模式 业务场景 假设有这样的业务场景&#xff0c;大数据系统把文件推送过来&#xff0c;根据不同类型采取不同的解析方式。多数的小伙伴就会写出以下的代码&#xff1a; if(type"A"){//按照A格式解析}else if(t…

Electron逆向调试

复杂程序处理方式&#xff1a; 复杂方式通过 调用窗口 添加命令行参数 启动允许调用&#xff0c;就可以实现调试发布环境的electron程序。 断点调试分析程序的走向&#xff0c;程序基本上会有混淆代码处理&#xff0c; 需要调整代码格式&#xff0c;处理程序。

建木-自动化部署-dockerfile文件书写-自动化部署jar包完成docker运行镜像-dockerfile书写介绍

阿丹&#xff1a; 在自动化部署的时候jar包要如何进行部署。就需要通过使用书写dockerfile文件来进行触发的时候执行docker指令来完成镜像的部署以及运行。 什么是dockerFile dockerfile是自定义镜像的一套规则dockerfie由多条指令构成&#xff0c;Dockerfile中的每一条指令都…

基于 Docker 的深度学习环境:Windows 篇

本篇文章&#xff0c;我们聊聊如何在 Windows 环境下使用 Docker 作为深度学习环境&#xff0c;以及快速运行 SDXL 1.0 正式版&#xff0c;可能是目前网上比较简单的 Docker、WSL2 配置教程啦。 写在前面 早些时候&#xff0c;写过一篇《基于 Docker 的深度学习环境&#xff…

spring注解驱动开发(一)

Spring常用注解&#xff08;绝对经典&#xff09; 1、需要导入的spring框架的依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.12.RELEASE</version></dependenc…

Spring源码(二)Spring底层架构核心概念解析

1、BeanDefinition BeanDefinition表示Bean定义&#xff0c;BeanDefinition中存在很多属性用来描述一个Bean的特点。比如&#xff1a; class&#xff0c;表示Bean类型scope&#xff0c;表示Bean作用域&#xff0c;单例或原型等lazyInit&#xff1a;表示Bean是否是懒加载initM…

Hbase基础概念

HBase 一、HBase的数据模型1.HBase数据存储结构2.HBase存储概念3.HBase基本架构 二、HBase Shell1.DDL(Data Definition Language)1.namespace2.table 2.DML&#xff08;Data Manipulation Language&#xff09;1.写入数据2.读取数据3.删除数据 三、HBase组成架构1. Master架构…

STM32 CubeMX 定时器(普通模式和PWM模式)

STM32 CubeMX STM32 CubeMX 定时器&#xff08;普通模式和PWM模式&#xff09; STM32 CubeMXSTM32 CubeMX 普通模式一、STM32 CubeMX 设置二、代码部分STM32 CubeMX PWM模式一、STM32 CubeMX 设置二、代码部分总结 STM32 CubeMX 普通模式 一、STM32 CubeMX 设置 二、代码部分 …

使用Pytest生成HTML测试报告

背景 最近开发有关业务场景的功能时&#xff0c;涉及的API接口比较多&#xff0c;需要自己模拟多个业务场景的自动化测试&#xff08;暂时不涉及性能测试&#xff09;&#xff0c;并且在每次测试完后能够生成一份测试报告。 考虑到日常使用Python自带的UnitTest&#xff0c;所…

【JVM】详细解析java创建对象的具体流程

目录 一、java创建对象的几种方式 1.1、使用new关键字 1.2、反射创建对象 1.2.1、Class.newInstance创建对象 1.2.2、调用构造器再去创建对象Constructor.newInstance 1.3、clone实现 1.4、反序列化 二、创建对象的过程 2.1、分配空间的方式 1、指针碰撞 2、空闲列表 …

ElementUI 实现动态表单数据校验(已解决)

文章目录 &#x1f34b;前言&#xff1a;&#x1f34d;正文1、探讨需求2、查阅相关文档&#xff08;[element官网](https://element.eleme.cn/#/zh-CN/component/form)&#xff09;官方动态增减表单项示例3、需求完美解决4、注意事项 &#x1f383;专栏分享&#xff1a; &#…

小研究 - 浅析 JVM 中 GC 回收算法与垃圾收集器

本文主要介绍了JVM虚拟机中非常重要的两个部分&#xff0c;GC 回收算法和垃圾收集器。从可回收对象的标记开始&#xff0c;详细介绍 了四个主流的GC算法&#xff0c;详细总结了各自的算法思路及优缺点&#xff0c; 提出了何种情况下应该通常选用哪种算法。 目录 1 标记可回收对…

uniapp项目的pdf文件下载与打开查看

最近写的uniapp项目需要新增一个pdf下载和打开查看功能&#xff0c;摸索了半天终于写了出来&#xff0c;现分享出来供有需要的同行参考&#xff0c;欢迎指正 async function DownloadSignature() {//请求后端接口&#xff0c;返回值为一个url地址let resawait req.flow.flowDo…