Java面试题总结-02

索引

1.较频繁的查询条件字段应该创建索引
2.唯一性太差的字段不适合单独创建索引 即使频繁查询条件
3.更新频繁的字段不适合创建索引
4.不会出现在where子句中字段不该创建索引

-- 创建索引
CREATE TABLE t (
	id INT ,
	`name` VARCHAR(32));
	
-- 查询表是否有索引
SHOW INDEXES FROM 表名;

-- 添加索引
# create index 索引名 on 表名 (列名)
# alter table 表名 add index 索引名 (列名) 

-- 添加普通索引方式1
CREATE INDEX id_index ON t (id);
-- 添加普通索引方式2
ALTER TABLE t ADD INDEX id_index (id);
-- 添加唯一索引 
CREATE UNIQUE INDEX id_index ON t (id);
-- 如何选择 
-- 1. 如果某列的值,是不会重复的,则优先考虑使用unique索引, 否则使用普通索引

-- 添加主键索引
CREATE TABLE a (
	id INT ,
	`name` VARCHAR(32));
ALTER TABLE a ADD PRIMARY KEY (id)

-- 删除索引
# drop index 索引名 ON 表名
DROP INDEX id_index ON t
-- 删除主键索引
# alter table 表名 drop primary key
ALTER TABLE a DROP PRIMARY KEY

-- 修改索引 先删除 在添加新的索引

-- 查询索引
-- 1. 方式
SHOW INDEX FROM t
-- 2. 方式
SHOW INDEXES FROM t
-- 3. 方式
SHOW KEYS FROM t
-- 4 方式
DESC t

MySQL索引分类
数据结构维度
	B+Tree Hash FullText R-Tree
物理存储维度
	聚簇索引(依靠B+树) 非聚簇索引
字段约束维度
	主键索引 唯一索引 普通索引 前缀索引
索引组成维度
	单列索引 联合索引
	
索引失效的情况
1. 在where条件语句 '=' 的左边进行函数、运算符或表达式的计算
2. 不推荐使用like操作
  like '%aaa%' 和 like '%aaa' 都不会使用索引
  而 like 'aaa%' 可以使用索引
3. 避免对字段进行null的判断 (可以用一个值代替null,如-999)
4. 避免使用or,可以用union替代
  如果使用or还要让索引生效 or条件中的每个列都必须加上索引
5. 使用exist代替in
  表中数据越多,exist的效率就比in要越大
6. 联合索引要符合最左前缀原则
例如: 一个表a,b,c,d,e列,由三个字段 a,b,c 组成联合索引 idx_a_b_c
索引生效: SELECT * FROM table_name WHERE a = 1 AND b = 2 AND c = 5 
索引生效: SELECT * FROM table_name WHERE b = 2 AND a = 1 AND c = 5 
索引生效: SELECT * FROM table_name WHERE a = 1  

索引失效: SELECT * FROM table_name WHERE b = 2 AND c = 5
索引失效: SELECT * FROM table_name WHERE c = 5 

部分生效: SELECT * FROM table_name WHERE a = 1 AND c = 5 
部分生效: SELECT * FROM table_name WHERE a = 1 AND b > 2 AND c = 5 

事务

start transaction 开始一个事务
savepoint 设置保存点
rollback to 回退事务
rollback 回退全部事务
commit 提交事务 所有操作生效 不能回退

-- 1. 创建一张测试表
CREATE TABLE t
	( id INT,
	  `name` VARCHAR(32));
-- 2. 开始事务
START TRANSACTION 
-- 3. 设置保存点
SAVEPOINT a
-- 执行dml 操作
INSERT INTO t VALUES(100, 'tom');
SELECT * FROM t;
-- 3. 设置保存点
SAVEPOINT b
-- 执行dml操作
INSERT INTO t VALUES(200, 'jack');
-- 4.回退到 b
ROLLBACK TO b
-- 4.继续回退 a
ROLLBACK TO a
-- 4.直接回退到事务开始的状态.
ROLLBACK
-- 5.提交事务 所有操作生效不能回退
COMMIT

事务细节
#1.如果不开始事务 默认情况下 dml操作是自动提交的 不能回滚
    -- 自动提交 commit
    INSERT INTO t VALUES(300, 'milan');
#2. 如果开始一个事务,你没有创建保存点. 你可以执行rollback,
    -- 默认就是回退到你事务开始的状态
    START TRANSACTION 
    INSERT INTO t VALUES(400, 'king');
    INSERT INTO t VALUES(500, 'scott');
    -- 表示直接回退到事务开始的的状态
    ROLLBACK
    COMMIT;
