Mybatis学习
Mybatis学习
1. 简介#
1.1 什么是Mybatis#
- MyBatis 是一款优秀的持久层框架
- 它支持自定义 SQL、存储过程以及高级映射
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- 现迁移到GitHub
1.2 如何获取Mybatis#
-
Maven仓库:https://mvnrepository.com
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency>
1.3 持久化#
1.3.1 数据持久化#
- 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 内存:断电即失
- 数据库(jdbc),io文件持久化
- 生活结合:冰箱冷藏
1.3.2 为什么需要持久化?#
- 有一些对象,不能让他丢掉
- 内存太贵
1.4 持久层#
Dao层,Service层,Controller层…
- 完成持久化工作的代码块
- 层是界限十分明显的
1.5 为什么需要MyBatis#
- 帮助程序员将数据存入到数据库中
- 方便
- 传统的jdbc代码太复杂了,简化代码,形成框架。----自动化
- 不使用MyBatis也可以,更容易上手
- 优点:
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射。
- 提供对象关系映射标签,支持对象关系组建维护。
- 提供xml标签,支持编写动态sql。
2. 第一个Mybatis程序#
思路:搭建环境—>导入Mybatis—>编写代码---->测试
2.1 搭建环境#
-
搭建数据库
create table if not exists `user`( `id` int(20) not null auto_increment comment '编号', `name` varchar(30) default null comment '用户名', `pwd` varchar(30) default null comment '密码', primary key(`id`) )engine=innodb default charset='utf8' insert into `user`(`id`,`name`,`pwd`) values (1,'leez','123456'), (2,'小白','123123'), (2,'张三','123123')
-
新建项目
-
删除src目录
-
导入maven依赖
<!--导入依赖--> <dependencies> <!--MySQL驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
2.2 创建子模块#
-
编写Mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <!--configuration核心配置文件--> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT"/> <property name="username" value="root"/> <property name="password" value=""/> </dataSource> </environment> </environments> <!--每一个Mapper.xml都需要在MyBatis核心配置文件中注册--> <mappers> <mapper resource="com/LEEZ/dao/UserMapper.xml"/> </mappers> </configuration>
-
编写Mybatis工具类
public class MybatisUtil { private static SqlSessionFactory sqlSessionFactory; static{ //获取Mybatis第一步 //获取SqlSessionFactory try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(); } }
2.3 编写代码#
-
实体类
package com.LEEZ.pojo; public class User { private int id; private String name; private String pwd; public User() { } public User(int id, String name, String pwd) { this.id = id; this.name = name; this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
-
Dao接口
public interface UserDao { public List<User> getUserList(); }
-
接口实现类,由原来的UserDaoImpl转换为Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace绑定一个对应的dao/mapper接口--> <mapper namespace="com.LEEZ.dao.UserDao"> <!--id对应方法名字--> <select id="getUserList" resultType="com.LEEZ.pojo.User"> select * from mybatis.user where id = #{id} </select> </mapper>
2.4 测试#
注意点:
org.apache.ibatis.binding.BindingException: Type interface com.LEEZ.dao.UserMapper is not known to the MapperRegistry.
-
核心配置文件中注册UserMapper.xml
<!--每一个Mapper.xml都需要在MyBatis核心配置文件中注册--> <mappers> <mapper resource="com/LEEZ/dao/UserMapper.xml"/> </mappers>
-
Junit测试,测试代码
@Test public void test() { SqlSession sqlSession = null; try { //获取sqlSession对象 sqlSession = MybatisUtil.getSqlSession(); //执行sql UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> userList = userMapper.getUserList(); for (User user: userList) { System.out.println(user); } } catch (Exception e) { e.printStackTrace(); } finally { //关闭sqlSession sqlSession.close(); } }
3. CRUD#
增删改查
3.1 namespace#
namespace中的包名要和接口中的包名一致—uesrDao–>userMapper
3.2 select#
选择查询语句:
- id就是对应的namespace中的方法名
- resultType就是Sql语句执行的返回值
- parameterType就是参数类型
3.3 Insert#
3.4 update#
3.5 delete#
-
编写接口
public interface UserMapper { //获取全部用户 List<User> getUserList(); //根据用户id查询用户 User getUserById(int id); //增加一个用户 int addUser(User user); //修改一个用户 int updateUser(User user); //删除一个用户 int deleteUser(int id); }
-
编写对应Mapper中的sql语句
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace绑定一个对应的dao/mapper接口--> <mapper namespace="com.LEEZ.dao.UserMapper"> <!--id对应方法名字--> <select id="getUserList" resultType="com.LEEZ.pojo.User"> select * from mybatis.user </select> <select id="getUserById" parameterType="int" resultType="com.LEEZ.pojo.User"> select * from user where id = #{id} </select> <insert id="addUser" parameterType="com.LEEZ.pojo.User"> insert into user (id,name,pwd) values (#{id},#{name},#{pwd}) </insert> <update id="updateUser" parameterType="com.LEEZ.pojo.User"> update user set name = #{name},pwd = #{pwd} where id = #{id} </update> <delete id="deleteUser" parameterType="int"> delete from user where id = #{id} </delete> </mapper>
-
测试
@Test public void test() { SqlSession sqlSession = null; try { //获取sqlSession对象 sqlSession = MybatisUtil.getSqlSession(); //执行sql UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> userList = userMapper.getUserList(); for (User user : userList) { System.out.println(user); } } catch (Exception e) { e.printStackTrace(); } finally { //关闭sqlSession sqlSession.close(); } } @Test public void testGetUserById() { SqlSession sqlSession = null; try { //获取sqlSession对象 sqlSession = MybatisUtil.getSqlSession(); //执行sql UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User userById = userMapper.getUserById(1); System.out.println(userById); } catch (Exception e) { e.printStackTrace(); } finally { //关闭sqlSession sqlSession.close(); } } @Test public void testAddUser() { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); int i = userMapper.addUser(new User(3, "李四", "111111")); System.out.println(i); //增删改需要提交事务 sqlSession.commit(); sqlSession.close(); } @Test public void testUpdateUser(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int i = mapper.updateUser(new User(3, "张三", "111111")); System.out.println(i); sqlSession.commit(); sqlSession.close(); } @Test public void testDeleteUser() { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int i = mapper.deleteUser(3); System.out.println(i); sqlSession.commit(); sqlSession.close(); }
注意:增删改查需要提交事务
3.6 万能的map方法#
假设我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!
//万能的map
int addUser2(Map<String,Object> map);
<!--传递map的key-->
<insert id="addUser" parameterType="map" >
insert into mybatis.user(id,name,pwd) values (#{userid},#{userName},#{passWord});
</insert>
@Test
public void addUser2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("userid",5);
map.put("userName","hello");
map.put("passWord","976543");
mapper.addUser2(map);
sqlSession.commit();
sqlSession.close();
}
- Map传递参数,直接在sql中取出key即可!
- 对象传递参数,直接在sql中去对象的属性即可!
- 只有一个基本类型参数的情况下,可以直接在sql中取到!
- 多个参数用Map,或者注解
3.7 模糊查询#
-
java代码执行的时候,传递通配符%%
List<User> userList = mapper.getUserLike("%李%");
-
在sql拼接中使用通配符
select * from user where name like "%"#{value}"%"
4. 配置解析#
4.1 核心配置文件#
mybatis-config.xml
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
4.2、环境配置(environments)#
-
MyBatis 可以配置成适应多种环境
-
不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
-
数据源的配置(比如:type=“POOLED”)
-
学会配置多套运行环境-----更改id
<environments default="id">
-
Mybatis默认的事务管理器就是JDBC,连接池:POOLED
4.3、属性(properties)#
我们可以通过properties属性来实现引用配置文件
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置【db.properties】
编写一个配置文件db.properties:
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT
username = root
password =
在核心配置文件中引入
<!--引入外部配置文件-->
<properties resource="db.properties"/>
4.4 类型别名(typeAliases)#
-
类型别名可为 Java 类型设置一个缩写名字
-
用于 XML 配置,意在降低冗余的全限定类名书写
<!--可以给实体类起别名--> <typeAliases> <typeAlias type="com.LEEZ.pojo.User" alias="User"/> </typeAliases>
-
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
扫描实体类的包,它的默认别名就为这个类的类名,首字母小写
<!--可以给实体类器别名--> <typeAliases> <package name="com.LEEZ.pojo"/> </typeAliases>
-
在实体类比较少的时候,使用第一种方式;如果实体类十分多,建议使用第二种(在实体类中使用注解可以起别名)
4.5 设置#
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
一个配置完整的 settings 元素的示例如下:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
4.6 其他配置#
4.7 映射器(mappers)#
MapperRegistry:注册绑定我们的Mapper文件,每写一个dao层就要写一个Mapper文件
-
方式一:建议使用
<!--每一个Mapper.xml都需要在MyBatis核心配置文件中注册--> <mappers> <mapper resource="com/LEEZ/dao/UserMapper.xml"/> </mappers>
-
方式二:使用class文件绑定注册
<!-- 使用映射器接口实现类的完全限定类名 --> <mappers> <mapper class="com.LEEZ.dao.UserMapper"/> </mappers>
注意:
- 接口和他的Mapper配置文件必须同名
- 接口和他的Mapper配置文件必须在同一个包下
-
方式三:使用扫描包进行绑定注册
<mappers> <package name="com.LEEZ.dao"/> </mappers>
注意:
- 接口和他的Mapper配置文件必须同名
- 接口和他的Mapper配置文件必须在同一个包下
4.8 生命周期和作用域#
生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBuilder:
- 一旦创建了 SqlSessionFactory,就不再需要SqlSessionFactoryBuilder了
- 局部变量
SqlSessionFactory:
- 可以理解为数据库连接池
- SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
- SqlSessionFactory 的最佳作用域是应用作用域,最简单的就是使用单例模式或者静态单例模式
SqlSession:
- 连接到连接池的一个请求
- SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
- 用完之后需要赶紧关闭,否则资源被占用
这里每一个Mapper就代表一个具体的业务
5. 解决属性名和字段名不一致的问题#
5.1 问题#
数据库中的字段
新建一个项目,拷贝之前的,测试实体类字段不一样的情况
public class User {
private int id;
private String name;
private String password;
}
测试出现问题
问题原因
select * from mybatis.user where id =#{id}
select id,name,pwd from mybatis.user where id =#{id}
//此时已经没有pwd
解决方法
-
起别名
<select id="getUserById" parameterType="int" resultType="User"> select id,name,pwd as password from mybatis.user where id =#{id} </select>
5.2 resultMap#
结果集映射
id name pwd
id name password
<!--结果集映射-->
<resultMap id="UserMap" type="User">
<!--column对应数据库的列,property对应实体类的属性-->
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserById" parameterType="int" resultMap="UserMap">
select * from user where id =#{id}
</select>
resultMap
元素是 MyBatis 中最重要最强大的元素- ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了
6. 日志#
6.1 日志工厂#
如果一个数据库操作出现了异常,我们需要排错,日志就是最好的助手
之前: sout,debug
现在:日志工厂
- SLF4J
- LOG4J(3.5.9 起废弃) ----- 掌握
- LOG4J2
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING ----- 掌握
- NO_LOGGING
在Mybatis中具体使用哪一个日志实现,在设置中设定
STDOUT_LOGGING — 标准日志输出
在mybatis核心配置文件中,配置我们的日志
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
6.2 LOG4J#
什么是log4j
- Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
- 我们也可以控制每一条日志的输出格式
- 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程
- 通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
-
先导入log4j的包
<!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
log4j.properties
### 配置根 ### log4j.rootLogger = debug,console,file ### 配置输出到控制台 ### log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold = debug log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n ### 配置输出到文件 ### log4j.appender.file = org.apache.log4j.FileAppender log4j.appender.file.File = ./log/qjd.log log4j.appender.file.Append = true log4j.appender.file.Threshold = debug log4j.appender.file.layout = org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 配置输出到文件,并且每天都创建一个文件 ### log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender log4j.appender.dailyRollingFile.File = logs/log.log log4j.appender.dailyRollingFile.Append = true log4j.appender.dailyRollingFile.Threshold = debug log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout log4j.appender.dailyRollingFile.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 设置输出sql的级别,其中logger后面的内容全部为jar包中所包含的包名 ### log4j.logger.org.mybatis=debug log4j.logger.java.sql=debug log4j.logger.java.sql.Connection=debug log4j.logger.java.sql.Statement=debug log4j.logger.java.sql.PreparedStatement=debug log4j.logger.java.sql.ResultSet=debug
3.配置log4j为日志的实现
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
4.Log4j的使用,直接运行刚才的测试
简单使用
-
在要使用Log4j的类中,导入包import org.apache.log4j.Logger;
-
日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserMapperTest.class); 1
-
日志级别
logger.info("info:进入了testLog4j"); logger.debug("debug:进入了testLog4j"); logger.error("error:进入了testLog4j");
7. 分页#
思考:为什么要分页?
- 减少数据的处理量
7.1 使用Limit分页#
SELECT * FROM user limit startIndex,pageSize;
SELECT * FROM user limit 0,2;
SELECT * FROM user limit 3;#[0,n]
使用Mybatis实现分页,核心就是sql
-
接口
//分页 List<User> getUserListByLimit(Map<String, Integer> map);
-
UserMapper.xml
<!--分页--> <select id="getUserListByLimit" parameterType="map" resultMap="UserMap"> select * from user limit #{startPage},#{pageSize} </select>
-
测试
@Test public void testLimit() { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String, Integer> map = new HashMap<>(); map.put("startPage", 2); map.put("pageSize", 3); List<User> userList = mapper.getUserListByLimit(map); for (User user : userList) { System.out.println(user); } sqlSession.close(); }
7.2 RowBounds分页(不建议使用)#
RowBounds分页了解,不建议使用
不再使用sql实现分页
-
接口
//分页2 List<User> getUserByRowBounds();
-
Mapper.xml
<!-- 分页2--> <select id="getUserByRowBounds" resultMap="UserMap"> select * from mybatis.user </select>
-
测试
@Test public void getUserByRowBounds(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); //RowBounds实现 RowBounds rowBounds = new RowBounds(1, 2); //通过java代码层面实现分页 List<User> userList = sqlSession.selectList("com.qjd.dao.UserMapper.getUserByRowBounds",null,rowBounds); for (User user : userList) { System.out.println(user); } sqlSession.close(); }
7.3 分页插件#
MyBatis 分页插件 PageHelper
如何使用----https://pagehelper.github.io/docs/howtouse/
8. 使用注解开发#
8.1 面向接口编程#
一、概念
-
什么是面向接口编程
面向接口编程就是先把客户的业务逻辑线提取出来,作为接口,业务具体实现通过该接口的实现类来完成。当客户需求变化时,只需编写该业务逻辑的新的实现类,通过更改配置文件(例如Spring框架)中该接口的实现类就可以完成需求,不需要改写现有代码,减少对系统的影响。
-
面向接口编程的优点
- 降低程序的耦合性。其能够最大限度的解耦,所谓解耦既是解耦合的意思,它和耦合相对。耦合就是联系,耦合越强,联系越紧密。在程序中紧密的联系并不是一件好的事情,因为两种事物之间联系越紧密,你更换其中之一的难度就越大,扩展功能debug的难度也就越大。
- 易于程序的扩展;
- 有利于程序的维护;
-
接口编程在设计模式中的体现:开闭原则
其遵循的思想是: 对扩展开放,对修改关闭。其恰恰就是遵循的是使用接口来实现。在使用面向接口的编程过程中,将具体逻辑与实现分开,减少了各个类之间的相互依赖,当各个类变化时,不需要对已经编写的系统进行改动,添加新的实现类就可以了,不在担心新改动的类对系统的其他模块造成影响。
二、设计模式
面向过程编程
面向对象编程
面向接口编程
-
面向过程编程
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向过程是一种以过程为中心的编程思想。面向过程是一种最为实际的思考方式,就算是面向对象的方法也有面向过程的思想。可以说面向过程是一种基础的方法。它考虑的是实际的实现。一般面向过程是从上往下步步求精,所以面向过程最重要的是模块化的思想方法。
-
面向对象编程
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
- 对象:对象是要研究的任何事物。比如人类就是一个对象,然而对象是有属性和方法的,那么身高、体重、年龄、性别等等,这些是每个人都有的特征可以概括为属性。
- 类:类是对象的模板。即类是对一组有相同属性和相同操作的对象的定义,一个类所包含的方法和数据描述一组对象的共同属性和行为。类是在对象之上的抽象,对象则是类的具体化,是类的实例。
- 面向对象的基本特征 封装、继承、多态
- 封装:就是把属性私有化,提供公共方法访问私有对象。
- 继承:当多个类具有相同的特征(属性)和行为(方法)时,可以将相同的部分抽取出来放到一个类中作为父类,其他类继承于这个父类。继承后的子类自动拥有了父类的属性和方法,比如猫、狗、猪他们共同的特征都是动物、都会跑会叫等特征。但是需要注意的是,父类的私有属性(private)和构造方法不能被继承。另外子类可以写自己特有的属性和方法,目的是实现功能的扩展,子类也可以重写父类的方法。
- 多态:简单来说就是“一种定义,多种实现”。同一类事物表现出多种形态。JAVA语言中有方法重载和对象多态两种形式的多态。
- 方法重载:在一个类中,允许多个方法使用同一个名字,但是方法的参数不同,完成的功能也不同
- 对象多态:子类对象可以与父类对象进行相互转换,而且根据其使用的子类的不同,完成的功能也不同
-
面向接口编程
- 什么叫面向接口编程
- 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。
- 关于接口的理解
- 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
- 接口的本身反映了系统设计人员对系统的抽象理解。
- 接口应有两类:
- 第一类是对一个体的抽象,它可对应为一个抽象体(abstract class);
- 第二类是对一个体某一方面的抽象,即形成一个抽象面(interface);
- 一个体有可能有多个抽象面。抽象体与抽象面是有区别的。
- 什么叫面向接口编程
面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题
8.2 使用注解开发#
-
注解在接口上实现
public interface UserMapper { //使用注解 @Select("select * from user") List<User> getUsers(); }
-
需要在核心配置文件中绑定接口
<!--绑定接口--> <mappers> <mapper class="com.LEEZ.dao.UserMapper"/> </mappers>
-
测试
@Test public void test() { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> users = mapper.getUsers(); for (User user : users) { System.out.println(user); } sqlSession.close(); }
本质:反射机制实现
底层:动态代理
8.3 Mybatis详细执行流程#
具体实现:
8.4 注解CRUD#
我们可以在工具类中设置事务自动提交
public static SqlSession getSqlSession() {
//return sqlSessionFactory.openSession();
//openSession()有重载,可以设置自动提交事务
return sqlSessionFactory.openSession(true);
}
CRUD接口
//基本数据类型(框架中Spring也属于基本数据类型)必须有@Param,若有多个参数则写多个@Param,其他数据类型不用写
@Select("select * from user where id = #{id}")
User getUserById(@Param("id") int id);
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int addUser(User user);
@Update("update user set name = #{name},pwd = #{password} where id = #{id}")
int updateUser(User user);
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id") int id);
测试类
@Test
public void testGetUserById() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.getUserById(1);
sqlSession.close();
}
@Test
public void testAddUser() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(7, "小蜜蜂", "123123");
mapper.addUser(user);
sqlSession.close();
}
@Test
public void testUpdateUser() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(7, "捞蜂", "123123");
mapper.updateUser(user);
sqlSession.close();
}
@Test
public void testDeleteUser() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(7);
sqlSession.close();
}
注意:我们必须要将接口注册绑定到我们的核心配置文件中
8.5 关于 @Param(“”) 注解#
- 基本类型的参数或者String需要加上
- 引用类型不需要加
- 如果只有一个基本类型的话,可以忽略,但是建议大家都加上
- 我们在sql中引用的就是我们这里的@Param(“”)中设定的属性名
8.6 #{} 和 ${}#
1、#{}
是预编译处理,${}
是字符串替换
2、mybatis在处理两个字符时,处理的方式也是不同的:
(1)处理#{}
时,会将sql中的#{}
整体替换为占位符(即:?),调用PreparedStatement的set方法来赋值;
(2)在处理 ${ }
时,就是把 ${ }
替换成变量的值。
3、假如用${}
来编写SQL会出现:恶意SQL注入,对于数据库的数据安全性就没办法保证了
4、使用 #{}
可以有效的防止SQL注入,提高系统安全性:
预编译的机制。预编译是提前对SQL语句进行预编译,而后再调用SQL,注入的参数就不会再进行SQL编译。而SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译时SQL时轻而易举的通过,从而导致数据泄露。而预编译机制则可以很好的防止SQL注入。
9. Lombok#
Lombok项目是一个Java库,他是一个插件,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。仅五个字符(@Data)就可以替换数百行代码从而产生干净,简洁且易于维护的Java类。
使用步骤:
-
在IDEA中安装Lombok插件
-
在项目中导入Lombok的jar包
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency>
-
在实体类上加注解即可
@Data @AllArgsConstructor @NoArgsConstructor public class User { private int id; private String name; private String password; }
Lombok所有注解
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
experimental @var
@UtilityClass
说明:
@Data:无参构造,get,set,toString,hashcode,equals
@AllArgsConstructor
@NoArgsConstructor
@Getter and @Setter
@ToString
10. 多对一处理#
多对一:
- 多个学生对应一个老师
- 对于学生而言,关联···多个学生关联一个老师【多对一】
- 对于老师而言,集合···一个老师有很多学生【一对多】
结果映射(resultMap)
association
– 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以是 resultMap
元素,或是对其它结果映射的引用
collection
– 一个复杂类型的集合
嵌套结果映射 – 集合可以是 resultMap
元素,或是对其它结果映射的引用
SQL
新建学生表和教师表
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');
CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
10.1 测试环境搭建#
-
在pom.xml导入lombok(不需要自己添加构造方法等-----用@Data)
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies>
-
在pojo包下新建实体类Teacher,Student
@Data public class Teacher { private int id; private String name; }
@Data public class Student { private int id; private String name; //学生需要关联一个老师 private Teacher teacher; }
-
建立Mapper接口
public interface TeacherMapper { @Select("select *from teacher where id=#{tid}") Teacher getTeacher(@Param("tid") int id); }
public interface StudentMapper { }
-
建立Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--configuration核心配置文件--> <mapper namespace="com.LEEZ.dao.TeacherMapper"> </mapper>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--configuration核心配置文件--> <mapper namespace="com.LEEZ.dao.StudentMapper"> </mapper>
-
在核心配置文件中绑定注册我们的Mapper接口或者文件【有很多方式】
<!--绑定接口--> <mappers> <mapper class="com.LEEZ.dao.StudentMapper"/> <mapper class="com.LEEZ.dao.TeacherMapper"/> </mappers>
-
测试查询是否能够成功
@Test public void testGetTeacher() { SqlSession sqlSession = MybatisUtil.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacher(1); System.out.println(teacher); sqlSession.close(); }
10.2 按照查询嵌套处理#
实现以下sql语句
select s.id ,s.name ,t.name from student s,teacher t where s.tid=t.id
<!--思路-->
<!--首先先获取所有的学生信息-->
<!--然后通过tid获取到对应的老师信息-->
<!--获取到的学生信息中,teacher为null,因此要用结果集映射-->
<select id="getStudentList" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性我们需要单独处理-->
<!--对象:association-->
<!--集合:collection -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{tid}
</select>
结果
10.3 按照结果嵌套处理#
<!--方式二-->
<!--按照结果嵌套处理-->
<select id="getStudentList2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.id tid, t.name tname
from student s,teacher t
where s.tid=t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
11. 一对多处理#
比如:一个老师教多个学生,对于老师而言,就是一对多的关系
11.1 环境搭建,大体同10.1#
实体类:
@Data
public class Student {
private int id;
private String name;
private int tid;
}
@Data
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> studentList;
}
11.2、按照结果嵌套处理#
<!--按结果嵌套查询-->
<select id="getTeacherById" resultMap="TeacherStudents">
select t.id tid,t.name tname,s.id sid,s.name sname
from teacher t, student s
where t.id = s.tid and t.id = #{tid}
</select>
<resultMap id="TeacherStudents" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--复杂的属性我们需要单独处理-->
<!--对象:association-->
<!-- 集合:collection -->
<!--javaType=""指定属性的类型 集合中的泛型信息,我们使用ofType获取-->
<collection property="studentList" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
11.3、按照查询嵌套处理#
<select id="getTeacherById2" resultMap="TeacherStudents2">
select * from teacher where id = #{tid}
</select>
<resultMap id="TeacherStudents2" type="Teacher">
<collection property="studentList" column="id" ofType="Student" select="getStudentsByTeacherId"/>
</resultMap>
<select id="getStudentsByTeacherId" resultType="Student">
select * from student where tid = #{tid}
</select>
11.4 小结#
-
关联-association 【多对一】
-
集合-collection 【一对多】
-
javaType & ofType
-
1javaType用来指定实体类中属性的类型
3.2ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型
-
注意点:
- 保证SQL的可读性,尽量保证通俗易懂
- 注意一对多和多对一中,属性名和字段的问题
- 如果问题不好排查错误,可以使用日志,建议使用log4j
12. 动态SQL#
什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
12.1 搭建环境#
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
创建一个基础工程
-
导包
-
编写配置文件
-
编写实体类
@Data public class Blog { private int id; private String title; private String author; private Date create_Time; private int views; }
-
编写实体类对应的Mapper接口和Mapper.xml文件
public interface BlogMapper { int addBook(Blog blog); }
<insert id="addBook" parameterType="Blog"> insert into blog(id,title,author,create_time,views) values(#{id},#{title},#{author},#{create_time},#{views}) </insert>
-
测试
@Test public void test() { SqlSession sqlSession = MybatisUtil.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); Blog blog = new Blog(); blog.setId(IdUtil.getUUid()); blog.setTitle("mybatis学习"); blog.setAuthor("LEEZ"); blog.setCreate_time(new Date()); blog.setViews(9999); mapper.addBook(blog); blog.setId(IdUtil.getUUid()); blog.setTitle("javaweb学习"); mapper.addBook(blog); blog.setId(IdUtil.getUUid()); blog.setTitle("javase学习"); mapper.addBook(blog); blog.setId(IdUtil.getUUid()); blog.setTitle("mysql学习"); mapper.addBook(blog); sqlSession.close(); }
12.2 IF#
<select id="queryBlogByIf" parameterType="map" resultType="Blog">
select * from blog
<where>
<if test="title != null">
title like "%"#{title}"%"
</if>
<if test="author != null">
and author like "%"#{author}"%"
</if>
</where>
</select>
12.3 choose、when、otherwise#
<select id="queryBlogByChoose" parameterType="map" resultType="Blog">
select * from blog
<where>
<choose>
<when test="title != null">
title like "%"#{title}"%"
</when>
<when test="author != null">
author like "%"#{author}"%"
</when>
<otherwise>
views = #{views}
</otherwise>
</choose>
</where>
</select>
12.4 trim、where、set#
where:where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
<select id="queryBlogIF" parameterType="map" resultType="blog">
select *from mybatis.blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
set:set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author},
</if>
</set>
where id = #{id}
</update>
trim:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容
这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
或者,你可以通过使用trim元素来达到同样的效果:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
注意,我们覆盖了后缀值设置,并且自定义了前缀值
所谓动态SQL,本质还是SQL语句,只是我们可以在SQL层面去执行一个逻辑代码
12.5 SQL片段#
有的时候,我们可能会将一些功能的部分抽取出来,方便复用
-
使用sql标签抽取公共部分
<sql id="if-title-author"> <if test="title != null"> title = #{title}, </if> <if test="author != null"> author = #{author}, </if> </sql>
-
在需要使用的地方使用include标签引用即可
<update id="updateBlog" parameterType="map"> update blog <set> <include refid="if-title-author"></include> </set> where id = #{id} </update>
注意事项:
- 最好基于单表来定义sql片段
- 不要在1中存在where标签
12.6 foreach#
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
<where>
<foreach item="item" index="index" collection="list"
open="ID in (" separator="," close=")" nullable="true">
#{item}
</foreach>
</where>
</select>
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
具体实现:
<select id="queryBlogin123" resultType="Blog">
select * from blog
<where>
<foreach collection="list" item="ids"
open="id in (" separator="," close=")">
#{ids}
</foreach>
</where>
</select>
@Test
public void testForEach() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
ArrayList ids = new ArrayList();
ids.add("1");
ids.add("2");
ids.add("3");
List<Blog> blogs = mapper.queryBlogin123(ids);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
小结:
动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了
建议:
- 先在Mysql中写出完整的SQL再对应去修改成为我们的动态SQL实现通用即可
- Mysql重点掌握的知识
- Mysql引擎
- InnoDB底层原理
- 索引
- 索引优化
13. 缓存#
13.1 简介#
13.1.1 什么是缓存【Cache】#
- 存在内存中的临时数据
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用了从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题
13.1.2 为什么使用缓存?#
- 减少和数据库的交互次数,较少系统开销,提高系统效率
13.1.3 什么样的数据能使用缓存?#
- 经常查询而且不经常改变的数据
13.2 Mybatis缓存#
-
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
-
MyBatis系统中默认定义了两级缓存:
一级缓存
和
二级缓存
- 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
- 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
13.3 一级缓存#
- 一级缓存也叫本地缓存:
- 与数据库同一次会话期间查询到的数据会放在本地缓存中。
- 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
测试步骤
-
开启日志
-
测试在Session中查询两次相同的记录
@Test public void test() { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user1 = mapper.getUserById(1); System.out.println(user1); System.out.println("==========================="); User user2 = mapper.getUserById(1); System.out.println(user2); System.out.println("user1 == user2? ---> "+ (user1 == user2)); sqlSession.close(); }
-
查看日志输出
- 虽然调用了两次mapper.getUserById(),但sql语句只执行了一次,并且两次得到的对象是同一个对象。说明查询一次之后得到的结果放进了缓存中,第二次查询时,直接从缓存中提取结果,因此两次的对象是同一个。
- 缓存失效
- 查询不同的东西
- 增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
- 查询不同的Mapper.xml
- 手动清理缓存!
小结:一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段(相当于一个用户不断查询相同的数据,比如不断刷新),一级缓存就是一个map
13.4、二级缓存#
- 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
- 基于namespace级别的缓存,一个名称空间,对应一个二级缓存:
- 工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中:
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容:
- 不同的mapper查出的数据会放在自己对应的缓存(map)中;
步骤
-
核心配置文件中开启全局缓存(settings)
<!--显式的开启全局缓存--> <setting name="cacheEnable" value="true"/>
-
在要使用二级缓存的Mapper中开启
-
可以不加参数
<cache/>
-
也可以自定义参数
<!--在当前Mapper.xml中使用二级缓存--> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
-
-
测试
@Test public void test() { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user1 = mapper.getUserById(1); System.out.println(user1); System.out.println("==========================="); sqlSession.close(); SqlSession sqlSession2 = MybatisUtil.getSqlSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = mapper2.getUserById(1); System.out.println(user2); System.out.println("user1 == user2? ---> "+ (user1 == user2)); sqlSession2.close(); }
-
结果
- 可以看到只执行了一次sql,第二次查询时直接从二级缓存中得到查询结果,但两次结果的对象不一致,原因是:返回的是一个缓存对象的拷贝,一级缓存内容存到了二级缓存中所以内存地址变化,对比为false。序列化是深拷贝,所以反序列化后的对像和原对象不是同一个对象,故哈希值不同
问题:
-
我们需要将实体类序列化(实现Serializable接口),否则就会报错
Cause: java.io.NotSerializableException: com.LEEZ.pojo.User
小结
-
只要开启了二级缓存,在同一个Mapper下就有效
-
所有的数据都会先放在一级缓存中
-
只有当会话提交,或者关闭的时候才会提交到二级缓存中
13.5 缓存原理#
缓存顺序:
- 先看二级缓存中有没有
- 再看一级缓存中有没有
- 查询数据库
注:一二级缓存都没有,查询数据库,查询后将数据放入一级缓存
13.6 自定义缓存—ehcache#
介绍:
- EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider
- Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存
要在程序中使用ehcache,先要导包
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
12345
在mapper中指定使用我们的ehcache缓存实现
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
1
这部分关于缓存的内容了解就可以,以后开发我们会用Redis数据库来做缓存!
14. 练习:29到练习题实战!#
14.1 环境搭建#
-
实体类
-
Bill
@Data public class Bill { private Integer id; //id private String billCode; //账单编码 private String productName; //商品名称 private String productDesc; //商品描述 private String productUnit; //商品单位 private BigDecimal productCount; //商品数量 private BigDecimal totalPrice; //商品总额 private Integer isPayment; //是否支付(1:未支付 2:已支付) private Integer createdBy; //创建者(userId) private Date creationDate; //创建时间 private Integer modifyBy; //更新者(userId) private Date modifyDate; //更新时间 private Integer providerId; //供应商ID private String providerName; //供应商名称 }
-
Provider
@Data public class Provider { private Integer id; //id private String proCode; //供应商编码 private String proName; //供应商名称 private String proDesc; //供应商详细描述 private String proContact; //供应商联系人 private String proPhone; //联系电话 private String proAddress; //地址 private String proFax; //传真 private Integer createdBy; //创建者(userId) private Date creationDate; //创建时间 private Date modifyDate; //更新时间 private Integer modifyBy; //更新者(userId) }
-
Role
@Data public class Role { private Integer id; //id private String roleCode; //角色编码 private String roleName; //角色名称 private Integer createdBy; //创建者 private Date creationDate; //创建时间 private Integer modifyBy; //修改者 private Date modifyDate; //修改时间 }
-
User
public class User { private Integer id; //id private String userCode; //用户编码 private String userName; //用户名称 private String userPassword; //用户密码 private Integer gender; //性别(1:女、 2:男) private Date birthday; //出生日期 private String phone; //手机 private String address; //地址 private Integer userRole; //用户角色(取自角色表-角色id) private Integer createdBy; //创建者(userId) private Date creationDate; //创建时间 private Integer modifyBy; //更新者(userId) private Date modifyDate; //更新时间 private Integer age; //年龄 private String userRoleName; //用户角色名称 public User(String userCode, String userName, String userPassword, Integer gender, Date birthday, String phone, String address, Integer userRole, Integer createdBy, Date creationDate) { this.userCode = userCode; this.userName = userName; this.userPassword = userPassword; this.gender = gender; this.birthday = birthday; this.phone = phone; this.address = address; this.userRole = userRole; this.createdBy = createdBy; this.creationDate = creationDate; } public User() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getUserRole() { return userRole; } public void setUserRole(Integer userRole) { this.userRole = userRole; } public Integer getCreatedBy() { return createdBy; } public void setCreatedBy(Integer createdBy) { this.createdBy = createdBy; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public Integer getModifyBy() { return modifyBy; } public void setModifyBy(Integer modifyBy) { this.modifyBy = modifyBy; } public Date getModifyDate() { return modifyDate; } public void setModifyDate(Date modifyDate) { this.modifyDate = modifyDate; } public String getUserRoleName() { return userRoleName; } public void setUserRoleName(String userRoleName) { this.userRoleName = userRoleName; } public Integer getAge() { return this.age; } public User(Integer id, String userName, Integer gender, Date birthday, String phone, String address, Integer userRole, Integer modifyBy, Date modifyDate) { this.id = id; this.userName = userName; this.gender = gender; this.birthday = birthday; this.phone = phone; this.address = address; this.userRole = userRole; this.modifyBy = modifyBy; this.modifyDate = modifyDate; } public void setAge() { Date date = new Date(); this.age = date.getYear() - birthday.getYear(); } }
-
-
Dao接口
-
BillMapper
public interface BillMapper { //根据供应商ID查询订单数量 public int getBillCountByProviderId(@Param("providerId") Integer providerId) throws Exception; //增加订单 public int add(Bill bill) throws Exception; //通过查询条件获取供应商列表-getBillList public List<Bill> getBillList(@Param("productName") String productName, @Param("providerId") Integer providerId, @Param("isPayment") Integer isPayment, @Param("from") Integer currentPageNo, @Param("pageSize") Integer pageSize) throws Exception; //通过条件查询-订单表记录数 public int getBillCount(@Param("productName") String productName, @Param("providerId") Integer providerId, @Param("isPayment") Integer isPayment) throws Exception; //通过delId删除Bill public int deleteBillById(@Param("id") Integer delId) throws Exception; //通过billId获取Bill public Bill getBillById(@Param("id") Integer id) throws Exception; //修改订单信息 public int modify(Bill bill) throws Exception; //根据供应商ID删除订单信息 public int deleteBillByProviderId(@Param("providerId") Integer providerId) throws Exception; }
-
ProviderMapper
public interface ProviderMapper { //增加用户信息 public int add(Provider provider) throws Exception; //通过条件查询-providerList public List<Provider> getProviderList(@Param("proName") String proName, @Param("proCode") String proCode, @Param("from") Integer currentPageNo, @Param("pageSize") Integer pageSize) throws Exception; //获取供应商列表 public List<Provider> getProList() throws Exception; //通过条件查询-供应商表记录数 public int getProviderCount(@Param("proName") String proName, @Param("proCode") String proCode) throws Exception; //通过供应商id删除供应商信息 public int deleteProviderById(@Param("id") Integer delId) throws Exception; //根据provider id 获取供应商信息 public Provider getProviderById(@Param("id") Integer id) throws Exception; //修改供应商 public int modify(Provider provider) throws Exception; }
-
RoleMapper
public interface RoleMapper { //获取角色列表 public List<Role> getRoleList() throws Exception; //增加角色信息 public int add(Role role) throws Exception; //通过Id删除role public int deleteRoleById(@Param("id") Integer delId) throws Exception; //修改角色信息 public int modify(Role role) throws Exception; //通过id获取role public Role getRoleById(@Param("id") Integer id) throws Exception; //根据roleCode,进行角色编码的唯一性验证 public int roleCodeIsExist(@Param("roleCode") String roleCode) throws Exception; }
-
UserMapper
public interface UserMapper { //通过userCode获取User public User getLoginUser(@Param("userCode") String userCode) throws Exception; //增加用户信息 public int add(User user) throws Exception; //通过条件查询-userList public List<User> getUserList(@Param("userName") String userName, @Param("userRole") Integer userRole, @Param("from") Integer currentPageNo, @Param("pageSize") Integer pageSize) throws Exception; //通过条件查询-用户表记录数 public int getUserCount(@Param("userName") String userName, @Param("userRole") Integer userRole) throws Exception; //通过userId删除user public int deleteUserById(@Param("id") Integer delId) throws Exception; //通过userId获取user public User getUserById(@Param("id") Integer id) throws Exception; //修改用户信息 public int modify(User user) throws Exception; //修改当前用户密码 public int updatePwd(@Param("id") Integer id, @Param("userPassword") String pwd) throws Exception; }
-
-
Mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <!--configuration核心配置文件--> <configuration> <!--引入外部配置文件--> <properties resource="db.properties"/> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> <setting name="cacheEnabled" value="true"/> </settings> <!--可以给实体类起别名--> <typeAliases> <typeAlias type="com.LEEZ.pojo.User" alias="User"/> <typeAlias type="com.LEEZ.pojo.Role" alias="Role"/> <typeAlias type="com.LEEZ.pojo.Provider" alias="Provider"/> <typeAlias type="com.LEEZ.pojo.Bill" alias="Bill"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <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> <mappers> <mapper class="com.LEEZ.dao.UserMapper"/> <mapper class="com.LEEZ.dao.ProviderMapper"/> <mapper class="com.LEEZ.dao.RoleMapper"/> <mapper class="com.LEEZ.dao.BillMapper"/> </mappers> </configuration>
-
db.properties
driver = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/smbms?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT username = root password =
-
smbms数据库初始化
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for smbms_address -- ---------------------------- DROP TABLE IF EXISTS `smbms_address`; CREATE TABLE `smbms_address` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `contact` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系人姓名', `addressDesc` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '收货地址明细', `postCode` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '邮编', `tel` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系人电话', `createdBy` bigint(20) DEFAULT NULL COMMENT '创建者', `creationDate` datetime DEFAULT NULL COMMENT '创建时间', `modifyBy` bigint(20) DEFAULT NULL COMMENT '修改者', `modifyDate` datetime DEFAULT NULL COMMENT '修改时间', `userId` bigint(20) DEFAULT NULL COMMENT '用户ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of smbms_address -- ---------------------------- INSERT INTO `smbms_address` VALUES ('1', '王丽', '北京市东城区东交民巷44号', '100010', '13678789999', '1', '2016-04-13 00:00:00', null, null, '1'); INSERT INTO `smbms_address` VALUES ('2', '张红丽', '北京市海淀区丹棱街3号', '100000', '18567672312', '1', '2016-04-13 00:00:00', null, null, '1'); INSERT INTO `smbms_address` VALUES ('3', '任志强', '北京市东城区美术馆后街23号', '100021', '13387906742', '1', '2016-04-13 00:00:00', null, null, '1'); INSERT INTO `smbms_address` VALUES ('4', '曹颖', '北京市朝阳区朝阳门南大街14号', '100053', '13568902323', '1', '2016-04-13 00:00:00', null, null, '2'); INSERT INTO `smbms_address` VALUES ('5', '李慧', '北京市西城区三里河路南三巷3号', '100032', '18032356666', '1', '2016-04-13 00:00:00', null, null, '3'); INSERT INTO `smbms_address` VALUES ('6', '王国强', '北京市顺义区高丽营镇金马工业区18号', '100061', '13787882222', '1', '2016-04-13 00:00:00', null, null, '3'); -- ---------------------------- -- Table structure for smbms_bill -- ---------------------------- DROP TABLE IF EXISTS `smbms_bill`; CREATE TABLE `smbms_bill` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `billCode` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '账单编码', `productName` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品名称', `productDesc` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品描述', `productUnit` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品单位', `productCount` decimal(20,2) DEFAULT NULL COMMENT '商品数量', `totalPrice` decimal(20,2) DEFAULT NULL COMMENT '商品总额', `isPayment` int(10) DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)', `createdBy` bigint(20) DEFAULT NULL COMMENT '创建者(userId)', `creationDate` datetime DEFAULT NULL COMMENT '创建时间', `modifyBy` bigint(20) DEFAULT NULL COMMENT '更新者(userId)', `modifyDate` datetime DEFAULT NULL COMMENT '更新时间', `providerId` int(20) DEFAULT NULL COMMENT '供应商ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of smbms_bill -- ---------------------------- INSERT INTO `smbms_bill` VALUES ('1', 'BILL2016_001', '洗发水、护发素', '日用品-洗发、护发', '瓶', '500.00', '25000.00', '2', '1', '2014-12-14 13:02:03', '15', '2019-04-16 21:43:12', '13'); INSERT INTO `smbms_bill` VALUES ('2', 'BILL2016_002', '香皂、肥皂、药皂', '日用品-皂类', '块', '1000.00', '10000.00', '2', '1', '2016-03-23 04:20:40', null, null, '13'); INSERT INTO `smbms_bill` VALUES ('3', 'BILL2016_003', '大豆油', '食品-食用油', '斤', '300.00', '5890.00', '2', '1', '2014-12-14 13:02:03', null, null, '6'); INSERT INTO `smbms_bill` VALUES ('4', 'BILL2016_004', '橄榄油', '食品-进口食用油', '斤', '200.00', '9800.00', '2', '1', '2013-10-10 03:12:13', null, null, '7'); INSERT INTO `smbms_bill` VALUES ('5', 'BILL2016_005', '洗洁精', '日用品-厨房清洁', '瓶', '500.00', '7000.00', '2', '1', '2014-12-14 13:02:03', null, null, '9'); INSERT INTO `smbms_bill` VALUES ('6', 'BILL2016_006', '美国大杏仁', '食品-坚果', '袋', '300.00', '5000.00', '2', '1', '2016-04-14 06:08:09', null, null, '4'); INSERT INTO `smbms_bill` VALUES ('7', 'BILL2016_007', '沐浴液、精油', '日用品-沐浴类', '瓶', '500.00', '23000.00', '1', '1', '2016-07-22 10:10:22', null, null, '14'); INSERT INTO `smbms_bill` VALUES ('8', 'BILL2016_008', '不锈钢盘碗', '日用品-厨房用具', '个', '600.00', '6000.00', '2', '1', '2016-04-14 05:12:13', null, null, '14'); INSERT INTO `smbms_bill` VALUES ('9', 'BILL2016_009', '塑料杯', '日用品-杯子', '个', '350.00', '1750.00', '2', '1', '2016-02-04 11:40:20', null, null, '14'); INSERT INTO `smbms_bill` VALUES ('10', 'BILL2016_010', '豆瓣酱', '食品-调料', '瓶', '200.00', '2000.00', '2', '1', '2013-10-29 05:07:03', null, null, '8'); INSERT INTO `smbms_bill` VALUES ('11', 'BILL2016_011', '海之蓝', '饮料-国酒', '瓶', '50.00', '10000.00', '1', '1', '2016-04-14 16:16:00', null, null, '1'); INSERT INTO `smbms_bill` VALUES ('12', 'BILL2016_012', '芝华士', '饮料-洋酒', '瓶', '20.00', '6000.00', '1', '1', '2016-09-09 17:00:00', null, null, '1'); INSERT INTO `smbms_bill` VALUES ('13', 'BILL2016_013', '长城红葡萄酒', '饮料-红酒', '瓶', '60.00', '800.00', '2', '1', '2016-11-14 15:23:00', null, null, '1'); INSERT INTO `smbms_bill` VALUES ('14', 'BILL2016_014', '泰国香米', '食品-大米', '斤', '400.00', '5000.00', '2', '1', '2016-10-09 15:20:00', null, null, '3'); INSERT INTO `smbms_bill` VALUES ('15', 'BILL2016_015', '东北大米', '食品-大米', '斤', '600.00', '4000.00', '2', '1', '2016-11-14 14:00:00', null, null, '3'); INSERT INTO `smbms_bill` VALUES ('16', 'BILL2016_016', '可口可乐', '饮料', '瓶', '2000.00', '6000.00', '2', '1', '2012-03-27 13:03:01', null, null, '2'); INSERT INTO `smbms_bill` VALUES ('17', 'BILL2016_017', '脉动', '饮料', '瓶', '1500.00', '4500.00', '2', '1', '2016-05-10 12:00:00', null, null, '2'); -- ---------------------------- -- Table structure for smbms_provider -- ---------------------------- DROP TABLE IF EXISTS `smbms_provider`; CREATE TABLE `smbms_provider` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `proCode` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商编码', `proName` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商名称', `proDesc` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商详细描述', `proContact` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商联系人', `proPhone` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系电话', `proAddress` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '地址', `proFax` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '传真', `createdBy` bigint(20) DEFAULT NULL COMMENT '创建者(userId)', `creationDate` datetime DEFAULT NULL COMMENT '创建时间', `modifyDate` datetime DEFAULT NULL COMMENT '更新时间', `modifyBy` bigint(20) DEFAULT NULL COMMENT '更新者(userId)', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of smbms_provider -- ---------------------------- INSERT INTO `smbms_provider` VALUES ('1', 'BJ_GYS001', '北京三木堂商贸有限公司', '长期合作伙伴,主营产品:茅台、五粮液、郎酒、酒鬼酒、泸州老窖、赖茅酒、法国红酒等', '张国强', '13566669999', '北京市丰台区育芳园北路', '010-58858787', '1', '2013-03-21 16:52:07', '2019-04-12 16:44:03', '10'); INSERT INTO `smbms_provider` VALUES ('2', 'HB_GYS001', '石家庄帅益食品贸易有限公司', '长期合作伙伴,主营产品:饮料、水饮料、植物蛋白饮料、休闲食品、果汁饮料、功能饮料等', '王军', '13309094212', '河北省石家庄新华区', '0311-67738876', '1', '2016-04-13 04:20:40', null, null); INSERT INTO `smbms_provider` VALUES ('3', 'GZ_GYS001', '深圳市泰香米业有限公司', '初次合作伙伴,主营产品:良记金轮米,龙轮香米等', '郑程瀚', '13402013312', '广东省深圳市福田区深南大道6006华丰大厦', '0755-67776212', '1', '2014-03-21 16:56:07', null, null); INSERT INTO `smbms_provider` VALUES ('4', 'GZ_GYS002', '深圳市喜来客商贸有限公司', '长期合作伙伴,主营产品:坚果炒货.果脯蜜饯.天然花茶.营养豆豆.特色美食.进口食品.海味零食.肉脯肉', '林妮', '18599897645', '广东省深圳市福龙工业区B2栋3楼西', '0755-67772341', '1', '2013-03-22 16:52:07', null, null); INSERT INTO `smbms_provider` VALUES ('5', 'JS_GYS001', '兴化佳美调味品厂', '长期合作伙伴,主营产品:天然香辛料、鸡精、复合调味料', '徐国洋', '13754444221', '江苏省兴化市林湖工业区', '0523-21299098', '1', '2015-11-22 16:52:07', null, null); INSERT INTO `smbms_provider` VALUES ('6', 'BJ_GYS002', '北京纳福尔食用油有限公司', '长期合作伙伴,主营产品:山茶油、大豆油、花生油、橄榄油等', '马莺', '13422235678', '北京市朝阳区珠江帝景1号楼', '010-588634233', '1', '2012-03-21 17:52:07', null, null); INSERT INTO `smbms_provider` VALUES ('7', 'BJ_GYS003', '北京国粮食用油有限公司', '初次合作伙伴,主营产品:花生油、大豆油、小磨油等', '王驰', '13344441135', '北京大兴青云店开发区', '010-588134111', '1', '2016-04-13 00:00:00', null, null); INSERT INTO `smbms_provider` VALUES ('8', 'ZJ_GYS001', '慈溪市广和绿色食品厂', '长期合作伙伴,主营产品:豆瓣酱、黄豆酱、甜面酱,辣椒,大蒜等农产品', '薛圣丹', '18099953223', '浙江省宁波市慈溪周巷小安村', '0574-34449090', '1', '2013-11-21 06:02:07', null, null); INSERT INTO `smbms_provider` VALUES ('9', 'GX_GYS001', '优百商贸有限公司', '长期合作伙伴,主营产品:日化产品', '李立国', '13323566543', '广西南宁市秀厢大道42-1号', '0771-98861134', '1', '2013-03-21 19:52:07', null, null); INSERT INTO `smbms_provider` VALUES ('10', 'JS_GYS002', '南京火头军信息技术有限公司', '长期合作伙伴,主营产品:不锈钢厨具等', '陈女士', '13098992113', '江苏省南京市浦口区浦口大道1号新城总部大厦A座903室', '025-86223345', '1', '2013-03-25 16:52:07', null, null); INSERT INTO `smbms_provider` VALUES ('11', 'GZ_GYS003', '广州市白云区美星五金制品厂', '长期合作伙伴,主营产品:海绵床垫、坐垫、靠垫、海绵枕头、头枕等', '梁天', '13562276775', '广州市白云区钟落潭镇福龙路20号', '020-85542231', '1', '2016-12-21 06:12:17', null, null); INSERT INTO `smbms_provider` VALUES ('12', 'BJ_GYS004', '北京隆盛日化科技', '长期合作伙伴,主营产品:日化环保清洗剂,家居洗涤专卖、洗涤用品网、墙体除霉剂、墙面霉菌清除剂等', '孙欣', '13689865678', '北京市大兴区旧宫', '010-35576786', '1', '2014-11-21 12:51:11', null, null); INSERT INTO `smbms_provider` VALUES ('13', 'SD_GYS001', '山东豪克华光联合发展有限公司', '长期合作伙伴,主营产品:洗衣皂、洗衣粉、洗衣液、洗洁精、消杀类、香皂等', '吴洪转', '13245468787', '山东济阳济北工业区仁和街21号', '0531-53362445', '1', '2015-01-28 10:52:07', null, null); -- ---------------------------- -- Table structure for smbms_role -- ---------------------------- DROP TABLE IF EXISTS `smbms_role`; CREATE TABLE `smbms_role` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `roleCode` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色编码', `roleName` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色名称', `createdBy` bigint(20) DEFAULT NULL COMMENT '创建者', `creationDate` datetime DEFAULT NULL COMMENT '创建时间', `modifyBy` bigint(20) DEFAULT NULL COMMENT '修改者', `modifyDate` datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of smbms_role -- ---------------------------- INSERT INTO `smbms_role` VALUES ('1', 'SMBMS_ADMIN', '系统管理员', '1', '2016-04-13 00:00:00', null, null); INSERT INTO `smbms_role` VALUES ('2', 'SMBMS_MANAGER', '经理', '1', '2016-04-13 00:00:00', null, null); INSERT INTO `smbms_role` VALUES ('3', 'SMBMS_EMPLOYEE', '普通员工', '1', '2016-04-13 00:00:00', null, null); -- ---------------------------- -- Table structure for smbms_user -- ---------------------------- DROP TABLE IF EXISTS `smbms_user`; CREATE TABLE `smbms_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `userCode` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户编码', `userName` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户名称', `userPassword` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户密码', `gender` int(10) DEFAULT NULL COMMENT '性别(1:女、 2:男)', `birthday` date DEFAULT NULL COMMENT '出生日期', `phone` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '手机', `address` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '地址', `userRole` int(10) DEFAULT NULL COMMENT '用户角色(取自角色表-角色id)', `createdBy` bigint(20) DEFAULT NULL COMMENT '创建者(userId)', `creationDate` datetime DEFAULT NULL COMMENT '创建时间', `modifyBy` bigint(20) DEFAULT NULL COMMENT '更新者(userId)', `modifyDate` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of smbms_user -- ---------------------------- INSERT INTO `smbms_user` VALUES ('1', 'wen', '系统管理员', '123', '1', '1997-01-01', '15200981234', '湖南省衡阳市蒸湘区南华大学', '1', '1', '2019-04-07 10:15:55', null, null); INSERT INTO `smbms_user` VALUES ('5', 'hanlubiao', '韩路彪', '0000000', '2', '1984-06-05', '18567542321', '北京市朝阳区北辰中心12号', '2', '1', '2014-12-31 19:52:09', null, null); INSERT INTO `smbms_user` VALUES ('6', 'zhanghua', '张华', '0000000', '1', '1983-06-15', '13544561111', '北京市海淀区学院路61号', '3', '1', '2013-02-11 10:51:17', null, null); INSERT INTO `smbms_user` VALUES ('7', 'wangyang', '王洋', '0000000', '2', '1982-12-31', '13444561124', '北京市海淀区西二旗辉煌国际16层', '3', '1', '2014-06-11 19:09:07', null, null); INSERT INTO `smbms_user` VALUES ('8', 'zhaoyan', '赵燕', '0000000', '1', '1986-03-07', '18098764545', '北京市海淀区回龙观小区10号楼', '3', '1', '2016-04-21 13:54:07', null, null); INSERT INTO `smbms_user` VALUES ('10', 'sunlei', '孙磊', '0000000', '2', '1981-01-04', '13387676765', '北京市朝阳区管庄新月小区12楼', '3', '1', '2015-05-06 10:52:07', null, null); INSERT INTO `smbms_user` VALUES ('11', 'sunxing', '孙兴', '0000000', '2', '1978-03-12', '13367890900', '北京市朝阳区建国门南大街10号', '3', '1', '2016-11-09 16:51:17', null, null); INSERT INTO `smbms_user` VALUES ('12', 'zhangchen', '张晨', '0000000', '1', '1986-03-28', '18098765434', '朝阳区管庄路口北柏林爱乐三期13号楼', '3', '1', '2016-08-09 05:52:37', '1', '2016-04-14 14:15:36'); INSERT INTO `smbms_user` VALUES ('13', 'dengchao', '邓超', '0000000', '2', '1981-11-04', '13689674534', '北京市海淀区北航家属院10号楼', '3', '1', '2016-07-11 08:02:47', null, null); INSERT INTO `smbms_user` VALUES ('14', 'yangguo', '杨过', '0000000', '2', '1980-01-01', '13388886623', '北京市朝阳区北苑家园茉莉园20号楼', '3', '1', '2015-02-01 03:52:07', null, null); INSERT INTO `smbms_user` VALUES ('15', 'test', 'test', '111', '1', '2019-04-16', '123456789', '南华大学', '1', '1', '2019-04-16 19:52:37', null, null);
14.2 UserMapper.xml(8道题)#
-
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.LEEZ.dao.UserMapper"> <select id="getLoginUser" resultType="User"> select * from smbms_user <where> <if test="userCode != null"> userCode = #{userCode} </if> </where> </select> <insert id="add" parameterType="User"> insert into smbms_user(id,userCode,userName,userPassword,gender,birthday,phone,address,userRole) values(#{id},#{userCode},#{userName},#{userPassword},#{gender},#{birthday},#{phone},#{address},#{userRole}) </insert> <!--将多次重复的sql语句提取出来--> <sql id="if-userName-userRole"> <if test="userName != null"> userName like "%"#{userName}"%" </if> <if test="userRole != null"> and userRole = #{userRole} </if> </sql> <select id="getUserList" resultType="User"> select u.*,r.roleName from smbms_user u,smbms_role r <where> u.userRole = r.id <include refid="if-userName-userRole"/> </where> limit #{from},#{pageSize} </select> <select id="getUserCount" resultType="int"> select count(1) from smbms_user <where> <include refid="if-userName-userRole"/> </where> </select> <!--将多次重复的sql语句提取出来--> <sql id="if-id"> <if test="id != null"> id = #{id} </if> </sql> <delete id="deleteUserById" parameterType="int"> delete from smbms_user <where> <include refid="if-id"/> </where> </delete> <select id="getUserById" resultType="User"> select * from smbms_user <where> <include refid="if-id"/> </where> </select> <update id="modify" parameterType="User"> update smbms_user <set> <if test="userCode != null"> userCode = #{userCode}, </if> <if test="userName != null"> userName = #{userName}, </if> <if test="userPassword != null"> userPassword = #{userPassword}, </if> <if test="gender != null"> gender = #{gender}, </if> <if test="birthday != null"> birthday = #{birthday}, </if> <if test="phone != null"> phone = #{phone}, </if> <if test="address != null"> address = #{address}, </if> <if test="userRole != null"> userRole = #{userRole} </if> </set> <where> <include refid="if-id"/> </where> </update> <update id="updatePwd"> update smbms_user <set> <if test="userPassword != null"> userPassword = #{userPassword} </if> </set> <where> <include refid="if-id"/> </where> </update> </mapper>
-
测试
-
@Test public void testGetLoginUser() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User admin = mapper.getLoginUser("admin"); System.out.println(admin); sqlSession.close(); }
-
@Test public void testAdd() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int add = mapper.add(new User(27, "LEEZ", "CV攻城狮", "111111", 1, new Date(), "13411111111", "清华大学", 1)); sqlSession.close(); }
-
@Test public void testGetUserList() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.getUserList("张", 3, 0, 5); for (User user : userList) { System.out.println(user); } sqlSession.close(); }
-
@Test public void testGetUserCount() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int userCount = mapper.getUserCount("张", 3); System.out.println(userCount); sqlSession.close(); }
-
@Test public void testDeleteUserById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int i = mapper.deleteUserById(27); System.out.println(i); sqlSession.close(); }
-
@Test public void testGetUserById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User userById = mapper.getUserById(1); System.out.println(userById); sqlSession.close(); }
-
@Test public void testModify() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int modify = mapper.modify(new User(26, "LEEZ", "CV攻城狮", "111111", 1, new Date(), "13411111111", "清华大学", 1)); System.out.println(modify); sqlSession.close(); }
-
@Test public void testUpdatePwd() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int updatePwd = mapper.updatePwd(26, "222222"); System.out.println(updatePwd); sqlSession.close(); }
-
-
结果
14.3 RoleMapper.xml(6道题)#
-
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.LEEZ.dao.RoleMapper"> <select id="getRoleList" resultType="Role"> select * from smbms_role </select> <insert id="add" parameterType="Role"> insert into smbms_role(id,roleCode,roleName,createdBy,creationDate,modifyBy,modifyDate) values(#{id},#{roleCode},#{roleName},#{createdBy},#{creationDate},#{modifyBy},#{modifyDate}) </insert> <!--多次使用到的sql片段提取出来,方便复用--> <sql id="if-id"> <if test="id != null"> id = #{id} </if> </sql> <delete id="deleteRoleById"> delete from smbms_role <where> <include refid="if-id"/> </where> </delete> <update id="modify"> update smbms_role <set> <if test="roleCode != null"> roleCode = #{roleCode}, </if> <if test="roleName != null"> roleName = #{roleName}, </if> <if test="createdBy != null"> createdBy = #{createdBy}, </if> <if test="creationDate != null"> creationDate = #{creationDate}, </if> </set> <where> <include refid="if-id"/> </where> </update> <select id="getRoleById" resultType="Role"> select * from smbms_role <where> <include refid="if-id"/> </where> </select> <select id="roleCodeIsExist" resultType="int"> select count(*) from smbms_role <where> <if test="roleCode != null"> roleCode = #{roleCode} </if> </where> </select> </mapper>
-
测试
-
@Test public void testGetRoleList() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); RoleMapper mapper = sqlSession.getMapper(RoleMapper.class); List<Role> roleList = mapper.getRoleList(); for (Role role : roleList) { System.out.println(role); } sqlSession.close(); }
-
@Test public void testAdd() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); RoleMapper mapper = sqlSession.getMapper(RoleMapper.class); int add = mapper.add(new Role(4, "SMBMS_STUDENT", "实习生", 1, new Date(), null, null)); System.out.println(add); sqlSession.close(); }
-
@Test public void testDeleteRoleById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); RoleMapper mapper = sqlSession.getMapper(RoleMapper.class); int i = mapper.deleteRoleById(4); System.out.println(i); sqlSession.close(); }
-
@Test public void testModify() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); RoleMapper mapper = sqlSession.getMapper(RoleMapper.class); int modify = mapper.modify(new Role(4, "SMBMS_STUDENT", "实习生1", 1, new Date(), null, null)); System.out.println(modify); sqlSession.close(); }
-
@Test public void testGetRoleById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); RoleMapper mapper = sqlSession.getMapper(RoleMapper.class); Role roleById = mapper.getRoleById(4); System.out.println(roleById); sqlSession.close(); }
-
@Test public void testRoleCodeIsExist() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); RoleMapper mapper = sqlSession.getMapper(RoleMapper.class); int i = mapper.roleCodeIsExist("SMBMS_SUPADMIN"); System.out.println(i); sqlSession.close(); }
-
-
结果
14.4 BillMapper.xml(8道题)#
-
BillMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.LEEZ.dao.BillMapper"> <select id="getBillCountByProviderId" resultType="int"> select count(1) from smbms_bill <where> <if test="providerId != null"> providerId = #{providerId} </if> </where> </select> <insert id="add"> insert into smbms_bill(id,billCode,productName,productDesc,productUnit,productCount,totalPrice,isPayment,createdBy,creationDate,providerId) values(#{id},#{billCode},#{productName},#{productDesc},#{productUnit},#{productCount},#{totalPrice},#{isPayment},#{createdBy},#{creationDate},#{providerId}) </insert> <select id="getBillList" resultType="Bill"> select b.*,proName from smbms_bill b,smbms_provider p <where> b.providerId = p.id <if test="productName != null"> and productName like "%"#{productName}"%" </if> <if test="providerId != null"> and providerId = #{providerId} </if> <if test="isPayment != null"> and isPayment = #{isPayment} </if> </where> limit #{from},#{pageSize} </select> <select id="getBillCount" resultType="int"> select count(1) from smbms_bill <where> <if test="productName != null"> productName like "%"#{productName}"%" </if> <if test="providerId != null"> and providerId = #{providerId} </if> <if test="isPayment != null"> and isPayment = #{isPayment} </if> </where> </select> <delete id="deleteBillById"> delete from smbms_bill <where> <include refid="if-id"/> </where> </delete> <select id="getBillById" resultType="Bill"> select * from smbms_bill <where> <include refid="if-id"/> </where> </select> <!--多次使用到的sql片段提取出来,方便复用--> <sql id="if-id"> <if test="id != null"> id = #{id} </if> </sql> <update id="modify"> update smbms_bill <set> <if test="billCode != null"> billCode = #{billCode}, </if> <if test="productName != null"> productName = #{productName}, </if> <if test="productDesc != null"> productDesc = #{productDesc}, </if> <if test="productUnit != null"> productUnit = #{productUnit}, </if> <if test="productCount != null"> productCount = #{productCount}, </if> <if test="totalPrice != null"> totalPrice = #{totalPrice}, </if> <if test="isPayment != null"> isPayment = #{isPayment}, </if> <if test="createdBy != null"> createdBy = #{createdBy}, </if> <if test="creationDate != null"> creationDate = #{creationDate}, </if> <if test="providerId != null"> providerId = #{providerId} </if> </set> <where> <include refid="if-id"/> </where> </update> <delete id="deleteBillByProviderId"> delete from smbms_bill <where> <if test="providerId != null"> providerId = #{providerId} </if> </where> </delete> </mapper>
-
测试
-
@Test public void testGetBillCountByProviderId() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); int billCountByProviderId = mapper.getBillCountByProviderId(13); System.out.println(billCountByProviderId); sqlSession.close(); }
-
@Test public void testAdd() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); int add = mapper.add(new Bill(18, "BILL2022_018", "百事可乐", "饮料", "瓶", new BigDecimal(200.00), new BigDecimal(600.00), 2, 1, new Date(), 15)); System.out.println(add); sqlSession.close(); }
-
@Test public void testGetBillList() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); List<Bill> billList = mapper.getBillList("", 2, 2, 0, 5); for (Bill bill : billList) { System.out.println(bill); } sqlSession.close(); }
-
@Test public void testGetBillCount() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); int count = mapper.getBillCount("可乐", 2, 2); System.out.println(count); sqlSession.close(); }
-
@Test public void testDeleteBillById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); int i = mapper.deleteBillById(18); System.out.println(i); sqlSession.close(); }
-
@Test public void testGetBillById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); Bill billById = mapper.getBillById(17); System.out.println(billById); sqlSession.close(); }
-
@Test public void testModify() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); mapper.modify(new Bill(18, "BILL2022_018", "百事可乐", "饮料", "瓶", new BigDecimal(300.00), new BigDecimal(900.00), 2, 1, new Date(), 15)); sqlSession.close(); }
-
@Test public void testDeleteBillByProviderId() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); BillMapper mapper = sqlSession.getMapper(BillMapper.class); int i = mapper.deleteBillByProviderId(15); System.out.println(i); sqlSession.close(); }
-
-
结果
14.3 ProviderMapper.xml(7道题)#
-
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.LEEZ.dao.ProviderMapper"> <insert id="add"> insert into smbms_provider(id,proCode,proName,proDesc,proContact,proPhone,proAddress,proFax,createdBy,creationDate) values(#{id},#{proCode},#{proName},#{proDesc},#{proContact},#{proPhone},#{proAddress},#{proFax},#{createdBy},#{creationDate}) </insert> <select id="getProviderList" resultType="Provider"> select * from smbms_provider <where> <include refid="if-proName-proCode"/> </where> limit #{from},#{pageSize} </select> <select id="getProList" resultType="Provider"> select * from smbms_provider </select> <!--将多次使用的sql语句提取出来--> <sql id="if-proName-proCode"> <if test="proName != null"> proName like "%"#{proName}"%" </if> <if test="proCode != null"> and proCode like "%"#{proCode}"%" </if> </sql> <select id="getProviderCount" resultType="int"> select count(1) from smbms_provider <where> <include refid="if-proName-proCode"/> </where> </select> <delete id="deleteProviderById"> delete from smbms_provider <where> <include refid="if-id"/> </where> </delete> <!--提取出多次使用的sql语句--> <sql id="if-id"> <if test="id != null"> id = #{id} </if> </sql> <select id="getProviderById" resultType="Provider"> select * from smbms_provider <where> <include refid="if-id"/> </where> </select> <update id="modify"> update smbms_provider <set> <if test="proCode != null"> proCode = #{proCode}, </if> <if test="proName != null"> proName = #{proName}, </if> <if test="proDesc != null"> proDesc = #{proDesc}, </if> <if test="proContact != null"> proContact = #{proContact}, </if> <if test="proPhone != null"> proPhone = #{proPhone}, </if> <if test="proAddress != null"> proAddress = #{proAddress}, </if> <if test="proFax != null"> proFax = #{proFax}, </if> <if test="createdBy != null"> createdBy = #{createdBy}, </if> <if test="creationDate != null"> creationDate = #{creationDate} </if> </set> <where> <include refid="if-id"/> </where> </update> </mapper>
-
测试
-
@Test public void testAdd() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); int add = mapper.add(new Provider(14, "JM_LES009", "江门市云云科技有限公司", "初次合作伙伴", "LEEZ", "13411111111", "江门市蓬江区", "010-11111111", 1, new Date())); System.out.println(add); sqlSession.close(); }
-
@Test public void testGetProviderList() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); List<Provider> providerList = mapper.getProviderList("北京", "00", 0, 5); for (Provider provider : providerList) { System.out.println(provider); } sqlSession.close(); }
-
@Test public void testGetProList() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); List<Provider> proList = mapper.getProList(); for (Provider provider : proList) { System.out.println(proList); } sqlSession.close(); }
-
@Test public void testGetProviderCount() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); int providerCount = mapper.getProviderCount("北京", "00"); System.out.println(providerCount); sqlSession.close(); }
-
@Test public void testDeleteProviderById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); int i = mapper.deleteProviderById(14); System.out.println(i); sqlSession.close(); }
-
@Test public void testGetProviderById() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); Provider providerById = mapper.getProviderById(13); System.out.println(providerById); sqlSession.close(); }
-
@Test public void testModify() throws Exception { SqlSession sqlSession = MybatisUtil.getSqlSession(); ProviderMapper mapper = sqlSession.getMapper(ProviderMapper.class); int modify = mapper.modify(new Provider(14, "JM_LES009", "江门市磊磊科技有限公司", "初次合作伙伴", "LEEZ", "13411111111", "江门市蓬江区", "010-11111111", 1, new Date())); System.out.println(modify); sqlSession.close(); }
-
-
结果
作者:LEEZ
出处:https://www.cnblogs.com/leezStudy/p/16925368.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
声明:转载请注明出处!