概述
log4j
打印程序运行的日志,我们可以通过日志清楚的看到程序底层运行的一些逻辑顺序,类似于debug
- 引入jar包
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j</artifactId> <version>2.13.3</version> </dependency>
- 导入log4j配置文件
- 在Mybatis配置文件中,在全局配置<settings>中开启sql日志功能
<setting name = "logImpl" value = "STDOUT_LOGGING" />
Mybatis
缓存
-
一级缓存Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只是开启了一级缓存(一级缓存是相对于同一个SqlSession而言)在sql和参数完全一致的情况下,使用同一个sqlsession对象调用同一个Mapper的方法,只会执行一次Sql ,因为使用Sqlsession第一次查询后,Mybatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有设置超时时间的情况下,SqlSession都只会读取当前缓存的数据,而不会再次发送sql到数据库
如果不是一个Sqlsession对象,因为不同Sqlsession都是相互隔离的,所以一级缓存失效
测试一级缓存:此时不是同一个Sqlsession,通过log4j日志可以看出,生成了2条sql语句@Test public void findById() throws IOException { //通过流,将核心配置文件读取出来 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //通过核心配置文件创建会话工厂 SqlSessionFactory factor = new SqlSessionFactoryBuilder().build(inputStream); //通过会话工厂创建会话 SqlSession sqlSession = factor.openSession(); User user = sqlSession.selectOne("test.findById",8); SqlSession sqlSession2 = factor.openSession(); User user1 = sqlSession2.selectOne("test.findById",8); System.out.println(user==user1); // false }
此时,是同一个 Sqlsession, 只生成了一条 sql 语句@Test public void findById() throws IOException { //通过流,将核心配置文件读取出来 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //通过核心配置文件创建会话工厂 SqlSessionFactory factor = new SqlSessionFactoryBuilder().build(inputStream); //通过会话工厂创建会话 SqlSession sqlSession = factor.openSession(); User user = sqlSession.selectOne("test.findById",8); User user1 = sqlSession.selectOne("test.findById",8); System.out.println(user==user1); }
一级缓存声明周期,什么时候缓存失效:mybatis开启一个数据库会话时,会创建一个新的Sqlsession对象,Sqlsession对象中有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache缓存对象,当会话结束时,Sqlsession对象及其内部所有一并释放,缓存也就清空调用sqlsession.close()调用了sqlSession.clearCache() 在sqlsession中执行了任何一个update操作(update,delete,insert)都会清空缓存 spring整合mybatis后,spring默认继承的不是 DefaultSqlSession,而是SqlSessionTemplate,spring默认每次调用一次方法后,都会执行sqlsession.close(),也就是spring整合Mybatis后一级缓存失效 -
二级缓存Mybatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用性能Mybatis的二级缓存是指mapper映射文件,二级缓存的作用域是同一个namespace下mapper映射文件的内容,多个sqlsession共享二级缓存默认是不开启的,如果想开启二级缓存,需要进行配置实现二级缓存的时候,Mybatis要求返回的POJO必须是可序列化的,实现序列化接口配置方法很简单,只需要在映射xml(mapper.xml中)文件配置开启缓存即可映射语句文件中所有select语句会被缓存映射语句文件中所有insert,updatte,delete都会刷新清空缓存缓存会使用默认的 Least Recently Used(LRU,最近最少使用的)算法来回收实体类实现序列化接口 - 由于二级缓存不一定都是存储到内存中,也可以存储到外部,所以需要加序列化
public class User implements Serializable 在映射文件中开启二级缓存 (mapper.xml 中 )<mapper namespace = "com.zb.mapper.UserMapper" ><!--eviction :代表混村回收策略 LRU- 最近最少使用 FIFO- 先进先出flushInterval :刷新缓存间隔时间 单位是毫秒readOnly :只读,缓存只能读取不能被修改size :表示缓存可以存储多少各对象,不宜过大,过大可能导致内存溢出--><cache eviction = "LRU" flushInterval = "100000" readOnly = "true" size = "1024" ></cache>在 mybatis 全局设置中,开启二级缓存<settings><!-- 开启二级缓存 --><setting name = "cacheEnabled" value = "true" ></setting></settings>测试 此时 Spring 整合 Mybatis 由于开启了二级缓存,是全局级别缓存而不是sqlsession会话级别,此时可以通过 log4j 日志看到, sql 语句只生成了一次@Test public void findById(){ User user = userMapper.findById(10); User user2 = userMapper.findById(10); System.out.println(user==user2); //true }
Mybatis
逆向工程
-
概述我们在使用mybatis时,程序员需要自己在mapper.xml中编写sql语句,自己编写实体类,编写接口。mybatis官方提供理想工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java/mapper.xml/pojo...),可以让程序员将更多的经历放在繁杂的业务逻辑上在企业实际开发中,根据不同业务需求吧,逆向工程也经常使用之所以强调单表两个字,时因为Mybatis你想工程生成的mapper所进行的操作都是针对单表的,也许你觉得比较鸡肋,但是在某些项目中很少使用多表关联查询,所以作用还是很大的
-
入门
-
下载逆向工程 jar包 或者可以直接 maven下载 https://github.com/mybatis/generator/releases
<dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.0</version> </dependency>
-
代码的生成代码生成一共有三种方式可以帮助我们自动生成 eclipes 中插件 / 利用Maven插件生成 / 使用 java 程序生成创建普通的 java 项目 用于生成文件,生成后我们在粘贴到项目中引入下载好的 jar 包和 mysql 驱动创建生成代码 :
package com.zb.NXproject; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.File; import java.util.ArrayList; import java.util.List; public class GeneratorSqlmap { public void generator() throws Exception { List<String> warnings = new ArrayList<String>(); boolean overwrite = true; // 指定配置文件 File configFile = new File("./config/NXProject/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } // 执行main方法以生成代码 public static void main(String[] args) { try { GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap(); generatorSqlmap.generator(); } catch (Exception e) { e.printStackTrace(); } } }
-
创建配置文件 generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自动生成的注释 --> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- Mysql数据库连接的信息:驱动类、连接地址、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/ums" userId="root" password="root"> </jdbcConnection> <!-- Oracle数据库 <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --> <!-- 默认为false,把JDBC DECIMAL 和NUMERIC类型解析为Integer,为true时 把JDBC DECIMAL 和NUMERIC类型解析为java.math.BigDecimal --> <javaTypeResolver > <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成POJO类的位置 --> <javaModelGenerator targetPackage="com.zb.pojo" targetProject=".src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> <!-- 从数据库返回的值被清理前后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="cn.zb.mapper" targetProject=".src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetProject:mapper接口生成的的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="cn.zb.mapper" targetProject=".src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 指定数据表 --> <table schema="" tableName="user"></table> <!-- 有些表的字段需要指定java类型 <table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" > <property name="useActualColumnNames" value="true"/> <generatedKey column="ID" sqlStatement="DB2" identity="true" /> <columnOverride column="DATE_FIELD" property="startDate" /> <ignoreColumn column="FRED" /> <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> </table> --> </context> </generatorConfiguration>
配置完成后,运行创建生成代码中的Main方法,启动逆向工程
除了生成常规的 pojo 之外,还生成了用于设置条件的 xxxExample, 里面封装了很多查询条件
-
-
使用 将我们自动生成的代码,放到我们自己的项目对应路径中
-
查询:不足支出,不能指定查询的列,只能够查询所有列
public class TestNX { private ClassPathXmlApplicationContext ac; private UserMapper userMapper; private DepartmentMapper departmentMapper; @Before public void doBefore(){ ac=new ClassPathXmlApplicationContext("spring-config.xml"); userMapper=ac.getBean("userMapper",UserMapper.class); departmentMapper=ac.getBean("departmentMapper",DepartmentMapper.class); } @Test public void TestNXSelect(){ //创建用于设置条件的对象 DepartmentExample de=new DepartmentExample(); DepartmentExample.Criteria criteria=de.createCriteria(); criteria.andIdBetween(2,3); //查询方法一:根据条件查询 List<Department> list=departmentMapper.selectByExample(de); System.out.println(list); //查询方法二:根据主键查询 Department department=departmentMapper.selectByPrimaryKey(1); System.out.println(department); } @After public void doAfter(){ ac.close(); } }
-
插入插入操作很简单,只有两个方法,方法传入的参数都是 pojo 类型,返回值也是受影响的行数insert 会插入所有信息,如果传入的对象某一属性为空,则出入空,如果数据库中设置了默认值,默认值就失效了insertSelective 只会插入有数据的属性,对于为空的属性,不予理会,这样不会覆盖数据库中的默认值
@Test public void TestNXInsert(){ Department department=new Department(); departmentMapper.insert(department); departmentMapper.insertSelective(department); }
-
删除也是有两个方法,根据主键删除 / 根据条件删除
@Test public void TestNXDelete(){ DepartmentExample de=new DepartmentExample(); DepartmentExample.Criteria criteria = de.createCriteria(); criteria.andNameEqualTo("人力资源部"); //根据条件删除 departmentMapper.deleteByExample(de); //根据主键删除 departmentMapper.deleteByPrimaryKey(1); }
-
更新 更新的方法一共有 4个,我们可以将这4个方法分为两组去理解根据特定限制条件更新 xxxByExampleupdateByExample :根据特定的限制条件进行更新,除了 text 类型的所有列updateByExampleSelective :根据特定的限制条件更新所有列根据主键 ID 更新updateByPrimaryKey :通过 id 进行更新,除了 text 类型的所有列updateByPrimaryKeySelective: 通过 id 进行更新所有列
-
Mybatis
使用注解实现增删改查
在我们
sql
语句比较简单时我们可以直接在注解中写
sql
语句
在抽象方法上添加注解,在测试类直接调用方法即可,无需在
mapper.xml
映射文件中配置节点,适用于简单的增删改查
@Delete("delete from user where id = #{id}")
Integer deleteById(Integer id);
@Select("select * from user where id = #{id}")
User findById(Integer id);
最后
以上就是无限枕头为你收集整理的Mybatis框架复习&&整合Spring(二)的全部内容,希望文章能够帮你解决Mybatis框架复习&&整合Spring(二)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复