当前位置:网站首页>SSM details
SSM details
2022-06-09 09:38:00 【Xiaoxiao is not called Xiaoxiao】
MyBatis
Build an operating environment
1、--> Import jar package , Include mybatis The core and dependent packages and jdbc Connection package 2、--> To configure mybatis.xml file <?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> <!-- Set database connection parameters --> <properties resource="jdbc.properties"> <!-- If an external profile is imported , No separate configuration is required property label --> <property name="username" value="user_name"/> <property name="password" value="123456"/> </properties> <!-- Set up logs --> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <typeAliases> <!-- Alias a single entity class --> <!--<typeAlias type="com.yjd.pojo.Flower" alias="f"></typeAlias>--> <!-- Set an alias for the entity class under the entire package , The alias under the package is the class name , Case insensitive --> <package name="com.yjd.pojo"/> </typeAliases> <!-- To configure mybatis Database connection environment in --> <environments default="mysql"> <environment id="mysql"> <!-- Configure transactions , And jdbc Consistent transactions in --> <transactionManager type="JDBC"></transactionManager> <!-- Dynamic configuration of database connections driver、url、username、password--> <!-- Database connection parameter acquisition order : 1、 stay properties The attributes specified in the body of the element are read first . 2、 And then according to properties In the element resource Property reads the properties file under the classpath or by url Property to read the property file , And overrides the read property of the same name . 3、 Finally, read the properties passed as method parameters , And overrides the read property of the same name . qlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props); // ... or ... SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props); --> <dataSource type="POOLED"> <!-- You can specify default values for placeholders , If the specific value cannot be read , The default value is used <property name="username" value="${username:my_user}"/> Default off state , Can be found in properties Enable... In the tag <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> --> <property name="driver" value="${mysql_driver}"/> <property name="url" value="${mysql_url}"/> <property name="username" value="${mysql_username}"/> <property name="password" value="${mysql_password}"/> </dataSource> </environment> </environments> <!-- scanning FlowerMapper.xml Can be parsed and used --> <mappers> <!-- Separate classes for the package --> <mapper resource="com/yjd/mapper/FlowerMapper.xml"></mapper> <mapper resource="com/yjd/mapper/FlowerMapper2.xml"></mapper> <mapper resource="com/yjd/mapper/FlowerMapper3.xml"></mapper> <!-- Set all classes under the package to be scanned --> <package name="com.yjd.mapper"/> </mappers> </configuration> 3、--> Configure multiple persistence layers mapper.xml, Such as FlowerMapper.xml <?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"> <!-- Locate the operating position --> <mapper namespace="Flower.a"> <!-- The tag represents the operation type id Represents the method name resultType Represents the return value type , Collection, write generics directly parameterType Parameter type can be omitted --> <select id="selectList" resultType="Flower"> select * from flower </select> <select id="selectOne" resultType="Flower"> select * from flower where fid=29 </select> <select id="selectMap" resultType="Map"> select * from flower </select> <!-- Parameters of the receiving Basic data type or String Use param1 When an entity class object is used, the attribute name of the object is used #{ Property name } One Map Use... When assembling objects Map Medium key #{ key} --> <!-- When receiving parameters, you can use ${ param1/ Property name /key} Use $ Equivalent to string splicing , So you need to pay attention to the format of splicing "' flower '" Use # Equivalent to using a placeholder --> <!-- Single parameter --> <select id="selectOne1" resultType="Flower"> select * from flower where fid=#{ param1} </select> <!-- Single entity class object parameters --> <select id="selectOne2" resultType="Flower"> select * from flower where fid=#{ fid} and fname=#{ fname} </select> <!-- Single Map Set parameters --> <select id="selectOne3" resultType="Map"> select * from flower where fid=#{ a} and fname=#{ b} </select> <!-- Fuzzy query concat Splicing / After splicing, it will be transferred --> <select id="selectOne4" resultType="Flower"> select * from flower where fname like concat('%',#{ param1},'%') </select> //crud <insert id="insertOne"> insert into flower values(default,#{ fname},#{ price},#{ production}) </insert> <delete id="deleteOne"> delete from flower where fid=#{ param1} </delete> <update id="updateOne"> update flower set fname=#{ fname} where fid=#{ fid} </update> <select id="selectList" resultType="flower"> select * from flower </select> </mapper> 4、--> To configure log4j.properties file log4j.rootLogger=error,logfile,stdout // Set up log Print sql Statement ,Flower by mapper.xml in namespace Property value log4j.logger.Flower=debug log4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=E:/Object/logs/log4j.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d{ yyyy-MM-dd hh:mm:ss} %l %F %p %m%n log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout 5、--> To configure jdbc.properties file --> And jdbc The database connection is the same 6、--> Use mybatis Do the operation of adding, deleting, modifying and checking package com.yjd.text; import com.yjd.pojo.Flower; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author: Ada * @date: 2021/6/2 10:23 */ public class Test { public static void main(String[] args) throws IOException { // establish SqlSession object // analysis xml File configuration information InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml"); // get SqlSessionFactory Factory object SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); // get SqlSession object SqlSession sqlSession = build.openSession(); // There are three ways to query List<Flower> list = sqlSession.selectList("Flower.a.selectList"); System.out.println(list); Flower one = sqlSession.selectOne("Flower.a.selectOne"); System.out.println(one); //key For database fields Map<Object, Object> map = sqlSession.selectMap("Flower.a.selectMap", "fid"); System.out.println(map); // Passing a single parameter Flower flower = sqlSession.selectOne("Flower.b.selectOne1", 31); System.out.println(flower); // Passing a single entity class object Flower flower1 = new Flower(); flower1.setFid(30); flower1.setFname(" modify "); Flower flower2 = sqlSession.selectOne("Flower.b.selectOne2", flower1); System.out.println(flower2); // Pass a Map aggregate Map<String, Object> map1 = new HashMap<>(); map1.put("a", 29); map1.put("b", " success "); Object o = sqlSession.selectOne("Flower.b.selectOne3", map1); System.out.println(o); // Fuzzy query Object aa = sqlSession.selectOne("Flower.b.selectOne4", " become "); System.out.println(aa); System.out.println("========================"); //CRUD Flower flower3 = new Flower(); flower3.setFname(" newly added "); flower3.setPrice(23); flower3.setProduction(" China "); sqlSession.insert("Flower.c.insertOne", flower3); sqlSession.delete("Flower.c.deleteOne", 32); Flower flower4 = new Flower(); flower4.setFname("change"); flower4.setFid(30); int update = sqlSession.update("Flower.c.updateOne", flower4); System.out.println(update); List<Object> objects = sqlSession.selectList("Flower.c.selectList"); System.out.println(objects); // Add and commit transactions //1、SqlSession sqlSession = build.openSession(true); //2、sqlSession.commit(); sqlSession.commit(); sqlSession.close(); // Introduce local DTD } }
Mapper agent / Interface binding
--> There are two ways for entity class variables to receive data from corresponding columns in the database : Automatic mapping and manual mapping --> Automatic mapping -->mybatis When the entity class variable name defined in is the same as the column name in the database, it is mapped directly and automatically --> There are two ways to manually map -->1、 Not at the same time sql Alias the column name in the statement , The alias is the same as the entity class variable name -->2、 Use the following resultMap label , The primary key column should be written before the non primary key column , Yes dtd Format requirements <mapper namespace="com.yjd.mapper.ClazzMapper"> <select id="selectClazz" resultMap="cla"> select * from clazz where cid=#{ param1} </select> <resultMap id="cla" type="clazz"> <!-- result Apply to non primary key columns 、id Apply to primary key columns column Corresponding database column name property Corresponding entity class attribute name --> <id column="id" property="cid"></id> <result column="name" property="cname"></result> </resultMap> </mapper> --> Defining interfaces public interface FlowerMapper { List<Flower> selectMore(int id, String name); List<Flower> selectMore2(Flower flower1, Flower flower2); // Alias the parameter , Equivalent to transmission Map As a parameter //mapper Methods in interfaces cannot be overloaded List<Flower> selectMore3(@Param("a") int id, @Param("b") String name); } --> Definition mapper.xml --> Parameter passing in dynamic proxy <mapper namespace="com.yjd.mapper.FlowerMapper"> <!-- Get the primary key self increment 1、 Thread unsafe <insert id=" The new method " useGeneratedKeys="true" keyProperty="fid"> useGeneratedKeys: Enable primary key self increment keyProperty: Put the primary key value into the... Of the class fid Properties of the 2、 Thread safety order: Indicates that the <selectKey order="AFTER" keyProperty="fid" resultType="int"> select @@identity </selectKey> --> <!-- The first 1 Ways of planting , It is recommended to use --> <insert id="add" useGeneratedKeys="true" keyProperty="fid"> insert into t_checkgroup(code,name,sex,helpCode,remark,attention) values (#{ code},#{ name},#{ sex},#{ helpCode},#{ remark},#{ attention}) </insert> <!‐‐ The first 2 Ways of planting , Not tested ‐‐> <insert id="add" parameterType="com.yjd.pojo.user"> <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> select LAST_INSERT_ID()/select @@identity </selectKey> insert into t_checkgroup(code,name,sex,helpCode,remark,attention) values (#{ code},#{ name},#{ sex},#{ helpCode},#{ remark},#{ attention}) </insert> <delete id=" Delete method "> </delete> <update id=" Modification method "> </update> <!--paramN Represents the number of parameters passed in , When the parameter is an object , have access to paramN. Variable name get value --> <!-- Pass in two basic data types /String--> <select id="selectMore" resultType="Flower"> select * from flower where fid=#{ param1} and fname=#{ param2} </select> <!-- Pass in two objects , Take the variables in two objects --> <select id="selectMore2" resultType="Flower"> select * from flower where fid=#{ param1.fid} and fname=#{ param2.fname} </select> </mapper> -->mapper Proxy usage public static void main(String[] args) throws IOException { // analysis mybatis.xml file InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml"); // get SqlSessionFactory factory SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); // get SqlSession object SqlSession sqlSession = build.openSession(); // Get interface object FlowerMapper mapper = sqlSession.getMapper(FlowerMapper.class); List<Flower> list = mapper.selectMore(31, "a"); System.out.println(list); Flower flower1 = new Flower(); flower1.setFid(31); Flower flower2 = new Flower(); flower2.setFname("a"); List<Flower> list1 = mapper.selectMore2(flower1, flower2); System.out.println(list1); sqlSession.close(); } -->mappers Set up <mappers> <!-- Scan individual mapper.xml file --> <!--<mapper resource="com/yjd/mapper/FlowerMapper.xml"></mapper>--> <!-- Find all interfaces under the package , find xml With the same name as the interface xml File scanning . Be careful ** Interface and xml Same file name --> <!-- Package based xml scanning 1、 Interface name and xml Consistent names 2、xml in namespace The attribute is consistent with the full path name of the interface 3、crud In punctuation id Property is the same as the method name in the interface --> <!-- Scan all under the package mapper.xml file --> <package name="com.yjd.mapper"/> </mappers>
dynamic SQL
-->OGNL expression <?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.yjd.mapper.FlowerMapper"> <!-- dynamic SQL--> <!--if label 、set label --> <!--set Remove the last tag ,--> <update id="updateOne"> update flower <set> <if test="param2 !=null and param2 != ''"> fname=#{ param2}, </if> <if test="param3 !=null and param3 != ''"> production=#{ param3} </if> where fid=#{ param1} </set> </update> <!--where label --> <!--where Remove the first tag and--> <select id="selectMore4" resultType="Flower"> select * from flower <where> <if test="fname !=null and fname !=''"> and fname=#{ fname} </if> <if test="production !=null and production !=''"> and production=#{ production} </if> </where> </select> <!--chose label 、when label --> <!-- amount to if...else sentence --> <select id="selectMore5" resultType="Flower"> select * from flower <where> <choose> <when test="param1 !=null and param1 !=''"> and fname=#{ param1} </when> <when test="param2 !=null and param2 !=''"> and production=#{ param2} </when> </choose> </where> </select> <!-- Define projection Columns , Use include The memo takes effect as follows <include refid="sql1"/> --> <sql id="sql1"> fid,fname,price </sql> <!-- Prefixes and suffixes --> <update id="update"> update flower <trim prefix="set" suffixOverrides=","> <if test="param2 != null and param2 != ''"> fname=#{ param2} </if> </trim> where fid=#{ param1} </update> <-- foreach The tag traverses the elements in the collection --> <delete id="deleteMore"> delete from flower where fid in <foreach collection="list" item="e" open="(" close=")" separator=","> #{ e} </foreach> </delete> <!-- Fuzzy query bind Splicing --> <!--concat('%',#{ param1},'%')--> <select id="selectMore6" resultType="Flower"> select <include refid="sql1"></include> from flower where fname like <bind name="bind" value="'%'+param1+'%'"/> #{ bind} </select> </mapper>
Multi-table query
--> Business code method for (Student t : list) { int cid = t.getCid(); Clazz clazz = clazzMapper.selectClazz(cid); t.setClazz(clazz); System.out.println(t); } -->N+1 <!--N+1--> <select id="selectAll" resultMap="res1"> select sid,name sname,sex,cid from student </select> <resultMap id="res1" type="student"> <result column="name" property="sname"></result> <result column="cid" property="cid"></result> <association property="clazz" column="cid" javaType="clazz" select="com.yjd.mapper.ClazzMapper.selectClazz"> </association> </resultMap> <!--N+1--> <select id="selectAll" resultMap="res2"> select * from clazz </select> <resultMap id="res2" type="clazz"> <result column="cid" property="cid"></result> <collection property="list" column="cid" ofType="student" select="com.yjd.mapper.StudentMapper.selectMore"> </collection> </resultMap> //N+1 List<Student> list = studentMapper.selectAll(); System.out.println(list); List<Clazz> list1 = clazzMapper.selectAll(); System.out.println(list1); --> Single SQL Multi-table query <!-- Single SQL Multi-table query --> <select id="selectAll2" resultMap="res3"> select * from student s join clazz c on s.cid=c.cid </select> <resultMap id="res3" type="clazz"> <id column="cid" property="cid"></id> <result column="cname" property="cname"></result> <result column="cteacher" property="cteacher"></result> <-- Use together collection label ofType attribute --> <collection property="list" ofType="student"> <id column="sid" property="sid"></id> <result column="name" property="sname"></result> <result column="sex" property="sex"></result> <result column="cid" property="cid"></result> </collection> </resultMap> <!-- Single SQL Multi-table query --> <select id="selectAll2" resultMap="res2"> select * from student s join clazz c on s.cid=c.cid </select> <resultMap id="res2" type="Student"> <id column="sid" property="sid"></id> <result column="name" property="sname"></result> <result column="sex" property="sex"></result> <result column="cid" property="cid"></result> <-- A single object uses association label javaType attribute --> <association property="clazz" javaType="clazz"> <id column="cid" property="cid"></id> <result column="cname" property="cname"></result> <result column="cteacher" property="cteacher"></result> </association> </resultMap> // Single SQL Multi-table query List<Student> list = studentMapper.selectAll2(); System.out.println(list); List<Clazz> list1 = clazzMapper.selectAll2(); System.out.println(list1); --> Set delay loading <settings> <setting name="logImpl" value="LOG4J"/> <!-- Turn on mybatis Middle lazy load --> <setting name="lazyLoadingEnabled" value="true"/> <!-- Turn off lazy loading of each attribute --> <setting name="aggressiveLazyLoading" value="false"/> </settings>
Get the primary key self increment
--> After inserting a piece of data, directly return the primary key value of the currently inserted data , Assign a value to the... Of the incoming object Id attribute <insert id="insertInfo" useGeneratedKeys="true" keyProperty="Id"> insert into area(region,have,value) values (#{ region},#{ have},#{ value}) </insert> Info info = new Info(null,"3","2","3"); int i = infoDao.insertInfo(info); System.out.println(info.getId());`
cache
--> The first level cache is on by default , be called SqlSession cache --> The second level cache is not enabled by default , be called SqlSessionFactory cache , Satisfy multiple users sql The cache effect of the statement . The global cache is enabled by default , It only needs mapper.xml Middle configuration , The global cache is set at mybatis.xml Medium setting Set... In the tag <!-- Turn on SqlSessionFactory Second level cache , All sql All on --> <cache/> Set up useCache="false" Property can close the cache of the current query <select id="selectAll2" resultMap="res3" useCache="false"> --> Cache query order Second level cache --> First level cache --> database --> Save to level 1 --> close / Submit SqlSession In L1 cache, cache data is stored in L2 cache
Annotation development
@Insert("SQL sentence ") @Delete("SQL sentence ") @Update("SQL sentence ") @Select("SQL sentence ") List<Clazz> selectAll3(); --> It is applicable to single table simple query , There is no need to configure after writing annotations .xml file , Only applicable to the currently annotated method
Spring
IOC--> Inversion of control --> Don't use new How objects work , from spring Container creation object , Achieve loose coupling DI--> Dependency injection --> Assign values to the variable properties of the instance object AOP--> Section oriented programming --> Increase the extensibility of the program , You can add a notification before or after the current pointcut , To extend functions TX--> Declarative transactions --> Control of transactions is left to the framework , Bottom use aop technology , You can't try...catch Problem code , Otherwise, the business will not take effect
Create class instances IOC
--> There are four ways to create (IOC) 1、 No arguments bean 2、 Ginseng bean 3、 Static factory 4、 Non static factory -->ApplicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- Constructor creates an implementation class instance --> <!-- Parameterless construction creates implementation class instances --> <bean id="stu" class="com.yjd.service.impl.StudentServiceImpl"></bean> <!-- A parameterized construct creates an implementation class instance --> <bean id="stu2" class="com.yjd.service.impl.StudentServiceImpl"> <!--name The value in the attribute has the same name as the value in the construction parameter --> <!-- When the formal parameters of a construction parameter are the same , But the order is different , The last construction parameter will be called --> <!-- You can specify index/type Attribute corresponds to the order of parameters in the formal parameter , Call for the uniquely identified constructor --> <!--type Property can only write basic data types , To write a reference data type , Full pathname required java.lang.String--> <constructor-arg name="id" value="0" type="int"></constructor-arg> <constructor-arg name="name" value="yang"></constructor-arg> <constructor-arg name="sex" value=" male "></constructor-arg> </bean> <!-- Create an implementation class instance using a factory --> <!--param Is the formal parameter name of the factory method ,value For reference --> <!-- The factory creates instances using static methods --> <bean id="s" class="com.yjd.factory.Factory" factory-method="getStatic"> <constructor-arg name="param" value="stu"></constructor-arg> </bean> <!-- The method used by the factory to create an instance is a non static method --> <bean id="t" class="com.yjd.factory.Factory"></bean> <bean id="u" factory-bean="t" factory-method="getUnStatic"> <constructor-arg name="param" value="stu"></constructor-arg> </bean> </beans> -->test public class Test { public static void main(String[] args) { //xml File parsing , All in the file bean All labels are valid , Generate corresponding implementation class instances ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml"); // adopt bean Medium id Property to get an instance of the generated implementation class in the configuration file // Get the instance created by the parameterless construct StudentService stu1 = app.getBean("stu", StudentService.class); stu1.aa(); // Get the instance created by the parameterized construct StudentService stu = app.getBean("stu2", StudentService.class); stu.aa(); // Factory mode static StudentService s = app.getBean("s", StudentService.class); s.aa(); // Factory mode is not static StudentServiceImpl u = app.getBean("u", StudentServiceImpl.class); u.aa(); } }
Dependency injection DI
--> Assign a value to a variable in an existing instance object --> Four ways 1、 Constructor mode 2、set The way 3、 Automatic injection mode 4、 Array / Set assignment <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!-- Constructor mode assignment --> <bean id="cla" class="com.yjd.pojo.Clazz"> <constructor-arg name="cid" value="1"> </constructor-arg> <constructor-arg name="cname" value="S110"> </constructor-arg> <constructor-arg name="cteacher" value="yang"> </constructor-arg> </bean> <!--set Method assignment --> <!-- You must provide a for this variable get&set Method can be assigned --> <!--value: Basic data type ref: Instance class object --> <bean id="stu" class="com.yjd.pojo.Student"> <property name="sid" value="1"> </property> <property name="sname" value=" Xiao Ming "> </property> <property name="sex" value=" male "> </property> <!-- Dependency injection --> <property name="clazz" ref="cla"> </property> </bean> <!-- Automatic injection --> <!-- After using automatic injection , The attributes in the current instance will be automatically injected into the corresponding data according to the search rules , The injected properties are objects autowire: 1、byName: When bean Medium id Attribute name and class The variable names in the class are the same , Automatic injection 2、byType: When bean The type of the generated class instance is the same as the current class When the types required in the class properties are the same , Automatic injection , Note that there can only be one instance of the required type bean 3、constructor: There must be a separate constructor for automatic injection by the constructor , Otherwise, it's impossible to inject --> <!-- Automatic injection and set/ Constructor mode can be used in combination --> <bean id="cla" class="com.yjd.pojo.Clazz"> <constructor-arg name="cid" value="1"> </constructor-arg> <constructor-arg name="cname" value="S110"> </constructor-arg> <constructor-arg name="cteacher" value="yang"> </constructor-arg> </bean> <bean id="auto" class="com.yjd.pojo.Student" autowire="constructor"> <property name="sid" value="1"> </property> <property name="sname" value=" Xiao Ming "> </property> <property name="sex" value=" male "> </property> </bean> <!-- Array and set assignment ,name Is the name of the variable in the class --> <!--map The set assignment method is special --> <!-- Array --> <bean id="ar" class="com.yjd.pojo.Student"> <property name="arr"> <array> <value>a</value> <value>b</value> <value>c</value> </array> </property> </bean> <!--List aggregate --> <bean id="li" class="com.yjd.pojo.Student"> <property name="list"> <list> <value>a</value> <value>b</value> <value>c</value> </list> </property> </bean> <!--Set aggregate --> <bean id="se" class="com.yjd.pojo.Student"> <property name="set"> <set> <value>a</value> <value>b</value> <value>c</value> </set> </property> </bean> <!--Map aggregate --> <bean id="ma" class="com.yjd.pojo.Student"> <property name="map"> <map> <entry> <key><value>1</value></key> <value>a</value> </entry><entry> <key><value>2</value></key> <value>b</value> </entry><entry> <key><value>3</value></key> <value>c</value> </entry> </map> </property> </bean> </beans>
bean Single case / Multiple cases
public class Test { public static void main(String[] args) { /** * singleton: The singleton pattern * prototype: Many cases of pattern * Spring The default is singleton mode * In singleton mode ,new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml") Will create a Subobject * In multi instance mode ,app.getBean("li", Student.class) Objects are created when * */ ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml"); Student stu1 = app.getBean("li", Student.class); Student stu2 = app.getBean("li", Student.class); System.out.println(stu1==stu2); } } -->bean Add scope Label control singleton / Many cases of pattern <bean id="li" class="com.yjd.pojo.Student" scope="singleton"> <property name="list"> <list> <value>a</value> <value>b</value> <value>c</value> </list> </property> </bean>
And MyBatis Integrate
-->ApplicationContext.xml <?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: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-4.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- introduce jdbc.properties file --> <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder> <!--Spring To configure jdbc--> <bean id="jdbc" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${mysql_driver}"> </property> <property name="url" value="${mysql_url}"> </property> <property name="username" value="${mysql_username}"> </property> <property name="password" value="${mysql_password}"> </property> </bean> <!-- get SqlSessionFactory factory --> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="jdbc"> </property> <property name="typeAliasesPackage" value="com.yjd.pojo"> </property> </bean> <!-- To configure Mappers scanning --> <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="factory"> </property> <property name="basePackage" value="com.yjd.mapper"> </property> </bean> <!-- Simplify programming , To reduce the coupling --> <!-- Kill two birds with one stone , You can get UserMapper Object is used in the current instance , Again IOC Way to create UserServiceImpl object --> <bean id="users" class="com.yjd.service.impl.UserServiceImpl"> <property name="userMapper" ref="userMapper"> </property> </bean> </beans> -->servlet @WebServlet(urlPatterns = "/yjd/LoginServlet") public class LoginServlet extends HttpServlet { private UserService userService; @Override public void init() throws ServletException { // Parse the file and initialize it once ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml"); userService = app.getBean("users", UserService.class); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String uKey = req.getParameter("ukey"); String pwd = req.getParameter("pwd"); User one = userService.findOne(uKey, pwd); System.out.println(one); if (one != null) { resp.sendRedirect(req.getContextPath() + "/success.jsp"); } else { req.getRequestDispatcher("/success.jsp").forward(req, resp); } } } -->UserServiceImpl public class UserServiceImpl implements UserService { private UserMapper userMapper; public UserMapper getUserMapper() { return userMapper; } public void setUserMapper(UserMapper userMapper) { this.userMapper = userMapper; } @Override public User findOne(String uKey, String pwd) { return userMapper.selectOne(uKey, pwd); } }
The proxy pattern
--> Static agents and dynamic agents --> A dynamic proxy : Extend the program without modifying the source code -->JDK A dynamic proxy , There has to be an interface --> proxy class public class MyProxy { public Object getProxy(Object obj) { return Proxy.newProxyInstance(MyProxy.class.getClassLoader(), new Class[]{ MyCalculate.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { YjdExpand.log(method.getName(), args[0], args[1]); Object invoke = method.invoke(obj, args); return invoke; } }); } } --> Proxy class generation class file package com.yjd.proxy; import java.io.FileOutputStream; import java.io.IOException; import sun.misc.ProxyGenerator; public class Util { /** * Util.writeProxyClassToHardDisk("E:/$Proxy11.class",new FD1().getClass().getInterfaces() ); */ public static void writeProxyClassToHardDisk(String path,Class[] cla) { byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy11", cla); FileOutputStream out = null; try { out = new FileOutputStream(path); out.write(classFile); out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } --> Use proxy classes public class Test { public static void main(String[] args) { MyProxy myProxy = new MyProxy(); MyCalculate proxy = (MyCalculate) myProxy.getProxy(new MyCalculateImpl()); int jia = proxy.jia(1, 2); System.out.println(" The result is :" + jia); Util.writeProxyClassToHardDisk("E:/$Proxy11.class", new MyCalculateImpl().getClass().getInterfaces()); } } -->JVM Proxy class code in import com.yjd.service.*; import java.lang.reflect.*; public final class $Proxy11 extends Proxy implements MyCalculate{ private static Method m1; private static Method m2; private static Method m3; private static Method m0; private static Method m4; public $Proxy11(final InvocationHandler invocationHandler) { super(invocationHandler); } public final boolean equals(final Object o) { try { return (boolean)super.h.invoke(this, $Proxy11.m1, new Object[] { o }); } catch (Error | RuntimeException error) { throw; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } public final String toString() { try { return (String)super.h.invoke(this, $Proxy11.m2, null); } catch (Error | RuntimeException error) { throw; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } public final int jia(final int n, final int n2) { try { return (int)super.h.invoke(this, $Proxy11.m3, new Object[] { n, n2 }); } catch (Error | RuntimeException error) { throw; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } public final int hashCode() { try { return (int)super.h.invoke(this, $Proxy11.m0, null); } catch (Error | RuntimeException error) { throw; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } public final int jian(final int n, final int n2) { try { return (int)super.h.invoke(this, $Proxy11.m4, new Object[] { n, n2 }); } catch (Error | RuntimeException error) { throw; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } static { try { $Proxy11.m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); $Proxy11.m2 = Class.forName("java.lang.Object").getMethod("toString", (Class<?>[])new Class[0]); $Proxy11.m3 = Class.forName("com.yjd.service.MyCalculate").getMethod("jia", Integer.TYPE, Integer.TYPE); $Proxy11.m0 = Class.forName("java.lang.Object").getMethod("hashCode", (Class<?>[])new Class[0]); $Proxy11.m4 = Class.forName("com.yjd.service.MyCalculate").getMethod("jian", Integer.TYPE, Integer.TYPE); } catch (NoSuchMethodException ex) { throw new NoSuchMethodError(ex.getMessage()); } catch (ClassNotFoundException ex2) { throw new NoClassDefFoundError(ex2.getMessage()); } } } -->CGLIB A dynamic proxy --> proxy class public class CGLIBProxy { public Object getCGLIBProxy(Object obj) { Enhancer enc = new Enhancer(); // Set proxy class parent enc.setSuperclass(obj.getClass()); // Set the callback function enc.setCallback(new MethodInterceptor() { /** * Parameter one : Proxy object * Parameter two : The target method reflects the object * Parameter 3 : Target method parameters * Parameter 4 : Proxy methods reflect objects */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { // Extension code YjdExpand.log(method.getName(), objects[0], objects[1]); Object invoke = method.invoke(obj, objects); return invoke; } }); Object o = enc.create(); return o; } } --> Use public class TestCGLIBProxy { public static void main(String[] args) { // get CGLIBProxy Dynamic proxy object MyCalculateImpl cglibProxy = (MyCalculateImpl) new CGLIBProxy().getCGLIBProxy(new MyCalculateImpl()); int jia = cglibProxy.jia(1, 2); System.out.println(jia); } }
Section oriented programming AOP
--> Function expansion without modifying the source code , A technique for unified maintenance of program functions by precompiling and dynamic agents during runtime --> Basic concepts 1、Aspect( section ): It's usually a class , It can define entry points and notifications 2、JointPoint( Connection point ): Clear points in the process of program execution , It's usually a method call 3、Advice( notice ):AOP Enhanced processing performed at a specific entry point , Yes before,after,afterReturning,afterThrowing,around 4、Pointcut( The breakthrough point ): It's a connection point with a notification , In the program is mainly reflected in writing pointcut expressions 5、AOP agent :AOP Objects created by the framework , Agent is the strengthening of the target object .Spring Medium AOP An agent can make JDK A dynamic proxy , It can also be CGLIB agent , The former is based on For interface , The latter is based on subclasses --> Four notices : 1、 Pre notice 2、 The rear notice 3、 Surrounding the notification ( Can be performed before and after the pointcut , There is a return value , Be surrounded by notification before and after ) 4、 Abnormal notice ( Only when there is an error in the pointcut operation can it be executed , You cannot catch exceptions when using exception notification , Otherwise, the exception notification cannot be triggered ) Transverse section ( Proxy object ): Pre notice + Tangent point + The rear notice Execution order : Connection points are executed sequentially --> Pre notice --> Before you circle --> Tangent point --> After circling --> The rear notice -->AOP There are two ways to implement extension : 1、Schema_based Based on interfaces , Pointcut parameters and return values are easy to obtain 2、AspectJ Based on the object , Getting pointcut parameters and return values is a hassle Involving parameter use Schema-based, Parameter usage is not involved AspectJSchema_based The way
-->Schema_based The way --> Pre notice public class BeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("bb Prior notice of "); } } --> The rear notice public class AfterAdvice implements AfterReturningAdvice { /** * o: The return value of the pointcut method * method: Method object in tangent point * objects: List of parameters in tangent point * o1: The object of the class where the pointcut is located * */ @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { } } --> Surrounding the notification public class Around implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println(" Before you circle "+methodInvocation.getMethod()); // Be careful ** The fixed writing here , Perform the pointcut method Object proceed = methodInvocation.proceed(); System.out.println(" After circling "); return proceed; } } --> Abnormal notice public class Throw implements ThrowsAdvice { // Fixed writing , The pointcut operation is executed abnormally public void afterThrowing(Exception ex) throws Throwable { System.out.println("-- Abnormal notice --"); } } -->ApplicationContext.xml To configure <!-- Create an implementation class object --> <bean id="stu" class="com.yjd.service.impl.StudentServiceImpl"></bean> <!-- Create a pre notification object --> <bean id="bef" class="com.yjd.advice.BeforeAdvice"></bean> <!-- Create post notification object --> <bean id="aft" class="com.yjd.advice.AfterAdvice"></bean> <!-- Create a surround notification object --> <bean id="aro" class="com.yjd.advice.Around"></bean> <!-- Create an exception notification object --> <bean id="thr" class="com.yjd.advice.Throw"></bean> <!--AOP Set up --> <aop:config> <!-- Set tangent point --> <aop:pointcut id="pot" expression="execution(* com.yjd.service.impl.StudentServiceImpl.bb())"/> <!-- Pointcuts are associated with pre notification objects --> <aop:advisor advice-ref="bef" pointcut-ref="pot"></aop:advisor> <!-- Pointcuts are associated with post notification objects --> <aop:advisor advice-ref="aft" pointcut-ref="pot"></aop:advisor> <!-- The pointcut is associated with the surrounding notification object --> <aop:advisor advice-ref="aro" pointcut-ref="pot"></aop:advisor> <!-- Pointcuts are associated with exception notification objects --> <aop:advisor advice-ref="thr" pointcut-ref="pot"></aop:advisor> <!-- There are many ways to set the tangent point --> <!--impl All methods in all classes in the package are used as pointcuts --> <!--<aop:pointcut id="pot" expression="execution(* com.yjd.service.impl.*.*(..))"/>--> <!-- All methods in the class act as pointcuts --> <!--<aop:pointcut id="pot" expression="execution(* com.yjd.service.impl.StudentServiceImpl.*(..))"/>--> <!-- All names under the specified class are bb All of the methods are used as pointcuts --> <!--<aop:pointcut id="pot" expression="execution(* com.yjd.service.impl.StudentServiceImpl.bb(..))"/>--> <!-- Specify the method under the specified class as the tangent point --> <!--<aop:pointcut id="pot" expression="execution(* com.yjd.service.impl.StudentServiceImpl.bb(int,double,String))"/>--> </aop:config> <!--false by JDK A dynamic proxy ,true by CGLIB A dynamic proxy If no interface is declared in the target class , be spring Will be used automatically CGLIB A dynamic proxy --> <aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy> --> Tangent point use + notice package com.yjd.test; import com.yjd.service.StudentService; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // analysis xml File configuration ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml"); // Note here ,stu Object is a proxy object , Implement classes for interfaces , You cannot use interfaces to declare other implementation classes StudentService stu = app.getBean("stu", StudentService.class); //stu.aa(); stu.bb(); //stu.cc(); } }AspectJ The way
-->AspectJ --> Inform the class package com.yjd.advice; import org.aspectj.lang.ProceedingJoinPoint; /** * @author: Ada * @date: 2021/6/9 9:33 */ /** * AspectJ You can put four kinds of notifications in one notification class * */ public class AspectJAdvice { public void beforeAdvice() { System.out.println("-- Pre notice --"); } public void afterAdvice() { System.out.println("-- The rear notice --"); } public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable { System.out.println("-- Before surrounding the notice --"); Object proceed = point.proceed(); System.out.println("-- After the circular --"); return proceed; } public void throwsAdvice() { System.out.println("-- Abnormal notice --"); } } -->ApplicationContext.xml File configuration <!-- Implementation class object --> <bean id="stu" class="com.yjd.service.impl.StudentServiceImpl"></bean> <!-- Create notification object --> <bean id="aspect" class="com.yjd.advice.AspectJAdvice"></bean> <aop:config> <aop:aspect ref="aspect"> <!-- Set tangent point --> <aop:pointcut id="ap" expression="execution(* com.yjd.service.impl.StudentServiceImpl.bb())"/> <!-- Pre notice --> <aop:before method="beforeAdvice" pointcut-ref="ap"></aop:before> <!-- No matter whether the pointcut operation reports an error , Post notification will be executed --> <aop:after method="afterAdvice" pointcut-ref="ap"></aop:after> <!-- An error is reported during pointcut operation , Post notification does not execute --> <aop:after-returning method="afterAdvice" pointcut-ref="ap"></aop:after-returning> <!-- Surrounding the notification --> <aop:around method="aroundAdvice" pointcut-ref="ap"></aop:around> <!-- Abnormal notice --> <aop:after-throwing method="throwsAdvice" pointcut-ref="ap"></aop:after-throwing> </aop:aspect> </aop:config> --> Using tangent points + notice package com.yjd.test; import com.yjd.service.StudentService; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // analysis xml File configuration ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:ApplicationContext2.xml"); // Note here ,stu Object is a proxy object , Implement classes for interfaces , You cannot use interfaces to declare other implementation classes StudentService stu = app.getBean("stu", StudentService.class); //stu.aa(); stu.bb(); //stu.cc(); } }
LomBok Commonly used annotations
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-uebV4tVc-1654393801942)(C:\Users\ Vertically and horizontally \AppData\Roaming\Typora\typora-user-images\image-20210608183852358.png)]
-->lombok After changing the workspace, the settings in the above figure shall take effect @Data Annotation on class ; Providing all properties of the class getting and setting Method , It also provides equals、canEqual、hashCode、toString Method @Setter : Comment on attribute ; Provide... For properties setting Method @Getter : Comment on attribute ; Provide... For properties getting Method @Log4j : Annotation on class ; Provide the class with a property named log Of log4j Log object @NoArgsConstructor : Annotation on class ; Provides a parameterless construction method for a class @AllArgsConstructor : Annotation on class ; Provide a construction method of all parameters for the class @Cleanup : You can turn off the stream @Builder : The annotated class adds a constructor pattern @Synchronized : Add a synchrolock @SneakyThrows : Equate to try/catch Capture exception @NonNull : If you add this annotation to the parameter Parameter is null A null pointer exception will be thrown @Value : Notes and @Data similar , The difference is that it will default all member variables to private final modification , And will not generate set Method
Declarative transactions TX
--> Transaction manipulation is required to perform two or more addition, deletion and modification operations , Transactions are divided into programmatic transactions and declarative transactions ( Managed by the framework , The configuration can be ) --> Bottom use AOP Section oriented programming , Use tx notice , The business layer should not catch exceptions , Otherwise, the program fails and cannot be rolled back -->ApplicationCOntext.xml To configure 1、 Without using transaction annotations <!--Spring Management objects of transactions in --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="jdbc"></property> </bean> <!-- Add transaction notification for method --> <tx:advice id="ad" transaction-manager="transactionManager"> <!--attributes Omission ?--> <tx:attributes> <tx:method name="move"/> </tx:attributes> </tx:advice> <!-- Transaction bottom layer uses AOP complete --> <!-- adopt AOP Add transactions to the specified pointcut --> <aop:config> <aop:pointcut id="pt1" expression="execution(* com.yjd.service.impl.*.*(..))"/> <aop:advisor advice-ref="ad" pointcut-ref="pt1"></aop:advisor> </aop:config> 2、 Using annotations <!-- Transaction driven registration --> <tx:annotation-driven></tx:annotation-driven> <!-- Create a transaction management object --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="jdbc"></property> </bean> <!-- In the class / Method @Transactional annotation , Specify the cut point --> --> Set transaction properties --> In the case of using annotations @Transactional Property , Without using annotations in <tx:method name="move"/> Property -->time-out: Overtime -->read-only: read-only -->propagation: Transaction propagation behavior --> Transaction propagation behavior (propagation behavior) When a transaction method is called by another transaction method , How this transaction method should proceed -->methodA Transaction method call methodB Transaction method ,methodB Is to continue to call methodA Running in the same transaction , Or start a new transaction for yourself , That's why methodB The business communication behavior determines . 1、required( Default ): Method B Must run in a transaction , If the method A Affairs , Then the method B In the method A Run in , Otherwise, a new transaction will be started 2、supports: Method B You don't need to run in a transaction method , Method A Is there any business , Method B All in A Run in 3、mandatory: Method B Must run in a transaction , Such as the method A Not a transaction method , An exception is thrown 4、requires_new: When a transaction method A Call the transaction method in B when , Suspend transaction method A, Execute transaction method B, Method B Release the transaction execution method after execution A 5、not_supported: Method B Must be in a non transactional state , Transaction method A Calling method B after , Suspend transaction method A Execute methods in a non transactional state B 6、never: Method A With the method B Cannot be a transaction method , Otherwise, the report will be wrong 7、nested: Transaction method A Call transaction method B after , Such as the method A Report errors , Rollback directly to method B perform , Such as the method B Report errors , Direct return method A Carry on Transaction isolation level : Ensure data integrity in the case of multi threading or multi concurrency Dirty reading :A Operation not committed ,B Read uncommitted data Fantasy reading :( increase ) It can't be read repeatedly : A business A Multiple queries in , Other business B The data is manipulated , Cause transaction A The data before and after reading in is inconsistent ( Modification and deletion ) -->isolation: Transaction isolation level 1、default: The default value is , Judge the transaction isolation level by the underlying database 2、read_uncommitted: You can submit uncommitted data , Can appear 3、read_committed: Only data of committed transactions can be read , To solve the dirty read 4、pereatable_read: The read data is locked , Prevent other transactions from modifying data , Can prevent non repeatable reading 、 Dirty reading 5、serializable: Queued operation , Lock the entire table , When a transaction operates on data , Other transactions cannot operate on transactions 6、rollback-for: Exception type fully qualified name , What is the abnormal rollback 7、no-rollback-for: You won't roll in case of any abnormality
Spring Commonly used annotations
--> Annotations need to be scanned before they take effect ,IOC、DI、AOP、TX There are special notes in <!-- Annotation scan , Scan various annotations , among IOC+DI The annotation takes effect directly ,AOP and TX Annotations need to be resolved by their respective drivers before they take effect --> <!-- Specify the package IOC+DI Annotations to take effect --> <!-- Multiple packet scans can use , Separate Package name / The class name can be used * Instead of com.yjd.service.*--> <context:component-scan base-package="com.yjd.service.impl"> <!--type For the type : 1、annotation: annotation 2、assignable: class expression: Full pathname for annotation --> <!-- Appoint XXX Annotations are not scanned --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> <!-- Specifies that annotations for a class are not scanned --> <context:exclude-filter type="assignable" expression="com.yjd.service.impl.AccountServiceImpl"/> <!-- Appoint XXX Annotations are scanned --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> <!-- Specifies that the annotation of a class is scanned --> <context:include-filter type="assignable" expression="com.yjd.service.impl.AccountServiceImpl"/> </context:component-scan> <!--AOP Annotations need to be loaded AspectJ Drive parsing of annotations --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- load TX Drive parsing transaction annotations --> <tx:annotation-driven></tx:annotation-driven> -->IOC @Component: Other layers for placing classes @Service("id"):service layer , It's equivalent to configuration bean label ,ID Default to class name initial lowercase @controlor:-->servlet layer @repository:-->Dao layer -->DI @Resource: First, search by name , And then search for , Find the generated object and inject it into the attribute (JDK Official supply ) @Autowired: Find by type , Then search and inject according to the name (Spring Provide , It is recommended to use ), Don't write get/set Method @Quaifier(" Alias "): And Autowired A combination of , When there are multiple instances of the same type , Distinguish objects by alias @Value("${ key }"): Read the values in the properties file , Such as : key =com.mysql.cj.jdbc.Driver -->AOP Use annotation method , The execution order of the notification is different --> Surround front 、 In front of 、 Surround back 、 After @Aspect: The action takes effect on the notification class @Pointcut("execution(* com.yjd.test.*.*(..))"): Point to tangent method , The full path , The method body does not execute @Before("aa()"): Point to @Pointcut The method of annotation , Can be full path , The method body executes on notification @After: ditto @Around: ditto @AfterThrowing: ditto --> Target class @Component public class MyTarget { public void aa() { System.out.println(" Tangent point aa Method "); } } --> Inform the class @Component @Aspect public class MyAdvice { @Pointcut("execution(* com.yjd.test.*.*(..))") public void aa() { System.out.println(" Point to tangent method , But not implemented. "); } @Before("aa()") public void bb() { System.out.println(" Point to @Pointcut Annotation specifies the method , It's like a notice "); } } -->applicationContext.xml To configure <!-- Scan the package for comments --> <context:component-scan base-package="com.yjd.test"></context:component-scan> <!--AOP Annotation parser --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> -->TX 1、<!-- Register transaction annotation parsing driver --> <tx:annotation-driven></tx:annotation-driven> 2、<!--Spring Transaction management in --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="jdbc"></property> </bean> 3、@Transactional: Add a transaction to the method -->Junit( Method ) @Test: unit testing @Before: Execute before unit test @After: Execute after unit test //spring Notes on integration unit tests @ContextConfiguration(location={ "classpath:ApplicationContext.xml"}): need spring-test Of jar package @RunWith(Springjunit4ClassRunner.class)
SpringMVC
To configure
--> Yes servlet encapsulate , Provide public servlet, Processing methods can be called dynamically upon request package com.yjd.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author: Ada * @date: 2021/6/10 9:02 */ // A common class acts as a front-end controller @Controller public class MyController { // Configure the processor mapper mapping path @RequestMapping("/demo1") public String demo1() { System.out.println("demo1"); // The direct request forwarding method jumps to the corresponding String Type path address return "success.jsp"; } @RequestMapping("/getParam1") public String getParam1(HttpServletRequest req, HttpServletResponse resp) { req.getParameter(""); return "success.jsp"; } // Through form name Get the corresponding value for the property name @RequestMapping("/getParam2") public String getParam2(String uname,int age,String[] hobby1,String hobby2) { return "success.jsp"; } } -->springMVC.xml File configuration <?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.yjd.controller"></context:component-scan> <!-- Load mapper and adapter --> <mvc:annotation-driven></mvc:annotation-driven> <!-- Static resource release --> <!--mapping:url route location: The local path --> <mvc:resources mapping="/js/**" location="/js/"></mvc:resources> <mvc:resources mapping="/imgs/**" location="/imgs/"></mvc:resources> <mvc:resources mapping="/css/**" location="/css/"></mvc:resources> <mvc:resources mapping="/static/**" location="/static/"></mvc:resources> </beans> -->web.xml Set up <?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"> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <!-- except jsp All in --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Static resource release
--> except .jsp The documents , Other static files can be accessed directly , Otherwise, the mapper will report an error if it cannot match the path , After release, directly find the files in the disk for display <!-- Static resource release springmvc.xml Middle configuration --> <!--mapping:url route location: The local path --> <mvc:resources mapping="/js/**" location="/js/"></mvc:resources> <mvc:resources mapping="/imgs/**" location="/imgs/"></mvc:resources> <mvc:resources mapping="/css/**" location="/css/"></mvc:resources> <mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
springMVC Execute the process
--> After the browser sends the request, the web.xml File acquisition front-end controller ( Program entrance ), And analyze springMVC.xml file --> The front-end controller hands over the request path to the processor mapper , Find a matching mapping method --> The processor mapper feeds back the method information to the front-end controller , The front controller calls the processor adapter , Leave the method to the corresponding processor --> The processor returns models and views , It is returned to the front controller by the processor adapter --> The front controller calls the view parser to parse the model and view , And return the analysis result to the front-end controller --> The front-end controller invokes the view , Render the view results , And return the rendered view to the front controller --> The front controller presents the view response to the browser 1、 Front controller DispatcherServlet: Request query Handler、 Request execution 、 Request resolution view 、 Render view 、 Responding to users 2、 Processor mapper HandlerMapping: Back to the processor execution chain 3、 Processor adapter HandlerApadapter: Determine which processor to use based on the method parameters and return values 4、 processor Handler: Return to model and view ModleAndView 5、 view resolver Resolver: Return to view object 6、 View View: Render view --> Three components : Processor mapper 、 Processor adapter 、 view resolver
Foreground data acquisition
--> Parameter injection method 1、 Tight coupling mode : Using tradition servlet The way @RequestMapping("/getParam1") public String getParam1(HttpServletRequest req, HttpServletResponse resp) { req.getParameter(""); return "success.jsp"; } 2、 loose coupling ( decoupling ) The way :SpringMVC The way , The method parameter value is the foreground form name The value of the property , Data types can be automatically converted ,400 The error is the foreground parameter error // Through form name Get the corresponding value for the property name //checkbox The value of type can be used String[] hobby/String hobby obtain @RequestMapping("/getParam2") public String getParam2(String uname,String sex,String hobby,int password) { System.out.println(uname + sex + hobby + password); return "index.jsp"; } 3、 Formal parameters are objects // according to pojo The attribute names of entity classes in are automatically injected with data , Property name and foreground are required name Property values are consistent @RequestMapping("/getParam3") public String getParam3(Clazz clazz, Student student) { System.out.println(clazz); System.out.println(student); return "index.jsp"; } <form action="getParam3" method="get"> <p> class ID:<input type="text" name="cid"/> </p> <p> Class name :<input type="text" name="cname"/> </p> <p> Student ID:<input type="text" name="sid"/> </p> <p> The student's name :<input type="text" name="sname"/> </p> <p> male :<input type="radio" name="sex" value=" male "/> Woman :<input type="radio" name="sex" value=" Woman "/> </p> <p> hobby : eat :<input type="checkbox" name="hobby" value=" eat "/> drink :<input type="checkbox" name="hobby" value=" drink "/> play :<input type="checkbox" name="hobby" value=" play "/> Happy :<input type="checkbox" name="hobby" value=" Happy "/> </p> <p> <input type="submit" value=" Submit "/> </p> </form> 4、 Formal parameters are objects , Object has other objects as attributes // In the front desk name The attribute value is the attribute object name in the formal parameter object . Property name @RequestMapping("/getParam4") public String getParam4(Clazz clazz) { System.out.println(clazz); return "index.jsp"; } <form action="getParam3" method="get"> <p> class ID:<input type="text" name="cid"/> </p> <p> Class name :<input type="text" name="cname"/> </p> <p> Student ID:<input type="text" name="student.sid"/> </p> <p> The student's name :<input type="text" name="student.sname"/> </p> <p> male :<input type="radio" name="student.sex" value=" male "/> Woman :<input type="radio" name="student.sex" value=" Woman "/> </p> <p> hobby : eat :<input type="checkbox" name="student.hobby" value=" eat "/> drink :<input type="checkbox" name="student.hobby" value=" drink "/> play :<input type="checkbox" name="student.hobby" value=" play "/> Happy :<input type="checkbox" name="student.hobby" value=" Happy "/> </p> <p> <input type="submit" value=" Submit "/> </p> </form> 5、 Formal parameters are objects , Among objects List Collection objects as attributes @RequestMapping("/getParam5") public String getParam5(Clazz clazz) { System.out.println(clazz); return "index.jsp"; } <form action="getParam5" method="get"> <p> class ID:<input type="text" name="cid"/> </p> <p> Class name :<input type="text" name="cname"/> </p> <p> Student ID:<input type="text" name="list[0].sid"/> </p> <p> The student's name :<input type="text" name="list[0].sname"/> </p> <p> male :<input type="radio" name="list[0].sex" value=" male "/> Woman :<input type="radio" name="list[0].sex" value=" Woman "/> </p> <p> hobby : eat :<input type="checkbox" name="list[0].hobby" value=" eat "/> drink :<input type="checkbox" name="list[0].hobby" value=" drink "/> play :<input type="checkbox" name="list[0].hobby" value=" play "/> Happy :<input type="checkbox" name="list[0].hobby" value=" Happy "/> </p> <p> <input type="submit" value=" Submit "/> </p> </form> 6、 Formal parameters are objects , Among objects Map Collection objects as attributes @RequestMapping("/getParam6") public String getParam5(Clazz clazz) { System.out.println(clazz); return "index.jsp"; } <form action="getParam5" method="get"> <p> class ID:<input type="text" name="cid"/> </p> <p> Class name :<input type="text" name="cname"/> </p> <p> Student ID:<input type="text" name="map[0].sid"/> </p> <p> The student's name :<input type="text" name="map[0].sname"/> </p> <p> male :<input type="radio" name="map[0].sex" value=" male "/> Woman :<input type="radio" name="map[0].sex" value=" Woman "/> </p> <p> hobby : eat :<input type="checkbox" name="map[0].hobby" value=" eat "/> drink :<input type="checkbox" name="map[0].hobby" value=" drink "/> play :<input type="checkbox" name="map[0].hobby" value=" play "/> Happy :<input type="checkbox" name="map[0].hobby" value=" Happy "/> </p> <p> <input type="submit" value=" Submit "/> </p> </form> 7、 The parameter is date type / There are date type attributes in the parameter object --> Use @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") annotation , It can be placed in method parameters / Class properties @RequestMapping("/getParam6") public String getParam6(@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") Date date, Clazz clazz) { System.out.println(date); System.out.println(clazz); return "index.jsp"; } @Data @NoArgsConstructor @AllArgsConstructor public class Clazz { private int cid; private String cname; @DateTimeFormat(pattern = "yyyy-MM-dd yy:mm:ss") private Date date; private Student student; private List<Student> list; private Map<String, Student> map; } <p> Day school date :<input type="text" name="date"/> </p> 8、 Filter settings <!--springMVC in filter The filter is set at web.xml in --> <filter> <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
annotation
@RequestMapping --> Can be placed on classes and methods , Put it on the class , The path in the method is a secondary path , Note the superposition of relative paths -->path/value Is the access path , Omission / -->method Limit request mode -->param The parameters that limit the foreground must have name The property value is yang and sex Attribute values are not limited @RequestMapping(path="/ route ",method=RequestMethod.POST,param={ "name=yang","sex"}): // annotation @RequestMapping @RequestMapping(value = "/getParam6",method = RequestMethod.POST,params = { "name=yang","sex"}) public String getParam6(@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") Date date, Clazz clazz) { System.out.println(date); System.out.println(clazz); return "/index.jsp"; } @PostMapping("/yjd/addOne"): We only accept Post Mode request @GetMapping("/yjd/addOne"): We only accept Get Mode request @RequestParam --> Can only be placed on parameters -->value: Foreground data name Property value , It's equivalent to a nickname -->required:true Is required false Is not required -->defaultValue: The data transferred by the current station is not null when , You can use the default values @RequestParam(value = " The front desk name value ",required = false,defaultValue = " The default value is ") String name @PathVariable And restful In combination The ordinary way :http://localhost:8080/springmvc01/MyController/getParam5?cid=1&cname=s223&map%5B0%5D.sid=2&map%5B0%5D.sname=yang restful The way :http://localhost:8080/springmvc01/MyController/getParam7/zs/li/ww --> Use... In method parameters @RequestMapping("/getParam6/{a}/{b}/{c}") public String getParam7(@PathVariable String a, @PathVariable String b, @PathVariable String c) { System.out.println(a); System.out.println(b); System.out.println(c); return "/index.jsp"; } @RequestHeader Get the information in the request header --> Use... In method parameters @RequestMapping(value = "/getParam8") public String getParam8(@RequestHeader("accept") String a) { System.out.println(a); return "/index.jsp"; } @CookieValue: obtain cookie Information in --> Use... In method parameters @RequestMapping(value = "/getParam9") public String getParam9(@CookieValue("JSESSIONID") String a) { System.out.println(a); return "/index.jsp"; } @ResponseBody --> Can be used in classes and methods , On behalf of the use of ajax Response request @RequestMapping(value = "/yjd/respMethod6", produces = "application/json;charaset=GBK") @ResponseBody public Student respMethod6() { Student student = new Student(" Yang ", 20); return student; } @JsonFormat(pattern = "yyyy-MM-dd") -->ajax Response date @DateTimeFormat(pattern = "yyyy-MM-dd") --> Receive the date data in the request public class Student implements Serializable { private String name; private int age; // Response time formatting @JsonFormat(pattern = "yyyy-MM-dd") // Request receive time format @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birth; }
springMVC Respond to
--> The unit method uses void As a return value , There must be a response inside the method --> How to respond : 1、servletAPI The way @RequestMapping("/yjd/respMethod2") public void respMethod2(HttpServletRequest res, HttpServletResponse resp) throws IOException, ServletException { // Request forwarding res.getRequestDispatcher("/index.jsp").forward(res, resp); // Redirect //resp.sendRedirect(res.getContextPath() + "/index.jsp"); } 2、springMVC The way @RequestMapping("/yjd/respMethod1") public String respMethod1() { // forward return "forward:/index.jsp"; // Redirect return "redirect:/index.jsp"; } 3、View View mode @RequestMapping("/yjd/respMethod3") public View respMethod3(HttpServletRequest res) { // Request forwarding //InternalResourceView internalResourceView = new InternalResourceView("/index.jsp"); // Redirect RedirectView redirectView = new RedirectView(res.getContextPath() + "/index.jsp"); //return internalResourceView; return redirectView; } 4、ModelAndView The way @RequestMapping("/yjd/respMethod4") public ModelAndView respMethod4(HttpServletRequest res) { ModelAndView modelAndView = new ModelAndView(); // Request forwarding with view name //modelAndView.setViewName("forward:/index.jsp"); // Redirect with view name //modelAndView.setViewName("redirect:/index.jsp"); // Forward requests as views //modelAndView.setView(new InternalResourceView("/index.jsp")); // Redirect to view modelAndView.setView(new RedirectView(res.getContextPath() + "/index.jsp")); return modelAndView; } 5、 Tradition ajax The way , Return to the foreground as String type , Need to transfer Json, And the coding format needs to add @RequestMapping("/yjd/respMethod5") public void respMethod5(HttpServletResponse resp) throws IOException { resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charaset=utf-8"); Student student = new Student(" Yang ", 20); resp.getWriter().print(new Gson().toJson(student)); } $("#but1").click(function () { $.ajax({ type: "post", url: "yjd/respMethod5", data: { }, dataType: "json", success: function (result) { alert(result); }, error: function () { alert(" Request error !") } }); }); 6、springMVC Of ajax The way , Return to the foreground as Json, There is no need to transform , And the coding format does not need to be added , It can be done by context-Type View type // You can choose to set the encoding @RequestMapping(value = "/yjd/respMethod6", produces = "application/json;charaset=GBK") @ResponseBody public Student respMethod6() { Student student = new Student(" Yang ", 20); return student; } 7、ajax Response date @RequestMapping(value = "/yjd/respMethod6") @ResponseBody public Student respMethod6() { Student student = new Student(); Date date = new Date(); student.setBirth(date); return student; } @Data @NoArgsConstructor @AllArgsConstructor public class Student implements Serializable { private String name; private int age; // Response time formatting @JsonFormat(pattern = "yyyy-MM-dd") // Request receive time format @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birth; }
SSM Integrate
-->applicationContext.xml To configure <?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder> <!--Spring To configure jdbc--> <bean id="jdbc" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${mysql_driver}"> </property> <property name="url" value="${mysql_url}"> </property> <property name="username" value="${mysql_username}"> </property> <property name="password" value="${mysql_password}"> </property> </bean> <!-- get SqlSessionFactory factory --> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="jdbc"> </property> <property name="typeAliasesPackage" value="com.yjd.pojo"> </property> </bean> <!-- To configure Mappers scanning --> <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="factory"> </property> <property name="basePackage" value="com.yjd.mapper"> </property> </bean> <!-- Scan all annotations ,IOC+DI Directly ,AOP and TX Drive required --> <context:component-scan base-package="com.yjd.service.impl"></context:component-scan> <!-- Configure transaction management objects --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="jdbc"></property> </bean> <!-- load TX Drive parsing transaction annotations --> <tx:annotation-driven></tx:annotation-driven> <!-- load AOP Annotation parsing driven --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans> -->springMVC.xml To configure <?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- Annotation scan ,IOC+DI Directly ,AOP and TX Drive required / drive + Management object --> <context:component-scan base-package="com.yjd.controller"></context:component-scan> <!-- Load mapper and adapter --> <mvc:annotation-driven></mvc:annotation-driven> <!-- Static resource release --> <!--mapping:url route location: The local path --> <mvc:resources mapping="/js/**" location="/js/"></mvc:resources> <mvc:resources mapping="/imgs/**" location="/imgs/"></mvc:resources> <mvc:resources mapping="/css/**" location="/css/"></mvc:resources> <mvc:resources mapping="/static/**" location="/static/"></mvc:resources> </beans> -->web.xml To configure <?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"> <!-- analysis ApplicationContext.xml file --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- analysis springMVC.xml file --> <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:springMVC.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- Configure filters --> <filter> <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> --> Class instances and member variables are generated and injected with annotationsjar package
mybatis+spring+springMVC+lombok+jackson+jdbc common 29 individual[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-x8o3IXpF-1654393801947)(C:\Users\ Vertically and horizontally \AppData\Roaming\Typora\typora-user-images\image-20210611145239975.png)]
Scope
--> Add the field value in the background // Request domain 、 Session domain 、 The whole local area is used in the same way as before , Note the formal parameters and the acquisition of domain objects , The front desk to use EL/JSTL Expression receive @RequestMapping("/yjd/scope") public String scope1(HttpServletRequest res, HttpSession session) { //request Domain value transfer res.setAttribute("request", 1); //session Domain value transfer session.setAttribute("session", 2); //application Domain value transfer ServletContext application = res.getServletContext(); application.setAttribute("application", 3); return "forward:/index.jsp"; } //Model/ModelAndView The scope can be implemented with servlet The decoupling // When requesting to forward the response, the reception method of the foreground is the same as that of the request domain ${requestscope. key } // The data set in the redirection response time domain is carried in url In the address , have access to <%=request.getParamter(" key ")%> receive @RequestMapping("/yjd/scope2") public ModelAndView scope2(Model model) { model.addAttribute("model", 4); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("modelAndView", 5); modelAndView.setViewName("redirect:/index.jsp"); return modelAndView; } --> The value in the foreground receiving field <body> <p> request:${ requestScope.request} </p> <p> session:${ sessionScope.session} </p> <p> application:${ applicationScope.application} </p> <p> modelRequest:${ requestScope.model} </p> <p> modelAndViewRequest:${ requestScope.modelAndView} </p> <p> modelRedirect:<%=request.getParameter("model")%> </p> <p> modelAndViewRedirect:<%=request.getParameter("modelAndView")%> </p> </body>
view resolver
--> Set up the view parser for the response page -->WEB-INF The next page is to ensure the safety of the project , No direct access , You can only jump to the specified page by forwarding http://localhost:8080/springmvc03/WEB-INF/success.jsp--> This path is required to access --> When the response jumps, the view parser will add prefixes and suffixes to the path , Form a complete jump path <!-- Configure custom view parser --> <bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"></property> <property name="suffix" value=".jsp"></property> </bean> --> control unit @RequestMapping("/{path}") public String respMethod7(@PathVariable String path) { return path; } The path search order under the view parser : 1、/yjd/Login 2、@RequestMapping("/yjd/Login")--> first 3、@RequestMapping("/{path}") 4、 Under normal circumstances, the view parser is added with the prefix , If you don't want to go, you need to use the full path ( The front page is not WEB-INF Under the circumstances ) forward:/index.jsp redirect:/index.jsp @RequestMapping("/{path}") public String respMethod7(@PathVariable String path) { return "forward:/save.jsp"; }
Upload files
-->success.jsp <input type="file" id="file"/> <input type="button" value=" Upload files " id="but1"/> $("#but1").click(function () { var file = $("#file")[0].files[0]; var formData = new FormData(); formData.append("f", file); $.ajax({ type: "post", url: "yjd/upLoad", data: formData, processData:false, contentType:false, success: function (result) { alert(result); }, error: function () { alert(" Request error !"); } }); }); -->UpLoadController 1、 The files are stored on the local disk @RequestMapping("/yjd/upLoad") @ResponseBody public String upLoad(MultipartFile f, HttpServletRequest res, HttpServletResponse resp) throws IOException { String originalFilename = f.getOriginalFilename(); File file1 = new File("E:/" + originalFilename); f.transferTo(file1); return "OK"; } 2、 The files are stored on the local server @RequestMapping("/yjd/upLoad") @ResponseBody public Map<String,String> upLoad(MultipartFile f, HttpServletRequest res) throws IOException { // Get the file name String originalFilename = f.getOriginalFilename(); // Get file type String contentType = f.getContentType(); // Get file suffix String substring = f.getOriginalFilename().substring(f.getOriginalFilename().lastIndexOf(".")); // Get the file storage address in the server where the request is located String realPath = res.getServletContext().getRealPath("/imgs"); // Create a folder to store files in the local server File file = new File(realPath); if (!file.exists()) { file.mkdirs(); } // Create random file name , Avoid duplicate name coverage String uuid = UUID.randomUUID().toString(); // New name of the constituent document String fileName = uuid + substring; // Write the file to the specified directory f.transferTo(new File(file, fileName)); Map<String, String> map = new HashMap<>(); map.put("fileName", fileName); map.put("contentType", contentType); return map; } 3、 The files are stored in the remote server @RequestMapping(value = "/fileUplaod2",method = RequestMethod.POST) @ResponseBody public Map<String,String> fileUplaod2(MultipartFile f, HttpServletRequest request) throws IOException { //5. establish sun Provided by the company jersey In bag Client object Client client = Client.create(); //6. Specify the address for uploading files , The address is web route WebResource resource = client.resource("http://192.168.58.252:8888/imgs/"+f.getOriginalFilename()); //7. Upload String result = resource.put(String.class,f.getBytes()); Map<String,String> map =new HashMap<>(); map.put("a",f.getOriginalFilename()); map.put("b",f.getContentType()); return map; } --> The front desk code <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> File upload page </title> <base href="<%=request.getContextPath()+"/"%>"> <script type="text/javascript" src="js/jquery-1.12.3.min.js"></script> <script type="text/javascript"> $(function () { $("#but1").click(function () { var file = $("#file")[0].files[0]; var formData = new FormData(); formData.append("f", file); $.ajax({ type: "post", url: "yjd/upLoad", data: formData, // important *** processData:false, contentType:false, success: function (result) { alert(result); // Local server image echo $("#sp1").html("<img src='http://localhost:8080/springmvc05/imgs/" + result.fileName + "' width='80px'/>"); // Remote server image echo //$("#sp1").html("<img src='http://192.168.58.252:8888/imgs/"+result.a+"' width='80px'/>"); $("#fileName").val(result.fileName); $("#contentType").val(result.contentType); }, error: function () { alert(" Request error !"); }, // Upload progress bar xhr: function() { var xhr = new XMLHttpRequest(); // Use XMLHttpRequest.upload Monitor the upload process , register progress event , Print in callback function event event xhr.upload.addEventListener('progress', function (e) { console.log(e); //loaded On behalf of how many //total What is the total number of delegates var progressRate = (e.loaded / e.total) * 100 + '%'; // The effect is achieved by setting the width of the progress bar $('.progress > div').css('width', progressRate); }) return xhr; } }); }); }); </script> <%-- Progress bar style --%> <style type="text/css"> .progress { width: 600px; height: 10px; border: 1px solid #ccc; border-radius: 10px; margin: 10px 0px; overflow: hidden; } /* The initial state sets the width of the progress bar to 0px */ .progress > div { width: 0%; height: 100%; background-color: yellowgreen; transition: all .3s ease; } </style> </head> <body> <form> <h2> File upload page </h2> <br/> <%-- get files --%> <input type="file" id="file"/> <%-- Upload files --%> <input type="button" value=" Upload files " id="but1"/> <span id="sp1"></span> <p> <%-- Progress bar --%> <div class="progress"> <div> </div> </div> </p> <p> <%-- Get the new name and file type of the uploaded file --%> <input type="text" id="fileName" name="fileName"/> <input type="text" id="contentType" name="contentType"/> <input type="button" value=" Submit " id="sub"/> </p> </form> </body> </html>
File download
--> front end function getData(index, size) { var name = $("#name").val(); $.ajax({ type: "post", url: "yjd/findMore", data: { name: name,index:index, size: size}, success: function (result) { totalPage = result.totalPageCount; current=result.index; $("#tb").empty(); $.each(result.list, function (i, e) { $("#tb").append("<tr height=\"40px\">\n" + " <td>" + e.id + "</td>\n" + " <td>" + e.name + "</td>\n" + " <td>" + e.price + "</td>\n" + " <td>" + e.production + "</td>\n" + " <td>" + e.fileName + "</td>\n" + " <td>" + e.fileType + "</td>\n" + " <td><img src='http://localhost:8080/springmvc06/imgs/" + e.fileName + "' width='80px'/></td>" + " <td><a href='yjd/downLoad?fileName=" + e.fileName + "&fileType=" + e.fileType + "'> download </a></td>" + " </tr>"); }); $("#anyOne").empty(); $.each(result.numbers, function (i, e) { $("#anyOne").append("<a href=\"javascript:void(0)\" οnclick='getData(e,2)'>" + e + " </a>"); }); }, error: function () { alert(" request was aborted !"); } }); --> Back end @RequestMapping("/yjd/downLoad") @ResponseBody public void downLoad(String fileName, String fileType, HttpServletResponse resp) throws IOException { // Set download to local resp.setHeader("Content-Disposition", "attachment;Filename=" + fileName + ""); resp.setContentType(fileType); // Get server-side resources InputStream inputStream = new URL("http://localhost:8080/springmvc06/imgs/" + fileName).openStream(); // Response to download file ServletOutputStream outputStream = resp.getOutputStream(); IOUtils.copy(inputStream, outputStream); }
SpringMVC Middle interceptor
The interceptor is aimed at each control unit (servlet)--> Belong to springMVC The interceptor executes three methods per request , Can get xml The configuration of the bean Execution order :preHandler(true)--> control unit -->postHandler( Before responding )-->afterCompletion( After the page loads ) Three rewrite methods work : -->preHandler: Encoding settings 、 Page upgrade maintenance jump 、 Login permission settings -->postHandler: Page comparison and upgrading 、 Malicious character substitution map Act as a scope , The front desk to use requestscope receive -->afterCompletion: Resources to shut down 、 rubbish --> Multi layer interceptor execution sequence :preHandler1-->preHandler2--> control unit -->postHandler2-->postHandler1 -->afterCompletion2-->afterCompletion1 -->springMVC To configure <mvc:interceptors> <!-- All control unit paths are blocked --> <!--<bean class="com.yjd.controller.FlowerController"></bean>--> <!-- Specify path interception --> <mvc:interceptor> <!-- Intercept path , There must be /--> <mvc:mapping path="/yjd/indexPage"/> <!-- Full name of interceptor class --> <bean class="com.yjd.interceptor.MyInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> --> Control layer @RequestMapping("/yjd/indexPage") public String indexPage(Map<String,String> map) { System.out.println(" Enter the control unit "); map.put("msg", " guns "); return "forward:/index.jsp"; } --> Interceptor package com.yjd.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; /** * @author: Ada * @date: 2021/6/16 10:50 */ public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; } // Not ajax Effective upon request @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { Map<String, Object> model = modelAndView.getModel(); String msg = (String) model.get("msg"); System.out.println(msg); if (msg.contains(" guns ")) { String s = msg.replaceAll(" guns ", "**"); model.put("msg", s); } System.out.println("postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); } }
边栏推荐
- 将文件流(InputStream)写入文件 将上传文件MultipartFile写到文件
- Countdown 3 days 𞓜 sofachannel 28 sofaark class isolation framework design
- Analysis methods of common problems in performance testing
- KusionStack 开源有感|历时两年,打破 “隔行如隔山” 困境
- Project interview questions
- 2022-2028 global linear LED lighting industry research and trend analysis report
- What's wrong with Android development today? Is the interview question I asked so difficult?
- Can I LINQ a JSON- Can I LINQ a JSON?
- 【线性代数】理解特征值和特征向量
- ERP system, compilation and learning
猜你喜欢
随机推荐
FreeRTOS semaphore review
LeetCode_栈_困难_394. 字符串解码
. Net C # Foundation (6): namespace - a sharp tool for organizing code
Creation of menu for wechat applet development
MySQL basic addition, deletion, modification and query exercise
Linux online installation of a neo4j diagram database
最长公共子序列和最长公共子串
SSM详解
【概率论】变量之间的相关性计算
MySQL基础 基础认知
Kusionstack has a sense of open source | it took two years to break the dilemma of "separating lines like mountains"
2022-2028 global linear LED lighting industry research and trend analysis report
Omit application reduces TS duplicate codes
Wechat applet - doodle Conference - conference release and my conference view
如何优雅地画一张图
2022-2028 global online code learning industry research and trend analysis report
Paper understanding [RL - exp replay] - an equivalence between loss functions and non uniform sampling in exp replay
SOFA Weekly | Kusion 开源啦、本周 QA、本周 Contributor
MySQL基础 子查询
【线性代数】理解正定矩阵和半正定矩阵







