精华内容
下载资源
问答
  • 今天小编就为大家分享一篇php从数据库中获取数据用ajax传送到前台的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 今天小编就为大家分享一篇ajax动态查询数据库数据并显示在前台的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 今天看到有人问答上问怎样去动态取值附option上,本来想解决的,但我发现。。。。没有,我本来也笨,记不住,所以还是写一下,让大家可以看一下: 首先我这用的框架是SSM,代码就开始了: 这是写在前台的方法里...
  • 主要为大家详细介绍了node.js从数据库获取数据的具体代码,nodejs可以获取具体某张数据表信息,感兴趣的朋友可以参考一下
  • 直接用就可以,特别简单,简单易懂 代码有注释很好看懂
  • 用jquery的.getjson()技术和.ajax技术实现从后台的mysql数据在前台显示,能够直接myeclipse运行。
  • vue.js动态获取数据库数据 (通过vue.cli和webpack搭建的环境) 1.首先我先创建一个静态的data.json文件,static下创建json文件夹,(webpack环境下,静态的文件放在static目录下) { data:[ {id:1,name: yidong,...
  • 如何从数据库数据获取到前台页面

    万次阅读 热门讨论 2019-05-05 23:16:00
    最近做有个简单的电商平台,想做一个功能就是搜索商品的时候通过数据库查找,最后把数据直接显示在前台页面上。我自己完成功能的时候通过了俩种方式...1、首先,先从数据库中获取数据,并把数据返回给前台页...

    最近在做有个简单的电商平台,想做一个功能就是在搜索商品的时候通过数据库查找,最后把数据直接显示在前台页面上。我自己在完成功能的时候通过了俩种方式实现(基于SSM框架)完成,在此将我们的想法和代码分享出来,供自己和他人参考。

     

    电影的数据库数据:

    ps:imagepath 存放的图片的地址

    一、通过EL表达式和简单点SSM框架知识

    1、首先,先从数据库中获取数据,并把数据返回给前台页面

            控制器代码

    	@RequestMapping("/selmovie")
    	public String  selAllMovie(HttpServletRequest req){
                    //获取所有的电影信息
    		List<Movie> lm = moiveServiceImpl.selAllMovie();
    		if(lm!=null){
    			for (Movie movie : lm) {
    				System.out.println(movie);
    			}
    		}
    		req.setAttribute("movie", lm);
    		return "movie.jsp";
    	}

     

    2、在前台中显示(通过EL表达式和JSTL标准标签库)

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    <%@ taglib  prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'movie.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
    	  <style>
    	    *{margin: 0;padding: 0}
    	    #movie{width: 690px; margin: 40px auto}
    	    #movie ul li{list-style-type: none;float: left;width: 150px; height: 270px;margin: 10px 10px; position: relative}
    	    #movie ul li a div{list-style-type: none;float: left;width: 120px;}
    	    #movie ul li a p{position: absolute;top:200px;width: 150px;height: 70px;padding: 5px;box-sizing: border-box;font-size: 15px;}
    	    #movie ul li a p .grade{ color: #ffba5a ;font-weight: bold}
    	
    	
    	</style> 
     <body>	
        <div id="movie">
            <ul>
                <!--jstl标准标签库的循环-->
                <!--El表达式可以获取到四大作用域中的信息-->
                <c:forEach items="${movie }" var="mm">
    	            <li>
    	                <a>
    	                    <div>
    	                    	<img src="${mm.imagepath }" width="150px" height="200px">
    	                    </div>
    	                    <p>
    	                        <span>${mm.name }</span>&nbsp;&nbsp;
    	                        <span class="grade"> ${mm.average }</span>
    	                    </p>
    	                </a>
    	            </li>  
                </c:forEach>
            </ul>
        </div>
    </body>
    </html>
    

    3、添加一个触发点;

    因为我的页面必须先访问控制器才能返回数据到movie.jsp页面。所有需要一个网页先去访问控制器

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'movie2.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
      
      <body>
      	<!-- 触发点 -->
        <a href="selmovie">获取所有电源</a>
      </body>
    </html>
    

     

    返回结果:

     

     

    二、通过ajax异步请求获取后台数据

    1、在前端异步请求控制器并获取到电源数据

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'movieajax.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
    </head>
    <style>
        *{margin: 0;padding: 0}
        #movie{width: 690px; margin: 40px auto}
        #movie ul li{list-style-type: none;float: left;width: 150px; height: 270px;margin: 10px 10px; position: relative}
        #movie ul li a div{list-style-type: none;float: left;width: 120px;}
        #movie ul li a p{position: absolute;top:200px;width: 150px;height: 70px;padding: 5px;box-sizing: border-box;font-size: 15px;}
        #movie ul li a p .grade{ color: #ffba5a ;font-weight: bold}
    </style>
      <script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
      <script type="text/javascript">
                    //代码自动执行
      		$(function(){
      		  	var movies;
      		  	var movie ="";
      		  	/* 异步请求数据  */
      			$.ajax({
     		  	  type : "get",
     		 	  dataType : "json",
      		      url : "selmovie1",
      		      error : function(){
      		      		alert("请求失败");
      		      },
       		      success : function(movies) {
       		      	 //movie为json数据
       		      	 //通过$.each遍历json数据
       		      	 $.each(movies,function(key,obj){
       		      	 	  //拼接字符串
                  		  movie +="<li><a><div><img src='"+obj.imagepath+"' width='150px' height='200px'><p><span>'"+obj.name+"'</span>&nbsp;&nbsp;<span class='grade'>'"+obj.average+"'</span></p></div></a></li>";
    	   		  });
        	   	       }
    		     });
    		     //这块我本是想等到上面函数执行完在执行下面的代码,但是上面获取数据以及拼接字符串太耗费时间,总是优先执行下面的代码
    		     //所以暂时想出此方法来完成功能,往后在进行修改
    		     setTimeout(function() {	
    		     	 //将拼接好的字符串加入到html代码中去 
    		   	 $("#movie ul").html(movie);
    			},1000);
      		})
      </script>
      
      <body>
        <div id="movie">
             <ul>
             </ul>
        </div>
      </body>
    </html>
    

    2、在控制器中返回json格式的数据

    	@RequestMapping(value="/selmovie1",produces="application/json;charset=utf-8")
    	@ResponseBody
    	public List<Movie>  selAllMovie1(HttpServletRequest req){
    		List<Movie> lm = moiveServiceImpl.selAllMovie();
    		return lm;
    	}

     

    返回结果

     

     

    三、启发

    今天听到班里大牛在群里分析的类似的功能

    感觉也是可以从过滤器进行获取数据。

     

     

     

    展开全文
  • 首先我们需要项目pom.xml文件引入Mysql数据库相关架包: 注意:springboot项目引入架包时不需要加上版本号,因为自带的标签库自带了每个jar包工具的版本号,当你导入需要的架包时候springboot会自动为你...
  • ![图片说明](https://img-ask.csdn.net/upload/201706/14/1497428613_702432.png) ![图片说明]... 这样写不对吗?为什么获取到数据显示出来呢?新手求帮助。
  • 前台input数据异步传后台并存入数据库 先看图: 利用ajax异步交互数据,并不是以json数组的形式将数据后台,而是利用字符数组的形式将其传后台。动态新增每一行数据,将每一列对应的数...

    将前台input中的数据异步传到后台并存入数据库

    先看图:

    利用ajax异步交互数据,并不是以json数组的形式将数据传到后台,而是利用字符数组的形式将其传到后台。动态新增每一行数据,将每一列对应的数据存入数组,并传到后台中进行入库。(当然可以直接以json数组的形式将每一行的数据传到后台,这里就不详细讲了)

    前台js代码:

      ///保存多行数据,运用ajax异步交互请求
            function btnSave() {
                /*传值方式一:将添加的每一字段的值存在数组中,再将数组转换成字符串串传到后台*/
                //定义五个一维数组
                var code = new Array();
                var name = new Array();
                var pwd = new Array();
                var phone = new Array();
                var bmmc = new Array();
    
                //将表单中的数据添加到各自的数组中
                for (var i = 1; i <= rowL; i  ) {
                    code.push($("#"   "UserCode"   i).val());//对应每个增加表单中的id相应的值
                    name.push($("#"   "UserName"   i).val());
                    pwd.push($("#"   "UserPwd"   i).val());
                    phone.push($("#"   "Phone"   i).val());
                    bmmc.push($("#"   "Bmmc"   i).val());
                }
                //利用js的join方法将数组分割成字符串,用于传值,在后台解析。分割符号为逗号,可自行定义。
                var Code = code.join(',');
                var Name = name.join(',');
                var Pwd = pwd.join(',');
                var Phone = phone.join(',');
                var Bmmc = bmmc.join(',');
    
                //利用ajax进行传值,类型为POST
                $.ajax({
                    type: "POST",
                    //  dataType: "Text",
                    url: "UserList.ashx?Action=Save",
                    data: {
                        UserCode: Code,
                        UserName: Name,
                        UserPwd: Pwd,
                        UserPhone: Phone,
                        BmMc: Bmmc,
                        RowLength: rowL//将增加的行数传至后台控制for循环中的参数范围
                    },
                    success: function (result) {
                        if (result == "true") {
                            noty({ text: "保存成功!", type: "success", layout: "topCenter", timeout: 2000 });
                            Refresh();
                            
                        } else {
                            noty({ text: "保存失败!", type: "error", layout: "topCenter", timeout: 2000 });
                        }
                    }
                });
               
            }

    2、后台获取数据的代码:

       private string HandleSaveRequest(HttpContext context)
            {
                string result = "False";
                try
                {
                    /*定义参数数组,获取前台数据,并解析成数组形式。运用方法split()*/
                    string []UserName = context.Request.Form["UserName"].ToString().Split(',');
                    string []UserCode = context.Request.Form["UserCode"].ToString().Split(',');
                    string []UserPwd = context.Request.Form["UserPwd"].ToString().Split(',');
                    string []Phone = context.Request.Form["UserPhone"].ToString().Split(',');
                    string[] BmMc = context.Request.Form["BmMc"].ToString().Split(',');
                    int  length =Int32.Parse( context.Request.Form["RowLength"].ToString());
                    DUserList user = new DUserList();
                    MUserList Muser = new MUserList();
                    //将数组中的数据遍历插入数据库
                    for (int i = 0; i <length; i  )
                    {                  
                        Muser.NVFID = System.Guid.NewGuid().ToString();
                        Muser.USERCODE = UserCode[i];
                        Muser.USERNAME = UserName[i];
                        Muser.USERPWD = UserPwd[i];
                        Muser.BMMC = BmMc[i];
                        Muser.PHONEIMEI = Phone[i];
                        // user.Insert(Muser);
                        if (user.Insert(Muser))
                        {
                            result = "true";
                        }
                        else
                        {
                            result = "False";
                        }
                    }
              
                }
                catch(Exception ex)
                {
    
                }
                return result;
    
            }

    注意:ajax不能直接将数组直接传递到后台,所以在数组传递之前用Join()方法将数组转换成字符串,在后台获取到字符串之后再用spit()方法进行分割成数组。

    展开全文
  • 1.做数值校验 ,Bigdecimal 数据库获取数据后 和从前台获取数据作比较时(小数) 会出现 数据库取出的数据进度丢失 得到的结果是 false 解决方案 :先进行小数位保留 然后再作比较 compareTo -1:小于 ,...

    1.做数值校验 ,Bigdecimal 在从数据库获取数据后 和从前台获取的数据作比较时(小数) 会出现 数据库取出的数据进度丢失 得到的结果是 false

    解决方案 :先进行小数位保留 然后再作比较

    compareTo  -1:小于    ,0 :等于  1:大于

    2.从mysql中 取Bigdecimal时有概率回事科学计数法 但是如果取出后以toplainstring 可以实现 输出 但是我是直接取 list 然后发数据到前台。没法。只能重新创建Bigdecimal赋值

     

    展开全文
  • SpringBoot动态多数据源 1.简介 SpringBoot静态数据源指的是...动态数据源指的是将数据源信息配置关系型数据库中或者缓存数据库中,项目启动时只初始化一个默认数据源,项目运行过程动态的从数据库中读取数据源信

    SpringBoot动态多数据源

    1.简介

    SpringBoot静态数据源指的是将多个数据源信息配置在配置文件中,在项目启动时加载配置文件中的多个数据源,并实例化多个数据源Bean,再通过分包/Aop达到切换数据源的目的

    如果想要新增或者修改数据源,必须修改配置文件,并修改对应的代码(增加对应的DataSource Bean)重启项目,重新实例化数据源,才能使用

    动态数据源指的是将数据源信息配置在关系型数据库中或者缓存数据库中,在项目启动时只初始化一个默认数据源,在项目运行过程中动态的从数据库中读取数据源信息,实例化为DataSource,并使用该数据源获取连接,执行SQL

    此处研究的ORM框架为Mybatis

    2.实现方法

    动态数据源的实现方法有两种

    2.1 重写DataSource中的getConnection方法

    Mybatis中数据库的连接都是在执行sql的时候才触发并创建连接

    由此可以通过重写数据源的getConnection()方法,当Mybatis需要创建对应的数据库连接时,跟据要使用的数据源,修改当前使用的数据源,达到动态数据源的目的

    2.2 通过AbstractRoutingDataSource类

    AbstractRoutingDataSource类是jdbc提供的轻量级的切换数据源的方案,内部维护了一个数据源的集合,提供了维护这个数据源集合的方法,这样我们在动态的创建完对应的数据源后,就可以通过这个类提供的方法,将数据源维护进这个集合,再通过重写 determineCurrentLookupKey()方法,来告诉 AbstractRoutingDataSource我们要的是哪个数据源,最终达到切换数据源的目的

    3.具体代码

    3.1 方案1:重写DataSource中的getConnection方法

    3.1.1 主配置类 DataSourceConfig

    @Configuration
    @MapperScan(basePackages = "com.zhangyao.springboot.mapper",sqlSessionFactoryRef = "sqlSessionFactory")
    public class DataSourceConfig {
    
        /**
         * 主数据源配置
         * @return
         */
        @Bean(name = "primaryDataSource")
        @Primary
        @ConfigurationProperties(prefix = "spring.datasource.test1")
        public DataSource getDataSource1(){
            HikariDataSource datasource =  DataSourceBuilder.create().type(MyDynamicDataSource.class).build();
            if(datasource==null){
                datasource = new MyDynamicDataSource().initDataSource("default");
            }
            //设置默认的数据源
            DataSourceCache.put("default", datasource);
            ThreadLocalDataSource.setLocalSource("default");
            return datasource;
        }
        @Bean("sqlSessionFactory")
        @Primary
        public SqlSessionFactory getSqlSessionFactory(@Qualifier("primaryDataSource") DataSource primaryDataSource) throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(primaryDataSource);
            return sqlSessionFactoryBean.getObject();
        }
    }
    

    这个类里配置了默认的数据源default,这个数据源是从配置文件中读取到的,并且实例化了Mybatis的SqlSessionFactory,默认注入default数据源

    3.1.2 MyDynamicDataSource 覆盖HikariDataSource的getConnection()

    package com.zhangyao.springboot.config;
    
    import com.zaxxer.hikari.HikariDataSource;
    import com.zhangyao.springboot.domin.Databaseinfo;
    import com.zhangyao.springboot.service.DataBaseService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.support.EncodedResource;
    import org.springframework.core.io.support.PropertiesLoaderUtils;
    
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Map;
    import java.util.Properties;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @author: zhangyao
     * @create:2020-11-03 21:07
     * @Description:
     **/
    public class MyDynamicDataSource extends HikariDataSource {
    
        @Autowired
        DataBaseService dataBaseService;
    
    
    
        /**
         * 定义缓存数据源的变量
         */
        public static final Map<Object, Object> DataSourceCache = new ConcurrentHashMap<Object, Object>();
    
        @Override
        public Connection getConnection() throws SQLException {
            String localSourceKey = ThreadLocalDataSource.getLocalSource();
            HikariDataSource dataSource = (HikariDataSource) DataSourceCache.get(localSourceKey);
            if(dataSource==null){
    	        try {
    	            dataSource = initDataSource(localSourceKey);
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        }
            }
            return dataSource.getConnection();
        }
    
        /**
         * 初始化DataSource
         * 当缓存中没有对应的数据源时,需要去默认数据源查询数据库
         *
         * @param key
         * @return
         */
        public HikariDataSource initDataSource(String key) throws IOException {
            HikariDataSource dataSource = new HikariDataSource();
            if ("default".equals(key)) {
                Properties properties = PropertiesLoaderUtils.loadProperties(new EncodedResource(new ClassPathResource("application.properties"), "UTF-8"));
                dataSource.setJdbcUrl(properties.getProperty("spring.datasource.test1.jdbc-url"));
                dataSource.setUsername(properties.getProperty("spring.datasource.test1.username"));
                dataSource.setPassword(properties.getProperty("spring.datasource.test1.password"));
                dataSource.setDriverClassName(properties.getProperty("spring.datasource.test1.driver-class-name"));
            } else {
                //查询数据库
                ThreadLocalDataSource.setLocalSource("default");
                Databaseinfo dataBaseInfo = dataBaseService.getDataBaseInfo(key);
                dataSource.setJdbcUrl(dataBaseInfo.getUrl());
                dataSource.setUsername(dataBaseInfo.getUserName());
                dataSource.setPassword(dataBaseInfo.getPassword());
                dataSource.setDriverClassName(dataBaseInfo.getDriverClassName());
                ThreadLocalDataSource.setLocalSource(key);
            }
            DataSourceCache.put(key, dataSource);
            return dataSource;
        }
    }
    

    这个类重写了HikariDatasource类的getConnection()方法,当Mybatis使用连接时,就会调用MyDynamicDataSource的getConnection()方法,然后通过获取ThreadLoacal中存放的当前使用的数据源的key,进而从自定义的缓存变量 DataSourceCache 中获取对应的数据源,如果获取不到,就使用默认数据源查询数据库,如果再获取不到,就抛出异常,查询到数据源后,初始化完再放入到缓存中DataSourceCache

    3.1.3 ThreadLocalDataSource 存放当前线程使用数据源的key

    package com.zhangyao.springboot.config;
    
    import lombok.extern.slf4j.Slf4j;
    
    import javax.xml.crypto.Data;
    
    /**
     * ThreadLocal保存数据源的key,并切换清除
     * @author: zhangyao
     * @create:2020-04-07 09:24
     **/
    @Slf4j
    public class ThreadLocalDataSource {
    
        //使用threadLocal保证切换数据源时的线程安全 不会在多线程的情况下导致切换错数据源
        private static final ThreadLocal<String> TYPE = new ThreadLocal<String>();
    
        /**
         * 修改当前线程内的数据源id
         * @param key
         */
        public static void setLocalSource(String key){
            TYPE.set(key);
        }
    
        /**
         * 获取当前线程内的数据源类型
         * @return
         */
        public static String getLocalSource(){
            return TYPE.get();
        }
    
        /**
         * 清空ThreadLocal中的TYPE
         */
        public void clear(){
            TYPE.remove();
        }
    
    }
    

    提供了对ThreadLocal的set/get操作方法,ThreadLocal中存放的是数据源的key,这个key与 MyDynamicDataSource中的DataSourceCache中的key一致,ThreadLocal的作用就是保证在当前线程内可以取到唯一的数据源的key

    3.1.4 DataSourceAop 切面 用于解析请求中的数据源的key

    @Aspect
    @Component
    @Slf4j
    public class DataSourceAop {
        /**
         * 定义切入点
         * 切入点为有该注解的方法
         * 此注解用于数据源TEST1
         */
        @Pointcut("@annotation(com.zhangyao.springboot.annotation.DataSourceServiceAop)")
        public void serviceTest1DatasourceAspect(){};
    
        /**
         * 在切入service方法之前执行
         * 设置数据源
         */
        @Before("serviceTest1DatasourceAspect()")
        public void beforeAspect(){
            log.info("切入方法,开始设置数据源");
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String database_key = attributes.getRequest().getHeader("database_key");
            ThreadLocalDataSource.setLocalSource(database_key);
    
    
        }
        /**
         * 在切入service方法之后执行
         * 设置回默认数据源
         */
        @After("serviceTest1DatasourceAspect()")
        public void afterAspect(){
            log.info("切入方法后,开始切换默认数据源");
            ThreadLocalDataSource.setLocalSource("default");
        }
    }
    

    需要自定义一个注解@DataSourceServiceAop,标识在使用动态数据源的方法上

    这里是跟据前台传输的数据源的key来设置ThreadLocal中的key,如果前台传输的数据源的key不在header中,再跟据实际情况调整

    切完方法之后,切换回default数据源

    3.2 方案2: 通过AbstractRoutingDataSource类

    3.2.1 主配置类 DataSourceConfig

    package com.zhangyao.springboot.config;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import com.zaxxer.hikari.HikariDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import tk.mybatis.spring.annotation.MapperScan;
    
    import javax.sql.DataSource;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    import static com.zhangyao.springboot.config.MyDynamicDataSource.DataSourceCache;
    
    
    /**
     *
     * aop多数据源动态切换配置
     * @author: zhangyao
     * @create:2020-04-06 22:17
     **/
    
    @Configuration
    @MapperScan(basePackages = "com.zhangyao.springboot.mapper",sqlSessionFactoryRef = "sqlSessionFactory")
    public class DataSourceConfig {
    
        /**
         * 主数据源配置
         * @return
         */
        @Bean(name = "primaryDataSource")
        @Primary
        @ConfigurationProperties(prefix = "spring.datasource.test1")
        public DataSource getDataSource1(){
            HikariDataSource datasource =  DataSourceBuilder.create().type(HikariDataSource.class).build();
            //设置默认的数据源
            DataSourceCache.put("default", datasource);
            ThreadLocalDataSource.setLocalSource("default");
            return datasource;
        }
        /**
         * 动态装配所有的数据源
         * @param primaryDataSource
         * @return
         */
        @Bean("dynamicDataSource")
        public DynamicChangeDataSourceConfig setDynamicDataSource(@Qualifier("primaryDataSource") DataSource primaryDataSource){
            //定义所有的数据源
            Map<Object,Object> allDataSource = new HashMap<Object, Object>();
            //把配置的多数据源放入map
            allDataSource.put("default", primaryDataSource);
    
            //定义实现了AbstractDataSource的自定义aop切换类
            DynamicChangeDataSourceConfig dynamicChangeDataSourceConfig = new DynamicChangeDataSourceConfig();
            //把上面的所有的数据源的map放进去
            dynamicChangeDataSourceConfig.setTargetDataSources(allDataSource);
            //设置默认的数据源
            dynamicChangeDataSourceConfig.setDefaultTargetDataSource(primaryDataSource);
    
            return dynamicChangeDataSourceConfig;
        }
    
        @Bean("sqlSessionFactory")
        @Primary
        public SqlSessionFactory getSqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dynamicDataSource);
            return sqlSessionFactoryBean.getObject();
        }
    
    }
    

    与方案一一样需要先实例化默认数据源default,但是MyBatis的SqlSessionFactory中注入的就不是默认数据源了,而是AbstractRoutingDataSource的实现类,并将默认数据源放入AbstractRoutingDataSource的targetDataSources中

    3.2.2 DynamicChangeDataSourceConfig AbstractRoutingDataSource的子类

    package com.zhangyao.springboot.config;
    
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    /**
     * 继承AbStractRoutingDataSource
     * 动态切换数据源
     * @author: zhangyao
     * @create:2020-04-07 09:23
     **/
    public class DynamicChangeDataSourceConfig extends AbstractRoutingDataSource {
    
        @Override
        protected Object determineCurrentLookupKey() {
            return ThreadLocalDataSource.getLocalSource();
        }
    
    }
    

    重写了AbstractRoutingDataSource的determineCurrentLookupKey方法,改为返回ThreadLocal中的数据源的key

    3.2.3 ThreadLocalDataSource 存放当前线程使用数据源的key

    与方案1一摸一样

    3.2.3 DataSourceAop 切面 用于解析请求中的数据源的key

    package com.zhangyao.springboot.config;
    
    import com.zaxxer.hikari.HikariDataSource;
    import com.zhangyao.springboot.domin.Databaseinfo;
    import com.zhangyao.springboot.service.DataBaseService;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.annotation.Resource;
    
    import static com.zhangyao.springboot.config.MyDynamicDataSource.DataSourceCache;
    
    /**
     * @author: zhangyao
     * @create:2020-04-07 11:20
     **/
    @Aspect
    @Component
    @Slf4j
    public class DataSourceAop {
        @Autowired
        DataBaseService dataBaseService;
    
        @Resource(name = "dynamicDataSource")
        DynamicChangeDataSourceConfig dynamicChangeDataSourceConfig;
        /**
         * 定义切入点
         * 切入点为有该注解的方法
         * 此注解用于数据源TEST1
         */
        @Pointcut("@annotation(com.zhangyao.springboot.annotation.DataSourceServiceAop)")
        public void serviceTest1DatasourceAspect(){};
    
        /**
         * 在切入service方法之前执行
         * 设置数据源
         */
        @Before("serviceTest1DatasourceAspect()")
        public void beforeAspect(){
            log.info("切入方法,开始设置数据源");
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String database_key = attributes.getRequest().getHeader("database_key");
            initDataSource(database_key);
            ThreadLocalDataSource.setLocalSource(database_key);
    
    
        }
        /**
         * 在切入service方法之后执行
         * 设置回默认数据源
         */
        @After("serviceTest1DatasourceAspect()")
        public void afterAspect(){
            log.info("切入方法后,开始切换默认数据源");
            ThreadLocalDataSource.setLocalSource("default");
        }
    
    
        public HikariDataSource initDataSource(String key) {
            HikariDataSource dataSource = new HikariDataSource();
            if ("default".equals(key)) {
                 Properties properties = PropertiesLoaderUtils.loadProperties(new EncodedResource(new ClassPathResource("application.properties"), "UTF-8"));
                dataSource.setJdbcUrl(properties.getProperty("spring.datasource.test1.jdbc-url"));
                dataSource.setUsername(properties.getProperty("spring.datasource.test1.username"));
                dataSource.setPassword(properties.getProperty("spring.datasource.test1.password"));
                dataSource.setDriverClassName(properties.getProperty("spring.datasource.test1.driver-class-name"));
            } else {
                //查询数据库
                ThreadLocalDataSource.setLocalSource("default");
                Databaseinfo dataBaseInfo = dataBaseService.getDataBaseInfo(key);
                dataSource.setJdbcUrl(dataBaseInfo.getUrl());
                dataSource.setUsername(dataBaseInfo.getUserName());
                dataSource.setPassword(dataBaseInfo.getPassword());
                dataSource.setDriverClassName(dataBaseInfo.getDriverClassName());
                DataSourceCache.put(key, dataSource);
                dynamicChangeDataSourceConfig.setTargetDataSources(DataSourceCache);
                dynamicChangeDataSourceConfig.afterPropertiesSet();
                ThreadLocalDataSource.setLocalSource(key);
            }
            return dataSource;
        }
    }
    

    当进入切点方法后,获取到前台传输的数据源key,去缓存中取,如果取不到,就查询数据库,并实例化放置到缓存中,并设置ThreadLocal的key为前台传输的key

    4.总结

    其实两种方案本质上是一种方法,第一种方法相当于自己把AbstractRoutingDataSource这个类的功能再手动的实现一遍,好处是更加灵活,可以针对自己的业务做定制

    展开全文
  • 1. 先去数据库中查值,查询整个数据表,结果为二维数组。 $project = M(project); $cell = $project->where(array('status'=>1))->order(id desc)->select(); //var_dump($cell); $this->assign('cell',$cell);...
  • 2、php连接数据库获取数据库的信息放入json_encode($css);{文件为:db.php} $host="localhost"; $username="root"; $password="root"; $dbName="baixing"; $port=3306; $conn=new mysqli($host,$username,$pas
  • 今天这篇主要讲从后台获取数据库数据在前台显示(类似背单词小程序的点击下一个会显示数据库的下一个数据) 1.效果图: 2.wxml文件: <view class="container"> <text>{{id}}</text>...
  • 数据库数据转成Json并返回到前台 查看
  • 使用websocket+mysql+java8+Tomcat8技术,管理端动态添加数据到数据库,用户端实时刷新新添加的数据
  • 前言 上一篇博客我把微信小程序云开发数据库操作(增删改查)的实现方法都已经分享出来啦,可以...js文件调用云函数的逻辑代码并接收数据库获取到数据,以便后面进行渲染 js文件 获取到数据之后下一步就是页面渲
  •  //从数据库获得数据  $sql='SELECT * FROM lys_news order by mid desc';  $_GET;  $r=$db->query($sql);  // 得到一个二维数  $result= array();  while ($row = $r->fetch_array(MYSQLI_ASSOC)) {...
  • 直接web.xml设置设置全局的过滤就可以解决器解决数据库数据显示页面乱码问题 CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 forceEncoding ...
  • 利用servlet获取数据库数据

    千次阅读 2019-10-25 00:09:50
    数据库数据到前台 数据库建表:(图片的话存放第一个里面,自己选图片地址添加数据库) CREATE TABLE COURSE( COURSE_imgurl VARCHAR(150), COURSE_title VARCHAR(150), COURSE_num INT(255), COURSE_...
  • 开发工具IDEA 废话不多说直接看效果图 柱状图 折线图 饼图 上面三张图是早期的,博客里给出源码实际效果如下 楼主已将页面整合后台,还是一样的实现过程 1:创建表 2:搭建项目 项目结构图 3:实体类entity package ...
  • 前台的表单分了多页,怎么填写完成后再一起存入数据库,怎么将 填写的数据存入session里或者有什么方法能将数据存入数据库, controller该怎么写,最好有示例代码,没用过这东西,实在头大
  • SSM获取数据库数据的两种方法

    千次阅读 2019-09-04 18:48:15
    DataSource(连接数据库)–>SqlSessionFactory–>SqlSessionTemplate–>调用里面的发方法 2.mybaties特有的方法 写一个关于dao的接口,配置文件实现接口里的方法。 写一个biz(功能相当于dao),写接口,...
  • 浏览器和服务器之间建立WebSocket双工连接,启动一个线程,设置私有变量数据修改时间,循环读取数据库实时表某个传感器的数据修改时间,与私有变量进行对比,如果相同则不做任何改动,若不同,则把查询的时间...
  • 主要介绍了django之从html页面表单获取输入的数据实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 大数据时代,凡是AI类项目的落地,都需要具备数据、算法、场景、计算力四个基本元素,缺一不可。...目前,外界与业内很多人对于数据中台的理解存在误区,一直只是强调技术的作用,强调技术对于业务的推动作用
  • MySQL数据库获取指定行的数据信息,limit方法的简单使用(个人心得)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 64,464
精华内容 25,785
关键字:

如何在前台获取到数据库中的数据