#3.你也可以在这个事务中(还没有提交时),
    -- 创建多个保存点.比如: savepoint a;    
    -- 执行dml, savepoint b
#4.你可以在事务没有提交前,选择回退到哪个保存点
#5.InnoDB 存储引擎支持事务, MyISAM不支持
#6.开始一个事务 start  transaction, set autocommit=off;

事务四大特性

事务: 
	生活中的事务: 指的是比较正式的事情
	数据库中的事务: 指的是一组最小逻辑操作单元,这个操作它包含了很多步骤,组成这个事务的这些步骤,是整体不可再分割的,这些步骤要么同时成功,要么同时失败
	
	转账: 张三给李四转账1000元
		1.张三的账户上减去1000元
		出现异常
		2.李四的账户上增加1000元
	上面减钱和加钱这两步操作 必须在同一事务中进行。
    
事务的四大特性(ACID):
1.原子性(Atomicity):
	原子性是指事务是一个不可分割的工作单位 
	事务中的操作要么都发生,要么都不发生
2.一致性:
	事务必须使数据库从一个一致性状态变换到另外一个一致性状态
3.隔离性:
	事务的隔离性是多个用户并发访问数据库时
	数据库为每一个用户开启的事务
	不能被其他事务的操作数据所干扰
	多个并发事务之间要相互隔离
4.持久性:
	持久性是指一个事务一旦被提交
	它对数据库中数据的改变就是永久性的
	接下来即使数据库发生故障也不应该对其有任何影响
	
默认情况下,Connection对象处于自动提交模式下
这意味着它在执行每个语句后都会自动提交更改。
如果禁用了自动提交模式,那么要提交更改就必须显式调用commit方法
否则无法保存数据库更改。
//void setAutoCommit ( boolean autoCommit)
throws SQLException将此连接的自动提交模式设置为给定状态
如果连接处于自动提交模式下,则它的所有SQL语句将被执行并作为单个事务提交。
否则,它的SQL语句将聚集到事务中,
直到调用commit方法或rollback方法为止。
默认情况下,新连接处于自动提交模式。

事务隔离级别

★不考虑隔离性会出现的读问题
脏读: 
	在一个事务中读取到另一个事务没有提交的数据
不可重复读:
	在一个事务中,两次查询的结果不一致(针对的update操作)
	不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
虚读(幻读):
	在一个事务中,两次查询的结果不一致(针对的insert操作)
	无法演示出来,MySQL已经默认避免了
	
★MySQL四种隔离级别	
通过设置数据库的隔离级别来避免上面的问题
read uncommitted  	读未提交	上面的三个问题都会出现
read committed  	读已提交	可以避免脏读的发生Oracle默认级别
repeatable read		可重复读	可以避免脏读和不可重复读的发生MySQL默认级别
serializable		串行化		可以避免所有的问题

●演示脏读的发生:
    将数据库的隔离级别设置成 读未提交
    set session transaction isolation level read uncommitted;
    查看数据库的隔离级别
    select @@tx_isolation;
    演示:
        打开两个窗口进行演示: 给两个窗口设置好相同的隔离级别
        开启事务: start transaction;
        修改数据: update bank set money=1500 where username='lisi';
        让另一个窗口开启事务 查询数据 他查到了 就是脏读
        我这边窗口 一回滚(rollback),钱又没过去
●避免脏读的发生,将隔离级别设置成 读已提交
    set session transaction isolation level read committed;
    不可避免不可重复读的发生
●避免不可重复读的发生 经隔离级别设置成 可重复读
	set session transaction isolation level repeatable read; 
●演示串行化 可以避免所有的问题
	set session transaction isolation level  serializable;  
	我这边的事务不提交,那边的事务无法执行锁表的操作 
    
四种隔离级别的效率
(read uncommitted)>(read committed)>(repeatable read)>(serializable)
四种隔离级别的安全性
(read uncommitted)<(read committed)<(repeatable read)<(serializable)

开发中绝对不允许脏读发生
    mysql中默认级别:repeatable read
    oracle中默认级别:read committed

java中控制隔离级别:
    Connection的api
    void setTransactionIsolation(int level) 
    level是常量 

视图

概念:
	有结构(有行有列)
	但没有结果(结构中不真实存储数据)的虚拟的表,
    虚拟表的结构来源不是自己定义
    而是从对应的基表中产生(视图数据的来源)

