相关文章推荐
乐观的小刀  ·  2016届毕业生就业信息318——中材科技风 ...·  11 月前    · 
跑龙套的凉茶  ·  【教育资讯】西湖大学首届本科新生开学典礼举行 ...·  1 年前    · 
逃跑的单杠  ·  恶毒还貌美会被玩到哭哦by独上西楼全章节(无 ...·  1 年前    · 
聪明的椅子  ·  水族非遗又“上会” 宋水仙:马尾绣“绣”出美 ...·  2 年前    · 
犯傻的杨桃  ·  败者为寇漫画全集免费(下拉式)阅读-仙漫网·  2 年前    · 
Code  ›  mybatis 中对元数据的操作_mybatisplus怎样操作information_schema里面的元数据_天涯共明月的博客
元数据 mybatis jdbc orm
https://blog.csdn.net/mybook201314/article/details/120622769
逼格高的木瓜
2 年前
  • mybatis 中对元数据的操作
    • 1. 使用MySQL内部数据库information_schema表查询实现
      • 1.1 MySQL内部字段表 information_schema.COLUMNS
      • 1.2 mybatis的mapper.xml文件
      • 1.3 mybatis服务层
      • 1.4 输出结果
    • 2. 使用jdbc方式获取元数据
      • 2.1 使用原生jdbc获取元数据
        • 2.1.1 原生JDBC
        • 2.1.2 DatabaseMetaData.getColumns
      • 2.2 mybatis采用JDBC方式获取元数据
        • 2.2.1 mybatis服务层
        • 2.2.2 结果

        在目前流行的持久层框架mybatis中,有些场景下需要获取数据库表的元数据(字段名称、字段类型、字段长度、字段注释等)操作,可以实现让繁琐的事情简单化,自动生成Javabean或者mybatis中的mapper.xml文件等等。

        mybatis框架的逆向工程(mybatis-generate)也可以实现部分功能,有些场景是需要在Java运行时去动态获取字段列表等。

        本篇文章在spring boot+mybatis架构下完成的,若是需要可以查看往期文章:

        《Spring boot整合持久层框架Mybatis》

        在数据库 test 下建一张表 user

        CREATE TABLE `user` (
          `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
          `username` varchar(255) DEFAULT NULL COMMENT '用户姓名',
          `password` varchar(255) DEFAULT NULL COMMENT '用户密码',
          `isadmin` int(1) DEFAULT NULL COMMENT '是否是管理员',
          PRIMARY KEY (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8
        

        1. 使用MySQL内部数据库information_schema表查询实现

        通过查询试图,读取表的字段等信息

        1.1 MySQL内部字段表 information_schema.COLUMNS

        MySQL中,存放表字段的内部表是:information_schema.COLUMNS

        1.2 mybatis的mapper.xml文件

        例如:查询数据库 test 下的 表 user 的 表字段列名等信息,在mapper.xml文件中

        <select id="getUserTableColumns" resultType="map"> SELECT information_schema.COLUMNS WHERE TABLE_SCHEMA = 'test' TABLE_NAME = 'user' </select>

        TABLE_SCHEMA:数据库名称

        TABLE_NAME:表名

        mapper.java

        @Mapper
        public interface IUserMapper {
        	public List<Map<String, Object>> getUserTableColumns();
        

        1.3 mybatis服务层

        * @description * 获取 元 数据 * @author TianwYam * @date 2021年10月6日上午9:05:47 * @return public List<Map<String, Object>> getUserTableColumns(){ return userMapper.getUserTableColumns();

        1.4 输出结果

        "TABLE_CATALOG":"def", "IS_NULLABLE":"NO", "TABLE_NAME":"user", "TABLE_SCHEMA":"test", "EXTRA":"auto_increment", "COLUMN_NAME":"id", "COLUMN_KEY":"PRI", "NUMERIC_PRECISION":10, "PRIVILEGES":"select,insert,update,references", "COLUMN_COMMENT":"主键ID", "NUMERIC_SCALE":0, "COLUMN_TYPE":"int(11)", "ORDINAL_POSITION":1, "DATA_TYPE":"int" "TABLE_CATALOG":"def", "IS_NULLABLE":"YES", "TABLE_NAME":"user", "TABLE_SCHEMA":"test", "EXTRA":"", "COLUMN_NAME":"username", "COLUMN_KEY":"", "CHARACTER_OCTET_LENGTH":765, "PRIVILEGES":"select,insert,update,references", "COLUMN_COMMENT":"用户姓名", "COLLATION_NAME":"utf8_general_ci", "COLUMN_TYPE":"varchar(255)", "ORDINAL_POSITION":2, "CHARACTER_MAXIMUM_LENGTH":255, "DATA_TYPE":"varchar", "CHARACTER_SET_NAME":"utf8" "TABLE_CATALOG":"def", "IS_NULLABLE":"YES", "TABLE_NAME":"user", "TABLE_SCHEMA":"test", "EXTRA":"", "COLUMN_NAME":"password", "COLUMN_KEY":"", "CHARACTER_OCTET_LENGTH":765, "PRIVILEGES":"select,insert,update,references", "COLUMN_COMMENT":"用户密码", "COLLATION_NAME":"utf8_general_ci", "COLUMN_TYPE":"varchar(255)", "ORDINAL_POSITION":3, "CHARACTER_MAXIMUM_LENGTH":255, "DATA_TYPE":"varchar", "CHARACTER_SET_NAME":"utf8" "TABLE_CATALOG":"def", "IS_NULLABLE":"YES", "TABLE_NAME":"user", "TABLE_SCHEMA":"test", "EXTRA":"", "COLUMN_NAME":"isadmin", "COLUMN_KEY":"", "NUMERIC_PRECISION":10, "PRIVILEGES":"select,insert,update,references", "COLUMN_COMMENT":"是否是管理员", "NUMERIC_SCALE":0, "COLUMN_TYPE":"int(1)", "ORDINAL_POSITION":4, "DATA_TYPE":"int"

        2. 使用jdbc方式获取元数据

        2.1 使用原生jdbc获取元数据

        2.1.1 原生JDBC

        * @description * JDBC 获取元数据方式 * @author TianwYam * @date 2021年10月6日上午10:39:46 public class JdbcTest { public static void main(String[] args) throws Exception { // 1. 配置 数据库链接信息 String driver="com.mysql.cj.jdbc.Driver"; String url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC"; String username="root"; String password="mysql"; //2. 加载驱动 Class.forName(driver); //3. 建立连接 Connection connection= DriverManager.getConnection(url,username,password); //4. 获取元数据 DatabaseMetaData metaData = connection.getMetaData(); //5. 获取表的字段 列 ResultSet resultSet = metaData.getColumns("test", null, "user", null); //6. 处理ResultSet while(resultSet.next()){ //处理resultSet //7. 释放资源 resultSet.close(); connection.close();

        这儿是采用原生jdbc方式对元数据操作获取表的字段所有列,基本上都是以上几步

        2.1.2 DatabaseMetaData.getColumns

        // 获取表所有字段
        DatabaseMetaData.getColumns(String catalog, 
        						String schemaPattern, 
        						String tableNamePattern, 
        						String columnNamePattern) ;
        // catalog 分类 -- 数据库名称
        // schemaPattern 约束
        // tableNamePattern 表名
        // columnNamePattern 字段列名
        

        getColumns 方法返回值有:

        2.2 mybatis采用JDBC方式获取元数据

        持久层框架不同,需要对第三步中的获取连接 connection有所改变

        思路:Spring boot集成mybatis框架中,获取connection是从 SqlSessionFactory 中获取到 SqlSession,然后从 SqlSession 中获取到 Connection

        2.2.1 mybatis服务层

        新建类 封装表字段返回数据结构

        * @description * 表 元数据 字段列信息 * @author TianwYam * @date 2021年10月5日下午8:08:08 @Data @Builder public class TableColumnBean { private String dbName ; private String tableName ; private String columnName ; private String autoIncrement ; private String generatedColumn ; private String columnType ; private int columnLength ; private String columnRemark ;

        service类

        @Service
        public class UserService {
            // 自动引入(前提是 搭建了spring boot+mybatis架构)
        	@Autowired
        	private SqlSessionFactory sqlSessionFactory ;
        	 * @description
        	 *	获取 user 表的 元数据 表结构
        	 * @author TianwYam
        	 * @date 2021年10月6日上午9:05:14
        	 * @return
        	public List<TableColumnBean> getUserMeta() {
        		List<TableColumnBean> columnList = new ArrayList<>();
        		try {
        			// 获取连接、获取元数据
        			DatabaseMetaData metaData = sqlSessionFactory.openSession()
        				.getConnection()
        				.getMetaData();
        			// 获取 表字段
        			ResultSet columns = metaData.getColumns("test", null, "user", null);
                    // 对结果集 ResultSet 操作
        			System.out.println("column: ");
        			while(columns.next()){
        				TableColumnBean columnBean = TableColumnBean.builder()
        						.dbName(columns.getString("TABLE_CAT"))
        						.tableName(columns.getString("TABLE_NAME"))
        						.columnName(columns.getString("COLUMN_NAME"))
        						.autoIncrement(columns.getString("IS_AUTOINCREMENT"))
        						.generatedColumn(columns.getString("IS_GENERATEDCOLUMN"))
        						.columnType(columns.getString("TYPE_NAME"))
        						.columnLength(columns.getInt("COLUMN_SIZE"))
        						.columnRemark(columns.getString("REMARKS"))
        						.build();
        				columnList.add(columnBean);
        			System.out.println(JSON.toJSONString(columnList, true));
        		} catch (SQLException e) {
        			// TODO Auto-generated catch block
        			e.printStackTrace();
        		return columnList;
                            mybatis 中对元数据的操作目录mybatis 中对元数据的操作1. 使用MySQL内部数据库information_schema表查询实现1.1 MySQL内部字段表 information_schema.COLUMNS1.2 mybatis的mapper.xml文件1.3 mybatis服务层1.4 输出结果2. 使用jdbc方式获取元数据2.1 使用原生jdbc获取元数据2.1.1 原生JDBC2.1.2 DatabaseMetaData.getColumns2.2 mybatis采用JDBC
        Sql 注入产生原因及威胁:
        当我们访问动态网页时, Web 服务器会向数据访问层发起 Sql 查询请求,如果权限验证通过就会执行 Sql 语句。这种网站内部直接发送的Sql请求一般不会有危险,但实际情况是很多时候需要结合用户的输入数据动态构造 Sql 语句,如果用户输入的数据被构造成恶意 Sql 代码,Web 应用又未对动态构造的 Sql 语句使用的参数进行审查,则会带来意想不到的危险。
        Sql 注入带来的威胁主要有如下几点
        猜解后台数据库,这是利用最多的方式,盗取网站的
        N+1问题??
        N+1问题来源于数据库中常见的级联技术,即N个数据库表形成关联关系,当再增加一个关联表时,也就是N+1个级联关系,由于某些时候,我们并不需要加载数据库的所有数据,而是某一个数据库表中数据,这时Mybatis会自动加载所有表的数据,多执行几条无关sql语句,会造成数据库资源的浪费以及系统性能的下降,这就是级联表的缺点。
        如何解决N+1问题
        				
         &lt;select id="findFields" resultType="java.lang.String"&gt; select DISTINCT COLUMN_NAME,DATA_TYPE from information_schema.COLUMNS where table_name = #{dataTable}  &lt;/select&gt;
        随着业务的发展和合规要求,产品数据库将切换到Postgres。之前不同技术域,不同交付工程的数据分库管理的方式切换到PG数据库后将通过分schema管理。 ORM继续使用Mybatis,为使用迁移工作量极可能小,现有的SQL代码不做大的修改,考虑在Mybatis执行过程中做拦截,替换sql中的schema标识。 提取请求参数中的schema 约定rest接口请求参数中增加schema,通过切面技术从请求头中schema保持到线程变量中。 1. 提取schema代码 package com.postgr <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration>
        mysql查询表名: SELECT table_name FROM information_schema.tables WHERE table_schema='sell' AND table_type='base table'; 查询表中的字段: SELECT column_name FROM information_schema.columns WHERE table_sc...
        private List<String> getTableName(String tradeTimeBegin,String tradeTimeEnd){ List<String> tableName = new ArrayList<>(); if(StringUtils.isBlank(tradeTimeBegin)){ tradeTimeBegin="2020-01-01"; <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>3.4.1</version> </dependency> 然后,你可以使用@TableField注解来标记你的实体类中的JSON类型字段: ```java public class User { // ... 省略其他字段 @TableField(typeHandler = JsonTypeHandler.class) private Map<String, Object> extra; 这样,在使用mybatis-plus操作数据库时,extra字段就会自动使用JsonTypeHandler进行转换。 你也可以自定义自己的JsonTypeHandler来覆盖默认的转换器,例如使用你喜欢的JSON库进行转换。 ```java public class MyJsonTypeHandler extends JsonTypeHandler { // ... 自定义实现 然后,在你的实体类中使用自定义的JsonTypeHandler: ```java public class User { // ... 省略其他字段 @TableField(typeHandler = MyJsonTypeHandler.class) private Map<String, Object> extra; 最后,你就可以在mybatis-plus中像操作其他类型一样操作JSON类型数据了。
 
推荐文章
乐观的小刀  ·  2016届毕业生就业信息318——中材科技风电叶片股份有限公司招聘信息-黑龙江大学研究生院
11 月前
跑龙套的凉茶  ·  【教育资讯】西湖大学首届本科新生开学典礼举行!校长施一公致辞“大学,何以为大”_陈虹宇_未来的_大写
1 年前
逃跑的单杠  ·  恶毒还貌美会被玩到哭哦by独上西楼全章节(无弹窗)全文免费阅读
1 年前
聪明的椅子  ·  水族非遗又“上会” 宋水仙:马尾绣“绣”出美好新生活_新闻频道_央视网(cctv.com)
2 年前
犯傻的杨桃  ·  败者为寇漫画全集免费(下拉式)阅读-仙漫网
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号