ssm框架

在整合三大框架SSM , 即 Spring 和 SpingMVC和Mybatis的时候,搭建项目最初需要先配置好配置文件.

有人在刚开始学习框架的时候会纠结项目搭建的顺序,因为频繁的报错提示是会很影响强迫症和编程心情的,这里分享我在构建项目时候的心得和配置文件的编写

首先你需要知道你的项目需要哪些结构,我们这里举一个基于Java的简单Web项目,实现最简单的功能,我需要Mybatis来进行持久层的控制,那么Mybatis就需要配置文件,我需要Dao层提供数据,那就需要Dao层的配置文件,我还需要服务层,那就需要Service的配置文件,再其次,我在进行一些选项的时候需要开启事务操作,那就需要事务的配置文件,最后是整合的SpringMVC的配置文件.

那么综上而言 我们把文件列表可以罗列出来:

Mybatis的配置文件: sqlMapConfig.xml

Spring的配置文件: applicationContext-dao.xml

applicationContext-service.xml

applicationContext-tx.xml

springmvc.xml

外部的Properties配置文件: jabc.properties 和 log4j.properties

学会配置xml文件是学习spring的基础,需要长时间的练习来达到熟练的效果.

我们先编写jabc.properties的配置文件:

这里使用的是阿里云的连接池Druid:

复制代码
druid.url=jdbc:mysql://localhost:3306/egoubuy?characterEncoding=utf-8
druid.password=root
druid.username=root
druid.driverClassName=com.mysql.jdbc.Driver
druid.initialSize=5
druid.minIdle=3
druid.maxActive=20

复制代码
再编写log4j.properties:

复制代码
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
复制代码
现在,我们开始编写SSM的xml

首先配置Mybatis的配置文件

复制代码
<?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>
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">

    </plugin>
</plugins>
</configuration>

复制代码
然后配置Spring下的Dao配置文件

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!--加载外部属性配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${druid.url}"></property>
        <property name="username" value="${druid.username}"></property>
        <property name="password" value="${druid.password}"></property>
        <property name="driverClassName" value="${druid.driverClassName}"></property>
        <property name="initialSize" value="${druid.initialSize}"></property>
        <property name="minIdle" value="${druid.minIdle}"></property>
        <property name="maxActive" value="${druid.maxActive}"></property>
    </bean>

    <!--配置sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置mybatis配置文件,这里的名称一定要对应-->
        <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml"></property>
        <!--配置数据源对象-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>


    <!--批量配置mapper接口:
    通过mapper扫描器,扫描某个包下的所有mapper接口,批量加载配置
    -->

    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--设置需要扫描的包-->
        <property name="basePackage" value="这里是你需要的被扫描的包"></property>
        <!--配置sqlSessionFactory对象-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
</beans>

复制代码
再编写service的配置文件

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--扫描service包,将service包下添加@Servcie注解的类添加到容器中-->
    <context:component-scan base-package="这里是你编写的service的包"></context:component-scan>
</beans>

复制代码
由于需要开启事务,再编写事务的配置文件

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd
 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">

    
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置通知-->
    <tx:advice id="tx_advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="add*"></tx:method>
            <tx:method name="update*"></tx:method>
            <tx:method name="modify*"></tx:method>
            <tx:method name="delete*"></tx:method>
            <tx:method name="remove*"></tx:method>
            <tx:method name="get*" read-only="true"></tx:method>
            <tx:method name="select*" read-only="true"></tx:method>
            <tx:method name="query*" read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>

    <!--配置切面-->
    <aop:config>
        <aop:advisor advice-ref="tx_advice" pointcut="execution(* 这里一般写service的类所在包.*.*(..))"></aop:advisor>
    </aop:config>
</beans>