◎创建视图语法:
  	create view 视图名称 as select语句
    #创建单表视图 
  	CREATE VIEW my_v1 AS SELECT * FROM employee;
    #创建多表视图 注意:不要查询两张表中的同名字段 不然会报错
  	create view my_v2 
  		as select a.字段名,b.字段名 from a,b where a.id=b.id;
  		
  	注意:MySQL中视图不支持封装子查询查出来的数据
  
查看视图 
	其实视图是一张 虚拟表 那关于查询表的语句 对视图都是可以用的
  	show tables; 
    #显示视图的结构
  	desc 视图名;
  	#视图查询语句
  	SELECT * FROM 视图名;
  	#查看视图创建语句
  	show create view 视图名;
  
视图的使用: 
	视图的使用,只是为了简化查询,你可以把视图当作表一样去使用
    视图的执行:其实本质就是执行封装的select语句
    
◎删除视图: drop view 视图名  
	drop view my_v1
  
◎修改视图:
	视图本身不可以修改,但是视图的来源是可以修改的(其实就是修改select语句)
  	语法: alter view 视图名字 as 新的select语句
  
视图的意义:
    (1) 视图可以节省SQL语句,
        将一条复杂的查询语句,
        使用视图进行保存,
        以后可以直接对视图进行操作
    (2) 数据安全,
        视图操作注意是针对查询语句的,
        如果对视图结构进行处理(比如删除),
        不会影响基表的数据,
        所以相对来说数据比较安全
    (3) 视图往往是在大项目中去使用,
        而且是多系统中去使用,
        我可以对外提供一些有用的数据,
        隐藏一些关键的数据
    (4) 视图对外可以提供友好的数据,
        不同的视图提供不同的数据,
        对外提供的数据好像是经过专门设计的一样
    (5) 视图可以更好的进行权限控制 
    	比如对外隐藏我的一些基表的名称
  
视图数据的操作:
	视图是可以进行数据操作的(比如 增,删,改,视图中的数据),但是有很多限制
	视图插入数据:
  		(1)多表视图不能插入数据
  		(2)单表视图中可以插入数据
  			如果视图中字段没有基表中不能为空的字段且没有默认值的字段,是插入不成功的
  		(3)视图是可以向基表中插入数据的 
  			视图的操作是影响基表的
  	视图删除数据
  		(1)多表视图不能删除数据
  		(2)单表视图可以删除数据,也会影响到基表
  	视图更新数据
  		单表视图,多表视图都可以更新数据
  		更新限制:with check option
  		例如: create view my_v1 
            	 as select * from student 
             	 where age>30 
            	 with check option;
  		    表示视图数据的来源都是年龄大于30的
  		    with check option 决定通过视图更新的时候
  		    不能将已得到数据age>30的学生 改成age<30 的
  		    那么:update my_v1 set age=20 where id=1; 
  		    	就会报错 不允许改 因为做了限制

存储过程

存储过程是数据库中的一个对象 
存储在服务端 用来封装多条SQL语句且带有逻辑性 可以实现一个功能
由于他在创建时 就已经对SQL进行了编译 所以执行效率高 
而且可以重复调用 类似与我们Java中的方法

in:输入参数
out:输出参数
inout:输入输出参数

DELIMITER $$ 
CREATE PROCEDURE `security`.`test2`(IN num INT,OUT res INT)
BEGIN
  SELECT * FROM sys_role WHERE id = num;
  SELECT COUNT(*) FROM sys_role INTO res;
END $$ 
DELIMITER ; 

CALL `security`.`test2`(1,@res);
SELECT @res;

函数

函数包含了内置函数和自定义函数

函数调用
SELECT 函数名();

删除函数:
DROP FUNCTION 函数名; 

函数和存储过程的区别
1.存储过程没有返回值 函数必须要有返回值
  但是存储过程可以用out能实现返回值这个作用
2.存储过程有in out inout这几个参数类型 
  函数的参数全是用来收实参
  
自定义函数语法
DELIMITER $$
CREATE
    FUNCTION `数据库名`.`函数名`()
    RETURNS 返回类型
    BEGIN
       函数逻辑...
    END$$
DELIMITER ;

触发器

触发器:
	数据库中的一个对象 相当于JS中的监听器 
	触发器可以监听 增 删 改 三个动作

比如说我想监听一张表,只要我增删改了这张表中的数据,
 		我就可以触发这个触发器,去往另外一张表中记录一下日志
 		