复制代码
最后是编写springmvc的配置文件

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    

    <!--配置扫描controller包下的所有以@Controller注解修饰的类-->
    <context:component-scan base-package="这里是控制器的所在类,你可以放一起写,也可以分开写"></context:component-scan>

    <!--配置注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--放行静态资源文件-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!--视图解析器-->
    <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--配置文件上传解析器 吐过需要,你就打开注释commons-io commons-fileupload-->
    <!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10000000"></property></bean>--
        </beans>

复制代码
Java代码部分不做展示没有意义,当你在写项目的时候也要注意web.xml的配置,前提是web的项目

java<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <!--配置post提交中文乱码的过滤器-->
  <filter>
    <filter-name>characterEncoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <url-pattern>*</url-pattern>
  </filter-mapping>

  <!--给监听器指定初始化参数,用于加载spring配置文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <!--classpath:spring/applicationContext-dao.xml,classpath:spring/applicationContext-tx.xml,classpath:spring/applicationContext-servcie.xml-->
    <param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>

  <!--配置监听器 加载spring配置文件-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!--配置前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

1. mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。

采用 ORM 思想解决了实体和数据库映射的问题,**对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
JDBC

public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","ro
ot", "root");
//定义 sql 语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理 statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的
参数值
preparedStatement.setString(1, "王五");
//向数据库发出 sql 执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
 System.out.println(resultSet.getString("id")+"
 "+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
} }
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
} }
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } } }
上边使用 jdbc 的原始方法(未经封装)实现了查询数据库表记录的操作。
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200225235030250.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxMzIzMg==,size_16,color_FFFFFF,t_70)
````java<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper 
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.itheima.dao.IUserDao">
<!-- 配置查询所有操作 --> <select id="findAll" resultType="com.itheima.domain.User">
select * from user
</select>
</mapper>

编写 SqlMapConfig.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>
<!-- 配置 mybatis 的环境 --> <environments default="mysql">
<!-- 配置 mysql 的环境 --> <environment id="mysql">
<!-- 配置事务的类型 --> <transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源(连接池) --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ee50"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<!-- 告知 mybatis 映射配置的位置 --> <mappers> <mapper resource="com/itheima/dao/IUserDao.xml"/>
</mappers>
</configuration>

MyBatis优点

1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:
在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
解决:
将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
3.向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:
Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的
类型。
4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对
象解析比较方便。
解决:
Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的
类型。

resultType和resultMap

功能类似 ,都是返回对象信息 ,但是resultMap要更强大一些 ,可自定义。因为resultMap要配置一下,表和类的一一对应关系,所以说就算你的字段名和你的实体类的属性名不一样也没关系,都会给你映射出来,但是,resultType就比较鸡肋了,必须字段名一样,比如说 cId和c_id 这种的都不能映射 。下面介绍几个常用的映射关系:
在这里插入图片描述主配置文件
要使用的properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root
jdbc.password=admin

一个主配置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">
<!-- mybatis的主配置文件 -->
<configuration>
	<!--配置参数-->
    <settings>
        <!--开启Mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"></setting>
        <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!--配置properties:
        可以在标签内部链接的数据库的信息,也可以通过属性引用外部配置文件的信息
            resource属性:(常用)
                用于指定配置文件的位置,是按照类路径的写法来写的,并且比逊存在类路径下
            url属性:
                要求按照url的写法来写地址(文件协议)
                url:同一资源定位符,可唯一表示一个资源的位置
    -->

    <!--1. 使用url得到4个基本信息 文件协议,这三中方式使用时任意选一种就好-->
    <properties url="file:///D:/IntelliJIDEAWorkProject/mybatiss_Test/day01_03_crud/src/main/resources/jdbcConfig.properties"></properties>

    <!--2. 外部配置文件得到4个基本信息,这三中方式使用时任意选一种就好-->
    <properties resource="jdbcConfig.properties"></properties>

    <!--3. 配置连接数据库的4个基本信息,这三中方式使用时任意选一种就好-->
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/gq_day18"/>
        <property name="username" value="root"/>
        <property name="password" value="admin"/>
    </properties>

    <!--使用typeAliases配置别名,他只能配置domain中类的别名-->
    <typeAliases>
        <!--typeAlias用于配置别名,type属性指定的实体类全限定类名,alias属性指定别名,就像int/INT/Intager等等那样使用了-->
        <typeAlias type="cn.itcast.domain.User" alias="user"></typeAlias>
        <typeAlias type="cn.itcast.domain.User" alias="UESR"></typeAlias>

        <!--如果想配置多一点,使用这个麻烦了,package用于指定要配置别名的包,当指定之后该包下的实体类都会被注册别名,并且类名就是别名,不再区分大小写-->
        <package name="cn.itcast.domain"/>
    </typeAliases>
    
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 1. 硬编码 配置连接数据库的4个基本信息 -->
                <!--<property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/gq_day18"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>-->

                <!--2. 直接引用上面properties标签的内容-->
                <!-- <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="{username}"/>
                <property name="password" value="${password}"/>-->

                <!--3. 引用使用了resource或url属性的properties标签  外部配置文件-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>

            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <!--使用注解时-->
        <mapper class="cn.itcast.dao.UserDao"/>
        
        <!--使用xml文件时-->
        <mapper resource="cn/itcast/dao/UserDao.xml"/>
        
        <!--package标签在这里是用于指定dao接口所在的包,当指定之后就不在写mapper以及resource或者class-->
        <package name="cn.itcast.dao"/>
    </mappers>
</configuration>

configuration:这个标签代表了这是mybatis的住配置文件
settings:配置一些mybatis的参数,例如:开启Mybatis支持延迟加载,name属性:“lazyLoadingEnabled” 属性value值:true,例如:属性name值:“cacheEnabled” ,属性value值:“true"开启mybatis的二级缓存功能。
environments:配置数据库环境,可以有默认值default
environment:具体的一个数据库环境,以mysql为例
transactionManager:事务类型,我们一般是JDBC
dataSource:配置数据源,我们的数据源一般有三类POOLED、UNPOOLED、JNDI,mybatis框架内部自己依照池的原理实现了自己的连接池,所以我们一般选用POOLED。
property:这个标签是配置参数,比较常见,有name、value属性,这里还可以引入外部文件properties文件,value可使用el表达式。
properties:可用来引入外部配置文件,有resource()引当前类路径下文件)和url(以文件协议引入外部文件)两个属性,例如resource属性值为"jdbcConfig.properties”
mappers:指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 ,属性是resource时表示对应接口使用的是xml配置,属性是class时表示对应接口使用的是注解配置。
typeAliases:使用typeAliases配置别名,他只能配置domain中类的别名
typeAlias:typeAliases的子标签,用于配置别名,type属性指定的实体类全限定类名,alias属性指定别名,就像int/INT/Intager等等那样使用了
package:用于指定要配置别名的包,当指定之后该包下的实体类都会被注册别名,并且类名就是别名,不再区分大小写

一个实体Dao的Mapper配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--一定要说明名称空间,mybatis才能明白你这个类是给那个接口的实现-->
<mapper namespace="cn.itcast.dao.UserDao">
    <!--配置查询结果的列名和实体类属性名对应关系-->
    <resultMap id="userMap" type="cn.itcast.domain.User">
        <!--主字段对应-->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="name"></result>
        <result property="userAddress" column="adress"></result>
        <result property="userbrithday" column="birthday"></result>
    </resultMap>
	
	 <!--开启user支持二级缓存-->
     <cache/>