-- 往一张表test中删除数据
-- 在日志表logger中添加一条记录
DELIMITER $$
CREATE TRIGGER tigger1 
    AFTER DELETE ON test
    FOR EACH ROW 
    BEGIN
	INSERT INTO logger VALUES(NULL,"你删除了一条数据",NOW());
    END$$
DELIMITER ;

DELETE FROM employee_enh WHERE emp_no = 25348;
#删除test表中的内容后 触发器启动 		

mybatis的使用

pom.xml 导入jar包

<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.14</version>
    </dependency>
    <!--分页插件-->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

<build>
    <plugins> <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.0</version>
            <!-- 插件的依赖 -->
            <dependencies>
                <!-- 逆向工程的核心依赖 -->
                <dependency>
                    <groupId>org.mybatis.generator</groupId>
                    <artifactId>mybatis-generator-core</artifactId>
                    <version>1.3.2</version>
                </dependency>
                <!--mysql驱动-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.6</version>
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

src/main/resources/mybatis/mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <!--开启驼峰式命名-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <plugins>
        <!--设置分页插件-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
</configuration>

src/main/resources/application.properties

# 应用名称
spring.application.name=airQuality
# 应用服务 WEB 访问端口
server.port=8080

#mybaits的相关配置
#mybatis核心配置文件的路径
mybatis.config-location=classpath:mybatis/mybatis-config.xml
# mybatis  mapper 接口的映射文件路径
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# 实体类的别名
mybatis.type-aliases-package=com.edu.entities

# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/airquality?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456

#使用德鲁伊数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 初始化大小,最小,最大
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
# 配置获取连接等待超时的时间
spring.datasource.druid.max-wait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.time-between-eviction-runs-millis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.min-evictable-idle-time-millis=300000

src/main/resources/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>

    <!--
    targetRuntime: 执行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD(清新简洁版)
    MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="testTables" targetRuntime="MyBatis3" defaultModelType="flat">

        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/airquality?serverTimezone=UTC"
                        userId="root"
                        password="123456">
            <!--去除xxxWithBLOBs的影响-->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>

        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="com.edu.entities" targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
            <!-- true就可以保证与数据库中的字段一致
                 false就是驼峰命名法的格式 -->
            <property name="useActualColumnNames" value="true"/>
        </javaModelGenerator>

        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="mybatis.mapper" targetProject=".\src\main\resources">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.edu.mapper"
                             targetProject=".\src\main\java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 指定数据库表 -->
        <!-- <table schema="" tableName="tb_item" domainObjectName="Item"></table>
            domainObjectName 可以配置生成的pojo名字
            如不需要example类添加下面四个属性 默认为true
            enableCountByExample="false" enableDeleteByExample="false"
            enableSelectByExample="false" enableUpdateByExample="false"></table> -->
        <table tableName="air_quality_index" domainObjectName="AirQualityIndex"/>
        <table tableName="district" domainObjectName="District"/>
    </context>
</generatorConfiguration>

src/main/java/com/edu/AirQualityMybatisApplication.java

@SpringBootApplication
@MapperScan(basePackages = "com.edu.mapper")
public class AirQualityMybatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(AirQualityMybatisApplication.class, args);
    }
}

src/test/java/com/edu/AirQualityMybatisApplicationTests.java

@SpringBootTest
class AirQualityMybatisApplicationTests {

    @Autowired
    private AirQualityIndexMapper airQualityIndexMapper;

    @Autowired
    private DistrictMapper districtMapper;

    @Test
    void contextLoads() {
        //按条件查询
        District district = districtMapper.selectByPrimaryKey(1);
        System.out.println(district);
    }

    @Test
    void contextLoads1() {
        //创建条件查询对象
        AirQualityIndexExample airQualityIndexExample = new AirQualityIndexExample();
        airQualityIndexExample.createCriteria().andIdBetween(2,4);
        List<AirQualityIndex> airQualityIndices = airQualityIndexMapper.selectByExample(airQualityIndexExample);
        airQualityIndices.forEach(System.out::println);
    }
}

mybatis-plus的使用

pom.xml 导入jar包

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
        <!--修改mysql驱动版本号-->
        <version>5.1.47</version>
    </dependency>
    <!--mybatis-plus启动器-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.3</version>
    </dependency>
    <!--mybatis-plus代码生成-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.4.1</version>
    </dependency>
    <!--模板引擎-->
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.31</version>
    </dependency>
    <!--druid连接池-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.21</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

src/main/resources/application.properties