<!--=============================================================================-->
    <!--查询所有-->
    <select id="findAll" resultType="cn.itcast.domain.User">
        select * from user
    </select>

    <!--保存用户-->
    <insert id="insertUser" parameterType="cn.itcast.domain.User">
        <!--keyproperty是实体类的属性名,keycolumn是数据库表中的列名,order是执行时机-->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id()
        </selectKey>
        insert into user (name,gender,age,address,qq,email,username,password)values (#{name},#{gender},#{age},#{address},#{qq},#{email},#{username},#{password})
    </insert>

    <!--删除用户-->
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{uid}
    </delete>

    <!--更新-->
    <update id="updateUser" parameterType="cn.itcast.domain.User">
        update user set name=#{name},gender=#{gender},age=#{age},address=#{address},
        qq=#{qq},email=#{email},username=#{username},password=#{password} where id=#{id}
    </update>

    <!--根据id查询用户-->
    <select id="findUserById" parameterType="int" resultType="cn.itcast.domain.User">
        select * from user where id=#{id}
    </select>

    <!--模糊查询(姓名)-->
    <select id="findUserByName" parameterType="string" resultType="cn.itcast.domain.User">
        select * from user where name like #{name}
    </select>

    <!--聚合函数-->
    <select id="findCount" resultType="int">
        select count(*) from user
    </select>

    <!--根据queryVo为条件查询-->
    <select id="findUserByVo" parameterType="cn.itcast.domain.QueryVo" resultType="cn.itcast.domain.User">
        select * from user where name like #{user.name}
    </select>
</mapper>

mapper :一个接口对应的配置文件,属性namespace说明了是哪个具体的接口
resultMap :配置查询结果的列名和实体类属性名对应关系,我们一直是建议实体类属性名、和数据库表名一致的,但是难免有可能你的实体类属性名、和数据库表名不一致这个标签就是解决这个问题,定义完成这个后,在后面的CRUD操作中就可以利用属性id使用这个类型了,
id : resultMap的子标签,用于主键
result : resultMap的子标签,用于普通键
collection : resultMap的子标签,用于一个实体类中包含另一个实体而且可能是多个的情况,一般用于表与表直接是一对多,多对多关系的情况
association : resultMap的子标签,用于一个实体类中包含另一个实体而且该实体对象是一个的情况,一般用于表与表直接是一对一,多对一关系的情况
constructor : resultMap的子标签,不常用
discriminator : resultMap的子标签,不常用
cache:表示这个Mapper对应的接口是支持二级缓存的
select、update、delete、insert:CRUD这里不在说明了
id:CRUD的属性对应接口中的那个方法,和mapper 的namespace值组合在一起,mybatis的代理对象就知道找个方法。
parameterType:参数类型,如果是已经在主配置文件中的package 标签配置了这个实体类型的包名,那么就不用关心大小写问题了
resultType:返回结果类型
useCache:该条sql语句支持二级缓存功能,boolean类型
resultMap:可以使用定义的
selectKey : select last_insert_id()语句的专属标签,可以用来为默认增长主键赋值。
keyproperty:selectKey 的属性,是实体类的属性名
keycolumn:selectKey 的属性,是数据库表中的列名
order:selectKey 的属性,是执行时机

<select id="findUserByCondition" resultMap="userMap" parameterType="cn.itcast.domain.User">
        <!--动态sql方式1-->
        select * from user where 1=1
        <if test="name!=null">
            and name=#{name}
        </if>
        <if test="gender!=null">
            and gender=#{gender}
        </if>-->

        <!--动态sql方式2  不用写1=1 -->
        select * from user
        <where>
            <if test="name!=null">
                and name=#{name}
            </if>
            <if test="gender!=null">
                and gender=#{gender}
            </if>
        </where>
    </select>
<select id="findUserByIds" resultMap="userMap" parameterType="queryvo">
    select * from user
    <where>
        <if test="ids !=null and ids.size()>0">
            <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                #{uid}
            </foreach>
        </if>
    </where>
</select>
<!--定义重复sql语句-->
<sql id="defaultSql">
    select * from user
</sql>

<!--查询所有-->
<select id="findAll" resultType="cn.itcast.domain.User">
    <include refid="defaultSql"/>
</select>

foreach标签,可以执行查询in类型sql,例如:select * from user where id in (5,6,7),属性collection就是那个集合,属性open就是开始的部分,属性close就是结束,item就是遍历名,separator是分隔符,标签体内容#{item名}
if标签:判断,test属性是判断条件
sql标签:可以定义一些可以重用的sql语句,并且起一个名字,就可以用这个名字直接使用了

Spring :

自定义json:

  return "{\"code\":\""+code+ "\"" +
                ",\"lat\":\""+lat+"\"" +
                ",\"lon\":\""+lon+"\"" +
                ",\"routeanalysisurl\":\""+routeanalysisurl+"\"" +
                ",\"tunnelurl\":\""+tunnelurl+"\"" +
                ",\"coalname\":\""+coalname+"\"" +
                ",\"updatetime\":\""+updatetime+"\"" +
                ",\"csMineShortname\":\""+csMineShortname+"\"" +
                "}";

处理list集合java代码分组并且取最新时间:

 public Page<CspHisminertrack> getNewPeoLocThreeHistory(CspHisminertrack cspHisminertrack,HttpServletRequest request) throws ParseException {
        List<CspHisminertrack> peoLocThreeHistory = dao.getPeoLocThreeHistory(cspHisminertrack);
        Page<CspHisminertrack> page = new Page<>(request);

        //根据人名和地址名分组,key值为dbfnRywz1.getPsPersonName() + dbfnRywz1.getPsStationLocation()字符串
        Map<String, List<CspHisminertrack>> collect = peoLocThreeHistory.stream().collect(Collectors.groupingBy(item -> item.getCsminecode() + item.getPspersoncard()));
        List<CspHisminertrack> dbfnRywzList2 = new ArrayList<>();
        //遍历result1的key值,key为人名+地址的字符串
        for(String s : collect.keySet()){
            //根据对象的csdatatime排序
            Collections.sort(collect.get(s),(CspHisminertrack o2, CspHisminertrack o1) -> o1.getCsdatatime().compareTo(o2.getCsdatatime()));
            //拿出第一个对象,即为时间最新的那个
            String psmineouttime = collect.get(s).get(0).getPsmineouttime();
            if ("1900-01-01 00:00:00".equals(psmineouttime)) {
                String psmineentertime = collect.get(s).get(0).getPsmineentertime();
                String csdatatime = collect.get(s).get(0).getCsdatatime();
                long[] difday = GetTimes.getDistanceTimes(psmineentertime,csdatatime);//返回值为:{天, 时, 分,秒}
                String str =difday[1]+"时"+difday[2]+"分";
                collect.get(s).get(0).setTotaltime(str);
                collect.get(s).get(0).setPsmineouttime("————");
            }
            else {
                String psmineentertime = collect.get(s).get(0).getPsmineentertime();
                String csdatatime = collect.get(s).get(0).getCsdatatime();
                long[] difday = GetTimes.getDistanceTimes(psmineentertime,psmineouttime);//返回值为:{天, 时, 分,秒}
                String str =difday[1]+"时"+difday[2]+"分";
                collect.get(s).get(0).setTotaltime(str);
            }
            dbfnRywzList2.add(collect.get(s).get(0));
        }
        List<CspHisminertrack> cspHisminertracks = PageUtil.pageMath(dbfnRywzList2, request);

        page.setList(cspHisminertracks);
        page.setTotal(dbfnRywzList2.size());
        return page;
    }

sql

SELECT DISTINCT
	(
	SELECT COUNT
		( ID ) leaderintimes 
	FROM
		(
		SELECT T
			.ID,
			T.cs_mine_code,
			T.cs_data_time,
			T.ps_person_card,
			M.ps_person_post,
			T.ps_mine_entertime,
			T.ps_mine_outtime 
		FROM
			dbfn_locdaydata
			T LEFT JOIN dbfn_ryry M ON T.ps_person_card = M.ps_person_card 
		) AS loc 
	WHERE
		ps_person_post LIKE'%矿领导%' 
		AND cs_mine_code ='610200001' 
		AND cs_data_time LIKE concat ( '%2020-08-16%' ) 
	),
	(
	SELECT COUNT
		( ID ) minerintimes 
	FROM
		(
		SELECT T
			.ID,
			T.cs_mine_code,
			T.cs_data_time,
			T.ps_person_card,
			M.ps_person_post,
			T.ps_mine_entertime,
			T.ps_mine_outtime 
		FROM
			dbfn_locdaydata
			T LEFT JOIN dbfn_ryry M ON T.ps_person_card = M.ps_person_card 
		) AS loc 
	WHERE
		ps_person_post NOT LIKE'%矿领导%' 
		AND cs_mine_code = '610200001'
		AND cs_data_time LIKE concat ( '%2020-08-16%' ) 
	),
	(
	SELECT SUM
		(
			date_part( 'HOUR', ps_mine_outtime :: TIMESTAMP - ps_mine_entertime :: TIMESTAMP ) * 60 + date_part( 'MINUTE', ps_mine_outtime :: TIMESTAMP - ps_mine_entertime :: TIMESTAMP ) 
		) leaderintotaltime 
	FROM
		(
		SELECT T
			.ID,
			T.cs_mine_code,
			T.cs_data_time,
			T.ps_person_card,
			M.ps_person_post,
			T.ps_mine_entertime,
			T.ps_mine_outtime 
		FROM
			dbfn_locdaydata
			T LEFT JOIN dbfn_ryry M ON T.ps_person_card = M.ps_person_card 
		) AS loc 
	WHERE
		ps_person_post LIKE'%矿领导%' 
		AND cs_mine_code ='610200001' 
		AND cs_data_time LIKE concat ( '%2020-08-16%' ) 
	),
	(
	SELECT SUM
		(
			date_part( 'HOUR', (case when ps_mine_outtime = '1900-01-01 00:00:00' then cs_data_time else ps_mine_outtime  end) :: TIMESTAMP - ps_mine_entertime :: TIMESTAMP ) * 60 + date_part( 'MINUTE', ps_mine_outtime :: TIMESTAMP - ps_mine_entertime :: TIMESTAMP ) 
		) minerintotaltime 
	FROM
		(
		SELECT T
			.ID,
			T.cs_mine_code,
			T.cs_data_time,
			T.ps_person_card,
			M.ps_person_post,
			T.ps_mine_entertime,
			T.ps_mine_outtime 
		FROM
			dbfn_locdaydata
			T LEFT JOIN dbfn_ryry M ON T.ps_person_card = M.ps_person_card 
		) AS loc 
	WHERE
		ps_person_post NOT LIKE'%矿领导%' 
		AND cs_mine_code ='610200001' 
		AND cs_data_time LIKE concat ( '%2020-08-16%' ) 
	) 
FROM
	(
	SELECT T
		.ID,
		T.cs_mine_code,
		T.cs_data_time,
		T.ps_person_card,
		M.ps_person_post,
		T.ps_mine_entertime,
		T.ps_mine_outtime 
	FROM
		dbfn_locdaydata
	T LEFT JOIN dbfn_ryry M ON T.ps_person_card = M.ps_person_card 
	) AS loc

动态拼接url

public static void main(String[] args) {
       //http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
        StringBuffer str =new StringBuffer();
        String url ="http://www.aspxfans.com:8080/news/index.asp?";
        String boardID="1";
        String ID="1";
        String page="1";
        System.out.println();
        if(boardID.length()>0&&!("null".equals(boardID))){
            str.append("boardID="+boardID+"&");
        } if(boardID.length()>0&&"null".equals(ID)){
            str.append("ID="+ID+"&");
        } if(boardID.length()>0&&"null".equals(page)){
            str.append("page="+page+"#");
        }
        url += str.deleteCharAt(str.length()-1).toString();
        System.out.println(url);

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值