# 应用名称
spring.application.name=AirQuality_mybatis_plus
# 应用服务 WEB 访问端口
server.port=8080

# 数据库驱动:根据pom.xml文件中的MySQL版本定
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/airquality
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#配置实体类别名
mybatis-plus.type-aliases-package=com.edu.entity
#配置mapper接口对应的xml文件放置的位置
mybatis-plus.mapper-locations=classpath:com/edu/mapper/*.xml"
#配置日志输出级别,输出sql语句
logging.level.org.westos.mapper=debug

src/test/java/com/edu/CodeGenerator.java

public class CodeGenerator {

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        //这里注意加上 useSSL=false
        dsc.setUrl("jdbc:mysql://localhost:3306/airquality?useSSL=false");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        //文件生成路径
        String path = System.getProperty("user.dir") + "/src/main/java";
        System.out.println(path);
        gc.setOutputDir(path);
        gc.setIdType(IdType.AUTO); //id自增长
        gc.setAuthor("作者:李杰");
        gc.setFileOverride(true); //覆盖现有的
        gc.setOpen(false); //是否生成后打开
        gc.setDateType(DateType.ONLY_DATE); //日期字段
        mpg.setGlobalConfig(gc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.edu"); //父包名
        //设置不同类文件生成的路径,如果你要默认的路径,下面可以不用设置
        //==========================
        HashMap<String, String> pathMap = new HashMap<>();
        //设置实体类生成的位置
        pathMap.put(ConstVal.ENTITY_PATH, System.getProperty("user.dir") + "/src/main/java/com/edu/entity");
        pathMap.put(ConstVal.CONTROLLER_PATH, System.getProperty("user.dir") + "/src/main/java/com/edu/controller");
        //设置Mapper接口生成的位置
        pathMap.put(ConstVal.MAPPER_PATH, System.getProperty("user.dir") + "/src/main/java/com/edu/mapper");
        //设置Service接口的位置
        pathMap.put(ConstVal.SERVICE_PATH, System.getProperty("user.dir") + "/src/main/java/com/edu/service");
        //设置Service接口实现类的位置
        pathMap.put(ConstVal.SERVICE_IMPL_PATH, System.getProperty("user.dir") + "/src/main/java/com/edu/service");
        pc.setPathInfo(pathMap);
        //============================================

        mpg.setPackageInfo(pc);

        // 自定义配置,这里配置 接口对应的mapper文件的输出路径,如果你要默认的位置可以不用设置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return System.getProperty("user.dir") + "/src/main/resources/com/edu/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true); //使用lombok
        strategy.setEntitySerialVersionUID(true);// 实体类的实现接口Serializable
        strategy.setRestControllerStyle(true); // @RestController
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix("tb_"); // 去掉表前缀
        mpg.setStrategy(strategy);

        //设置模板引擎
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }


    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }
}

src/main/java/com/edu/AirQualityMybatisPlusApplication.java

@SpringBootApplication
@MapperScan(basePackages = "com.edu.mapper")
public class AirQualityMybatisPlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(AirQualityMybatisPlusApplication.class, args);
    }
}

src/main/java/com/edu/config/MybatisPlusConfig.java

@Configuration
@EnableTransactionManagement //开启事务管理
@MapperScan("com.edu.mapper") //扫描该包下所有的mapper接口
public class MybatisPlusConfig {
    //分页插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

src/test/java/com/edu/AirQualityMybatisPlusApplicationTests.java

@SpringBootTest
class AirQualityMybatisPlusApplicationTests {

    @Autowired
    private AirQualityIndexMapper airQualityIndexMapper;

    @Autowired
    private DistrictMapper districtMapper;

    @Test
    void contextLoads() {
        District district = districtMapper.selectById(2);
        System.out.println(district);

        HashMap<String, Object> hm = new HashMap<>();
        hm.put("id",1);
        List<District> districts = districtMapper.selectByMap(hm);
        districts.forEach(System.out::println);

        //分页查询
        Page<District> districtPage = new Page<>(1,3);
        districtMapper.selectPage(districtPage, null);
        System.out.println(districtPage.getCurrent()+" "+districtPage.getSize());
    }


    @Test
    void contextLoads1() {
        //条件构造器
        QueryWrapper<AirQualityIndex> qw = new QueryWrapper<>();
        qw.in("id",1,2,3);
        List<AirQualityIndex> airQualityIndices = airQualityIndexMapper.selectList(qw);
        airQualityIndices.forEach(System.out::println);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值