JAVAWEB-NOTE04

Cool breeze AAA 2022-02-13 07:36:12 阅读数:861

javaweb-note04 javaweb note

1. unit12-mybatis frame

[ 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-oHYVv8ah-1638456215504)(JAVAWEB-NOTE04.assets/a0a2eb9fa872009998f7cd818925095d.png)]

Course plan :

1、MyBatis Quick start

2、MyBatis Addition, deletion, modification and query of data in the database

3、#{} The application of placeholders

4、 dynamic SQL Application

5、MyBatis Of Mapper Interface development

1.1 MyBatis brief introduction ( understand )


1.1.1 What is? MyBatis

MyBatis This is a apache An open source project of iBatis,2010 This project was initiated by apache software foundation Moved to google code, And renamed it MyBatis .2013 year 11 Month to migrate to Github.

MyBatis Is an excellent persistence layer framework , It's right jdbc To encapsulate the process of database operation , send Developers just need to focus on SQL In itself , Instead of having to deal with things like registered drivers 、 establish connection、 establish statement、 Manual setting of parameters 、 Result set retrieval, etc jdbc Complex process code .

Persistence layer : The layer that connects to and accesses the database is called the persistence layer , Such as jdbc MyBatis

Mybatis adopt xml Or the way of annotation All kinds of statement(statement、preparedStatemnt) To configure get up , And pass java Objects and statement Medium sql Map to generate the final execution sql sentence , Finally by mybatis Framework implementation sql And map the result to java Object and return .

All in all ,Mybatis Yes JDBC The process of accessing the database is encapsulated , To simplify the JDBC Code , solve JDBC Encapsulate the result set as Java The object's troubles .

The picture below is MyBatis Architecture diagram : Reference resources mybatis Encapsulation diagram of database day14 15

Yes set Methods are preferred set Method encapsulates information .

 Insert picture description here

 Insert picture description here

(1)mybatis-config.xml yes Mybatis Core profile for , Through the configuration, you can generate SqlSessionFactory, That is to say SqlSession factory

(2) be based on SqlSessionFactory Can generate SqlSession object

(3)SqlSession Is a both can send SQL To carry out , And return the result , Be similar to JDBC Medium Connection object , It's also Mybatis One of the most important objects in .

(4)Executor yes SqlSession The underlying object , Used to perform SQL sentence

(5)MapperStatement Object is also SqlSession The underlying object , Used to receive input maps (SQL Parameters in statement ), And do output mapping ( the SQL The result of the query is mapped to the corresponding result )

1.1.2 Why use MyBatis

reflection : Before we start , Think about how to pass JDBC Inquire about Emp All records in the table , And encapsulated in a List Returns... In the collection .( demonstration : Prepare the data 、 Guide pack 、 Import JDBC Program )

1、 Using traditional methods JDBC Access database :

(1) Use JDBC How big is it to access the database Quantity repeat code ( For example, register driver 、 Get the connection 、 Get the transmitter 、 Release resources, etc );

(2)JDBC There is no connection pool itself , Frequently create and close connections , Low efficiency ;( However, you can use a third-party connection pool, such as : c3p0)

(3)SQL It's written dead in the program , Once modified SQL, Need to recompile the class ;

(4) Query pair SQL Returned after execution ResultSet object , Need to be handled manually , Sometimes it's very troublesome ;

2、 Use mybatis The framework accesses the database :

(1)Mybatis Yes JDBC By the way , Can be simplified JDBC Code ;

(2)Mybatis It supports connection pool ( You can also configure other connection pools ), Therefore, the efficiency of the program can be improved ;

(3)Mybatis Yes, it will SQL Configure in mapper In file , modify SQL Just modify the configuration file , Class does not need to be recompiled .

(4) Query pair SQL Returned after execution ResultSet object ,Mybatis Will help us deal with , convert to Java object .

All in all ,JDBC All of the problems in the process ( Code cumbersome 、 There's too much duplicate code 、 Too many objects need to be manipulated 、 Release resources 、 It's too troublesome to deal with the results ), stay Mybatis Almost all of them have been solved in the framework !!

1.2 MyBatis Quick start


1.2.1 Prepare the data , Create libraries and tables

establish yonghedb library 、emp surface , And insert several records

-- 1、 Create database yonghedb database 
create database if not exists yonghedb charset utf8;
use yonghedb; -- choice yonghedb database 
-- 2、 Delete emp surface ( If there is )
drop table if exists emp;
-- 3、 stay yonghedb Create... In the library emp surface 
create table emp(
id int primary key auto_increment,
name varchar(50),
job varchar(50),
salary double
);
-- 4、 Go to emp In the table , Insert several records 
insert into emp values(null, ' Wang Haitao ', ' The programmer ', 3300);
insert into emp values(null, ' Qi Lei ', ' The programmer ', 2800);
insert into emp values(null, ' Liu peixia ', ' Programmers encourage teachers to ', 2700);
insert into emp values(null, ' Chen Zishu ', ' Department Director ', 4200);
insert into emp values(null, ' Liu Yujiang ', ' The programmer ', 3000);
insert into emp values(null, ' Dong Changchun ', ' The programmer ', 3500);
insert into emp values(null, ' Aoi Sora ', ' The programmer ', 3700);
insert into emp values(null, ' Han Shaoyun ', 'CEO', 5000);

1.2.2 Create a project , Import required jar package 、 Create test class

1、 establish Maven Of java engineering

 Insert picture description here

2、 Import junit、mysql、mybaits、log4j And so on

stay pom.xml Introduce relevant dependency packages into the file stay pom Right click in the blank space of the file Maven—Add Dependency( Add dependency ) dependency : rely on

ctrl+A+i Automatic alignment .

<dependencies>
<!-- junit unit testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version> //4.9 Maybe I can't get down , use 4.0
</dependency>
<!-- mysql drive , Connect mysql Must be needed jar package -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- mybatis Of jar package -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- Integrate log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>

3、 establish com.tedu.mybatis.TestMybatis01 Test class (class class ), And provide findAll Method ( Inquire about emp All employee information in the table ), The development steps are as follows :

 Insert picture description here

/** practice 1( Quick start ): Inquire about emp All employees in the table , Return to one List<Emp> aggregate * @throws IOException */
package com.tedu.mybatis;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 org.junit.Test;
import com.tedu.pojo.Emp;
/** * mybatis Introduction to : Inquire about yonghedb.emp All employee information in the table */
public class TestMybatis01 {

/* practice 1: Inquire about emp All employee information in */
@Test unit testing
public void testFindAll01() throws Exception {

//1. Read mybatis Core profile (mybatis-config.xml),Resources yes mybatis Tool class provided 
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2. Get through configuration information SqlSession Factory object 
SqlSessionFactory fac = new SqlSessionFactoryBuilder().build( in );
//3. obtain SQLSession object ( Open the connection to the database ) This session Talking to session It doesn't matter. 
SqlSession session = fac.openSession();
//4. perform SQL sentence , Return the processed result (EmpMapper.xml), Parameter is SQL The positioning identification of the statement is in addition to the query , Additions and deletions can be mixed But it is not recommended. Query one with selectone Multiple use selectList . Is a delimiter and cannot be omitted ( On the left is the file name On the right is id Value to locate the execution sql Which statement is )
List<Emp> list = session.selectList( "EmpMapper.findAll01" );
//5. Output results 
for (Emp emp : list) {

System.out.println( emp ); // Printing is the address value ? Because there is no rewriting toString Method 
}
}
}

mybatis Add, delete and change operations :

Run test method Right click —run as–JUnit Test

package com.tedu.mybatis;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
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 org.junit.Before;
import org.junit.Test;
import com.tedu.pojo.Emp;
/**
* Realization mybatis Add, delete and change operations
* Use mybatis Of #{} Place holder
* Use mybatis Of ${} Place holder
*/
public class TestMybatis02 {
private SqlSession session = null;
/* @Before How to annotate and mark , Will be in every @Test Annotation marks the method before execution
@After unit testing After performing this 2 The first method does not need to be checked , Just execute the test, and the method will automatically execute before and after him */
@Before
public void testBefore() throws Exception {
//1. Read mybatis Core profile (mybatis-config.xml),Resources yes mybatis Tool class provided ,// This configuration file is placed in the source directory , In the future, after compilation, it will be placed in the class directory , This method is to read the files in the directory , So we just need to read the file name . stay On the file ctr c You can directly copy the file name ctrl+v Copy where you need to .
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2. Get through configuration information SqlSession Factory object
SqlSessionFactory fac = new SqlSessionFactoryBuilder().build( in );
//3. obtain SqlSession object ( Open the connection to the database ), Parameters true Indicates setting auto commit transaction , The default value is false, Indicates manual submission This session Talking to session It doesn't matter.
session = fac.openSession( true ); // Declare on the class that the whole class can use
}
/* practice 2: New employee information : zhaoyun Security staff 6000
* Be careful :mybatis take jdbc The auto commit transaction of is turned off , Therefore, the transaction will be started by default , But because the transaction was not committed in the end
* So even if the data insertion operation is successful , But because it was not submitted , So the data will be rolled back , Not inserted into database .
Be careful :id Value will not be rolled back
increase , Delete , Change , The return value is the number of affected rows .
*/
@Test
public void testInsert02() {
// perform SQL sentence , Return execution result
int rows = session.insert( "EmpMapper.insert02" );
System.out.println( " Number of rows affected : "+rows );
// Commit transaction , It's too cumbersome to commit transactions manually every time , You can set mybatis Auto commit transaction !( In the above steps 3)
//session.commit(); Manual submission
}
/* practice 3: Modify employee information : zhaoyun bodyguards 20000 */
@Test
public void testUpdate03() {
int rows = session.update( "EmpMapper.update03" );
System.out.println( " Number of rows affected : "+rows );
}
/* practice 4: Delete name by ' zhaoyun ' The record of */
@Test
public void testDelete04() {
int rows = session.delete( "EmpMapper.delete04" );
System.out.println( " Number of rows affected : "+rows );
}
//=================== mybatis Place holder ===================
/* practice 5: Inquire about emp The table specifies id Employee information A placeholder to pass parameters */
@Test
public void testFindById05() {
Integer id = 1;
//sql Statement has a placeholder , You need to pass a parameter . Otherwise sql The statement is incomplete .
// Represents a query id by 3 Employee information
Emp emp = session.selectOne( "EmpMapper.findById05", id );
System.out.println( emp );
}
/* practice 6: New employee information : Zhang Fei Java Development Engineer 15000 Multiple placeholders pass parameters
increase , Delete , Change , insert 4 There are two ways to pass parameters , It can only be passed at most 2 individual . One is names+id Occupy , The other can only be occupied by one parameter .
solve : Encapsulate parameters into map In a collection or pojo object
*/
@Test
public void testInsert06() {
// Pass multiple parameters , take SQL The parameters in the statement are encapsulated in map Collection , then map Pass the collection to the past key To correspond to the name in the placeholder , The parameters used to distinguish the transfer are consistent with the corresponding placeholders .
//Map map = new HashMap();
//map.put( "name" , " Zhang Fei " );
//map.put( "job" , "Java Development Engineer " );
//map.put( "salary" , 15000 );
// session.insert( "EmpMapper.insert06", map );
// You can also SQL The parameter values in the statement are encapsulated in pojo In the object 3oooo Is an integer that can be reduced to double Type but cannot be converted to double Type of packaging , Add one d Change to decimal More in this way Because in the future, the written data will be transmitted from the front-end page to the server , To receive these parameters transmitted from the front end to the server, we use springmvc frame , It has a parameter binding mechanism , It can be very simple encapsulated into pojo In the object , So more in this way .( The assignment of this place can directly call the construction method , You can also write a structure with parameters , But be careful to write a parameterless constructor )
Emp emp =new Emp(null, " Liu bei ",“CEO”,30000d);
session.insert( "EmpMapper.insert06", emp );
}
/* practice 7: Modify employee information : Zhang Fei Architects 25000 */
@Test
public void testUpdate07() {
// take SQL The parameters in the statement are encapsulated in map Collection , then map Pass the collection to the past
//Map map = new HashMap();
//map.put( "name" , " Zhang Fei " );
//map.put( "job" , " Architects " );
//map.put( "salary" , 25000 );
//session.update( "EmpMapper.update07" , map );
Emp emp =new Emp(null, " Zhang Fei ",“ Chairman of the board of directors ”,35000d);
session.update( "EmpMapper.insert07", emp );
}
/* practice 8( Do it yourself ): Delete emp The table specifies id Employee information */
@Test
public void testDelete08() {}
}
/* #{} Place holder : amount to JDBC The question mark in (?) Place holder , It is for SQL Parameter value in statement ( Inserted value or Column = value The values in are parameter values )
* To carry on the placeholder , In most cases, you still use #{} Place holder , Can prevent SQL Injection attack !
* #{} If there is only one placeholder , Parameters can be passed directly to SQL sentence , Don't package into POJO Object or map aggregate
* ${} Place holder : It's for SQL fragment (SQL A paragraph in a statement ) To carry on the placeholder , Pass the parameters in the future , Is a direct substitute for ${} Place holder , Splicing
* stay SQL sentence , Because it's a direct splice , I won't do anything about it , Therefore, there may be SQL Injection attack !
* ${} Placeholder even if there is only one , You also need to encapsulate the parameter values into POJO Object or map aggregate , And pass it on to SQL sentence because : The reason is to practice 9 in
* /
/* practice 9: Dynamically specify the columns to display -- Only use ${} Place holder
* [] Number (id) [√] full name [√] occupation [√] salary The displayed columns are constantly changing .
* select id,name from emp;
* select id,name,job from emp;
* select id,name,job,salary from emp;
* select name,job from emp;
* ... */
@Test
public void testFindAll09() {
Map map = new HashMap();
map.put( "cols", "name,job" ); // The result of the query is a list aggregate
//List<Emp> list = session.selectList( "EmpMapper.findAll09", "id,name" );
// If you pass it directly, it will think that you pass it to an object , It will look for getcols Method ( Write according to your placeholder name cols I can splice getcols Method ), But there is no such method on the string, so an error will be reported .
List<Emp> list = session.selectList( "EmpMapper.findAll09", map );
for (Emp emp : list) {
System.out.println( emp );
}
}
/* practice 10: according to name Fuzzy query emp surface -- have access to #{}, You can also use ${} */
@Test
public void testFindByName10() {
List<Emp> list = session.selectList( "EmpMapper.findByName10", "% Liu %" );
for (Emp emp : list) {
System.out.println( emp );
}
}
/* practice 11: according to name Fuzzy query emp surface -- have access to #{}, You can also use ${}
${} Even if the placeholder needs to pass only one parameter, it must be passed in first map Encapsulated in a collection */
@Test
public void testFindByName11() {
Map map = new HashMap();
map.put( "name", " Liu " ); // There are already... On both sides % The no. , This place can spread % Or not , Because even if passed, it also represents one or more characters , Add a few more, the effect is the same .
List<Emp> list = session.selectList( "EmpMapper.findByName11", map );
for (Emp emp : list) {
System.out.println( emp );
}
}
/* practice 12: Query employee information according to salary
* select * from emp -- The minimum salary and the maximum salary are not transmitted
* select * from emp where salary >= #{minSal} -- Only the minimum salary
* select * from emp where salary <= #{maxSal} -- Only the highest salary
* select * from emp where salary>= #{minSal} and salary<=#{maxSal}
* -- Both the minimum wage , Also passed the highest salary
Advantages and disadvantages : If here , If there are no dynamic tags , You need to write 4 strip sql sentence . Then you need to judge the parameters in the program .
But with dynamic sql Just write one label
*/
@Test
public void testFindBySal12() {
Map map = new HashMap();
map.put("minSal", 3000); // Pass on the minimum salary
map.put("maxSal", 5000); // Pass on the highest salary
List<Emp> list = session.selectList( "EmpMapper.findBySal13", map );
for (Emp emp : list) {
System.out.println( emp );
}
}
/* practice 14: According to the employee's id Batch delete employee information */
@Test
public void testDeleteByIds14() {
Integer[] ids = {1,3,5,7};
session.delete("EmpMapper.deleteByIds14", ids);
}
/* practice 15: According to the employee's id Batch update employee information
take id by 2、4、6、8 The salary of our employees has been increased on the original basis 1000 */
@Test
public void testUpdateByIds15() {
Integer[] ids = {2,4,6,8}; // Of employees who are going to get a raise id value
Double money = 1000.0; // The number of salaries to be raised
Map map = new HashMap(); // Because you have to save 2 Two parameters, so use map The collection is encapsulated
map.put( "ids" , ids );
map.put( "money" , money );
session.update( "EmpMapper.updateByIds15", map );
}
}

1.2.3 add to mybatis-config.xml file

1、 stay src/main/resources Under the table of contents ( This directory is used to store configuration files ), establish mybatis-config.xml file MyBatis Core profile for

It's in this directory Right click —new----other— Search for xml file Choose XML File—next Write the file name

 Insert picture description here

2、mybatis-config.xml The file configuration is as follows : Can point source Enter edit mode

mybatis-config The file header information is as follows : Note that incorrect format comments are added for convenience .

<?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 Global configuration file for -->
<configuration >
Under this label alt+/ If there is a net, there will be a prompt , But there are also cases where there is no prompt on the Internet .
Reference resources : Extended content
</configuration>

mybatis-config The detailed configuration of the file is as follows : These labels don't need to remember , Just remember his Just use what you need springboot Can achieve 0 To configure

<?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>
<!-- 1. Configure the development environment : id Property specifies a name for the current environment ,default Property specifies which environment to use There may be multiple environments -->
<environments default="test">
<environment id="test">
<!-- 1.1. Configure transaction management mode type="JDBC|MANAGED" JDBC: Give the business to JDBC management MANAGED: Manage your own business ( Not recommended ) -->
<transactionManager type="JDBC" />
<!-- 1.2. Configure data sources ( Connection pool ) type: Specify the connection pool method , POOLED: Use connection pool Can improve the efficiency of the program , UNPOOLED Indicates that the connection pool is not used , JNDI: Not commonly used -->
<dataSource type="POOLED"> // This is a name The value is fixed and cannot be changed , The one on the right looks at the database you are connected to
<property name="driver" value="com.mysql.jdbc.Driver"/> //driver: The driver
<property name="url" value="jdbc:mysql:///yonghedb? characterEncoding=utf-8"/> // url: website
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 2. Import XxxMapper.xml file , Read this document in the future and take it home maper file resource Property points to the class directory ,mapper The file is stored in the source directory , When compiled, it will Output to the class directory direct ctr c v You can directly copy the file name on the file -->
<mappers>
<mapper resource="EmpMapper.xml"/> Many are writing one mapper label
</mappers>
</configuration>

1.2.4 add to EmpMapper.xml file

1、 stay src/main/resources Under the table of contents , establish EmpMapper.xml file ( Mapping files for entity classes )

 Insert picture description here

2、EmpMapper.xml The file configuration is as follows :

EmpMapper The file header information is as follows :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <!-- This is a description document , Regulations xml The specification required by the document -->
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- Different Mapper Of documents namespace The value should be unique Pass in the program [ namespace + id ] Locate which one you want to execute SQL sentence -->
<mapper namespace="">
</mapper>

EmpMapper The detailed configuration of the file is as follows : add to sql sentence

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" <!-- documentation , Regulations xml The writing standard of the document -->
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="EmpMapper">
<!-- practice 1: Inquire about emp All employee information in select The tag is used to write the query type SQL sentence ,insert/delete/update The tag is used to write the addition, deletion and modification type SQL sentence id Attribute is the attribute that must exist for each tag , Used to specify a unique number , Future and namespace Cooperate to locate the... To be executed SQL sentence So every SQL Labeled id Values cannot be repeated ! resultType Attributes can only be used in select On the label , Used to specify what type of , To encapsulate the results of the query ( Let's specify this type , Is a class that encapsulates information ) for example : Use Emp Class to encapsulate employee information , resultType Point to Emp The fully qualified class name of the class ( Package name + Class name ) Employee class encapsulates employee information List<Emp>: What he returns is a set. Why not specify a set , If you return an object, you can use a collection , If you return a collection, you only need to specify the generics in the collection ( Because more than one object is returned, it is encapsulated in the collection , Even if the final result returned is a collection ,resultType You only need to specify the generics in the collection ) Such as : It returns an object :resultType="List<com.tedu.pojo.Emp>" Select the class name and right-click --Copy Qualified Name The full name of the replication class defines the category , After copying ctrl Select this restricted category Click the mouse and an underline appears, indicating that the configuration is successful -->
<select id="findAll01" resultType="com.tedu.pojo.Emp">
select * from emp
</select>
<!-- practice 2: New employee information : zhaoyun Security staff 6000 id Self increment is set without setting the value to null-->
<insert id="insert02">
insert into emp value(null,' zhaoyun ',' Security staff ',6000)
</insert>
<!-- practice 3: Modify employee information : zhaoyun bodyguards 20000 -->
<update id="update03">
update emp set job=' bodyguards ',salary=20000
where name=' zhaoyun '
</update>
<!-- practice 4: Delete name by ' zhaoyun ' The record of -->
<delete id="delete04">
delete from emp where name=' zhaoyun '
</delete>
// This is not written dead, add, delete, change and check
<!--mybatis The placeholder in is equivalent to jdbc Of ? Place holder #{} The output to the console will become ? Place holder A name must be written in parentheses , Can't be empty -->
<!-- practice 5: Inquire about emp The table specifies id Employee information -->
<select id="findById05" resultType="com.tedu.pojo.Emp">
select * from emp where id=#{id}
</select>
<!-- practice 6: New employee information : Zhang Fei Java Development Engineer 15000 If you use map encapsulation SQL Parameters in statement , Make sure that #{} Name and... In placeholder map In the collection key bring into correspondence with , Because I'm going to map After the collection is passed in ,mybaties The bottom layer of the framework will be based on #{} The name in the placeholder is used as key, To map Take out the corresponding value, If there is no counterpart key, The final value is null -->
// If you use EMP object (pojo) encapsulation SQL Parameters in statement ,(1) Make sure that #{} Name in placeholder stay Emp There is a corresponding... In the object getXxx Method ;(2) perhaps #{} The name in the placeholder is in Emp Object with the same name Value through private attribute, but not through get The method has high efficiency If there are all, it will give priority to get Method , The private bottom layer also needs to set permissions, which makes it less efficient .( The permissions have been set at the bottom of the framework , We just need to bring it to use )
<!--id Property is set to auto increment , So here it says null value -->
<insert id="insert06">
insert into emp value(null, #{name}, #{job}, #{salary})
</insert>
<!-- practice 7: Modify employee information : Zhang Fei Architects 25000 -->
<update id="update07">
update emp set job=#{job}, salary=#{salary}
where name=#{name}
</update>
<!-- practice 9: Dynamically specify the columns to display getCols() -->
<select id="findAll09" resultType="com.tedu.pojo.Emp">
select ${cols} from emp
</select>
<!-- practice 10: according to name Fuzzy query emp surface ~ Use #{} Place holder % Vague words % xml Notes cannot be written (--) Will report a mistake , He is particularly strict with notes -->
<select id="findByName10" resultType="com.tedu.pojo.Emp">
select * from emp where name like #{name}
</select>
<!-- practice 11: according to name Fuzzy query emp surface ~ Use ${} Place holder Vague words Liu -->
<select id="findByName11" resultType="com.tedu.pojo.Emp">
select * from emp where name like '%${name}%'
</select>
<!-- practice 12: Query employee information according to salary (&lt; The less than sign ,&gt; Indicates greater than ) ( Use if label ) Why use escape characters : because xml The file engine will treat it as The beginning symbol of the label < Not less than < , So we use escape characters instead of The greater than sign doesn't need to be escaped Be careful :resultType Labels can only be used for select On the label ( Most use ),updadte,delete,insert Out-of-service test Used to designate a boolean value -->
<select id="findBySal12" resultType="com.tedu.pojo.Emp">
select * from emp
where 3=3 // You can add an equation to avoid if the user 2 None of them , All for null The code won't execute, but there are multiple where, Grammar can report errors ,where It can't be deleted, because in case of transmission, it also needs to have where, So just write a formula you want to wait for to ensure where Clause will execute
<if test="minSal != null">
and salary >= #{minSal} // Add a conjunction in the middle and Different conditions use and Connect . The range of the query is between the maximum and minimum .
</if>
<if test="maxSal != null">
and salary &lt;= #{maxSal}
</if>
</select>
<!-- hold where3=3 Switch to where label practice 13: Use where label If the user passes in parameters where Clause takes effect It will help you automatically generate an all uppercase WHERE keyword , And will automatically remove the following redundant and Symbol , So write one more in this place and No errors reported . This place doesn't have to write 3=3 了 , Because the following clause does not take effect, it will not generate WHERE keyword -->
<select id="findBySal13" resultType="com.tedu.pojo.Emp">
select * from emp
<where>
<if test="minSal != null">
and salary >= #{minSal}
</if>
<if test="maxSal != null">
and salary &lt;= #{maxSal}
</if>
</where>
</select>
<!-- practice 14: According to the employee's id Batch delete employee information test foreach label delete from emp where id in(1,3,5,7) It means that if one of the conditions is met, it will execute Take these uncertain contents Can pass foreach label Put these id Go through it use "," separate Reuse () wrap up If you pass an array collection It's a fixed value : array Write list Means to pass a list aggregate open Specify the starting symbol close Specify the end symbol In the middle is id Value cannot be written dead , Use a placeholder to write a name to receive id value , Every element in the array . Placeholder name and item Keep the same name separator: Specify the separator item: The name of the placeholder specified should be consistent up and down . The above is to pass a parameter 2 Two parameters can be used map aggregate -->
<delete id="deleteByIds14">
delete from emp where id in
<foreach collection="array" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- practice 15: According to the employee's id Batch update employee information take id by 2、4、6、8 The salary of our employees has been increased on the original basis 1000 -->
<update id="updateByIds15">
update emp set salary=salary + #{money} // Pass on 2 When the parameters , It needs to be encapsulated into map The values in the set should be the same as map Of key bring into correspondence with , Only in this way can it be based on key find value Value It's a map How to find the array in the collection ?
This array is saved to map Collection , And in this set key Representative value The value is ids, That's the name of this array , therefore collection You just need to save map Medium key, It represents the name of this array .
where id in
<foreach collection="ids" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

1.2.5 Add and write Emp Entity class

Be careful : In the current example ,Emp The attribute in the class and the field name of the database table must be consistent , Otherwise, you will not be able to encapsulate the result set into Java In the object .

stay src/main/java Create under directory com.tedu.pojo.Emp class (class), And edit Emp class : Provide private properties and corresponding getter Method 、setter Method , And rewrite toString Method Encapsulate information into In this class . For example, the information to be added . More enterprises use this method , use Map Encapsulating collections also requires adding data to methods one by one .

package com.tedu.pojo;
/** * Used to encapsulate employee information * Declare variables in entity classes , Try to use the packaging type , Can avoid ambiguity ! Basic types The default value is 0 The reference type is nuLl such as : Encapsulate students' grades : Some students have passed the exam , Some students passed the exam 0 branch , Some didn't go to the exam . So how to distinguish ? The test result is 0 The assigned score is 0. No test, no assignment, but its default value is 0, There's no way to tell , With his packaging type, we can distinguish , If you don't go to the exam, you won't be assigned as null. So try to use the packaging type . private double score The default is 0 private Double salary The default is null * Emp The attribute names in the class should be the same as emp The column names in the table are consistent ( If it's not consistent , It will cause data encapsulation failure , But it can solve ) */
public class Emp {

// Yes set Method , priority of use set Method to assign a value to an attribute , No, set Method can set the permissions of private properties , Assign the same private attribute as the column name 
// Provide private properties 
private Integer id; // Private properties cannot be assigned You need to set permissions It's better to use set The efficiency of method assignment is high 
private String name;
private String job;
private Double salary;
// Provide nonparametric construction 
public Emp() {
 // If you don't provide it, you will report an error because mybatis The bottom layer is created by reflection emp object , Not provided will overwrite the original construction method , Can't create object . So keep a habit of no participation and provide yourself .
System.out.println(" The nonparametric construction performs ");
}
// There are parameter constructors 
public Emp(Integer id,String name,String job,Double salary){

this.is=id;
this.name=name;
this.job=job;
this.salary=salary;
}
// Provide the corresponding get and set Method 
public Integer getId() {

return id;
}
public void setId(Integer id) {

this.id = id;
}
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public String getJob() {

return job;
}
public void setJob(String job) {

this.job = job;
}
public Double getSalary() {

return salary;
}
public void setSalary(Double salary) {

this.salary = salary;
}
// rewrite toString Method 
@Override
public String toString() {

return "Emp [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
}
}

1.2.6 Implement the test class , And test the

1、 Realization findAll Method , The code is as follows :

/** practice 1( Quick start ): Inquire about emp All employees in the table , Return to one List<Emp> aggregate * @throws IOException */
@Test
public void findAll() throws IOException {

//1. Read mybatis Core profile for (mybatis-config.xml)
InputStream in = Resources
.getResourceAsStream("mybatis-config.xml");
//2. Get a through configuration information SqlSessionFactory Factory object 
SqlSessionFactory fac =
new SqlSessionFactoryBuilder().build( in );
//3. Get one through the factory SqlSession object 
SqlSession session = fac.openSession();
//4. adopt namespace+id Find the sql Statement and execute sql sentence 
List<Emp> list = session
.selectList("EmpMapper.findAll");
//5. Output results 
for(Emp e : list) {

System.out.println( e );
}
}

2、 perform findAll Method , The output is :

Emp [id=1, name= Wang Haitao , job= The programmer , salary=3300.0]
Emp [id=2, name= Qi Lei , job= The programmer , salary=2800.0]
Emp [id=3, name= Liu peixia , job= Programmers encourage teachers to , salary=2700.0]
Emp [id=4, name= Chen Zishu , job= Department Director , salary=4200.0]
Emp [id=5, name= Liu Yujiang , job= The programmer , salary=3000.0]
Emp [id=6, name= Dong Changchun , job= The programmer , salary=3500.0]
Emp [id=7, name= Aoi Sora , job= The programmer , salary=3700.0]
Emp [id=8, name= Han Shaoyun , job=CEO, salary=5000.0]

1.3 MyBatis Entry details

1.3.1 mybatis-config.xml The configuration 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">
<!-- MyBatis Global configuration file for -->
<configuration >
<!-- 1. Configuration environment , Multiple environments can be configured ( such as :develop Development 、test test ) -->
<environments default="develop">
<environment id="develop">
<!-- 1.1. Configure transaction management mode :JDBC/MANAGED JDBC: Give the business to JDBC management ( recommend ) MANAGED: Manage your own business -->
<transactionManager type="JDBC"></transactionManager>
<!-- 1.2. Configure data sources , The connection pool JNDI/POOLED/UNPOOLED JNDI: Deprecated POOLED: Use connection pool ( recommend ) UNPOOLED: Do not use connection pool -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 2. Import Mapper The configuration file , If mapper There are multiple files , You can go through more than one mapper Tag import -->
<mappers>
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>

environments label : Multiple tags can be configured inside the tag environment, That is, multiple environments , Each environment can be configured differently or connected to different databases . for example , Development 、 test 、 Production environments may require different configurations , The connected databases may also be different , So we can configure three environment, Corresponding to the above three different environments .

But remember ,environment You can configure multiple , But only one of them can be used in the end !

environment label : Various configuration information can be configured internally , Transaction configuration and data source management are described below .

transactionManage label : Transaction management configuration ,mybatis There are two ways to manage transactions in , That is to say

type="[JDBC|MANAGED].

JDBC: This configuration is used directly JDBC Commit and rollback settings for , It relies on connections from data sources to manage transaction scope . Recommended .
MANAGED: This configuration does little . It never commits or rolls back a connection . You need to manually add and manage . It is not recommended to use .

dataSource label : data source , That is, connection pool configuration . here type Specify the data source type , There are three built-in types :JNDI、POOLED、UNPOOLED

JNDI: Deprecated , It is not recommended to use !
POOLED: Use connection pool ,mybatis The connection pool will be created , And get the connection from the connection pool to access the database , After the operation , Will return the connection to the connection pool .
UNPOOLED: Do not use connection pool , This method is suitable for simple applications with only a small number of concurrent users .

mappers label : Used to import mapper The location of the file , Multiple can be configured mapper, That is, you can import multiple mapper file .

1.3.2 EmpMapper.xml The configuration file

<?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">
<!-- Different Mapper Of documents namespace The value should be unique Pass in the program [ namespace + id ] Locate which one you want to execute SQL sentence -->
<mapper namespace="EmpMapper">
<!-- adopt select、insert、update、delete The tag declares the... To be executed SQL -->
<!-- practice 1: Inquire about emp All employee information in the table resultType Specify what type of query results will be encapsulated Even if the final result is a collection (List<Emp>),resultType You only need to specify the generics in the collection ! -->
<!-- Specify what type of class to use to encapsulate the information of query data -->
<select id="findAll" resultType="com.tedu.pojo.Emp">
select * from emp
</select>
</mapper>

(1) The first 1 Line is xml The document declaration of , For declaration xml Version and code of

(2) The first 2、3、4 That's ok , Introduced xml Constraint document , At present xml The document will follow mybatis-3-mapper.dtd Write the rules required by the document .

(3)Mapper label : Root tag , among namespace( The name space , It's also called a namespace ), Requirements cannot be repeated . Pass in the program 【namespace + id 】 Locate which one you want to execute SQL sentence

(4)select label : Used to specify various to be executed in the future SQL sentence . Attributes can be declared on the tag , The following describes the common properties :id、resultType、resultMap

  • id attribute : The required value cannot be repeated . In the future SQL when , Can pass 【namespace + id】 Find the specified SQL And implement .

  • resultType attribute : From this SQL Statement returns the fully qualified name of the class of the desired type ( Package name + Class name ). Note that if it is a set case , That should be the type that a collection can contain , Not the set itself . ( Query with )

    In short ,resultType Control query SQL The type of the returned value after execution or the generic type in the collection , For example, query emp A single record in the table , The return value is one Emp object , therefore ,resultType=“com.tedu.pojo.Emp”;

    If you inquire emp Multiple records in the table , The return value is one List, here resultType The value of should be generic in the collection , therefore resultType=“com.tedu.pojo.Emp”;

  • resultMap attribute : Complex object structure ( For example, multi table Association query, etc ). Use resultType or resultMap, But not at the same time .

1.4 MyBatis Additions and deletions


1.4.1 New employees

1、 edit EmpMapper.xml file , Add... Corresponding to the new employee sql.

<!-- practice 2: New employee information : zhaoyun Security staff 6000 There is no need to specify... On the label of addition, deletion and modification resultType, Because the return values are int type -->
<update id="insert" >
insert into emp value(null, ' zhaoyun ', ' Security staff ', 6000)
</update>

2、 To write TestMybatis class , add to testInsert Method , Realize the operation of adding new employees .

/** practice 2: New employee information : zhaoyun Security staff 6000 */
@Test
public void testInsert() {

// perform sql sentence , Return execution result 
int rows = session.update("EmpMapper.insert");
// Commit transaction 
session.commit();
System.out.println(" Number of rows affected : "+rows);
}

1.4.2 Modify employees

1、 edit EmpMapper.xml file , Add... Corresponding to the new employee sql.

<!-- practice 3: Modify employee information : zhaoyun bodyguards 20000 -->
<update id="update">
update emp set job=' bodyguards ', salary=20000 where name=' zhaoyun '
</update>

2、 To write TestMybatis class , add to testUpdate Method , Realize the modification of employee information .

/** practice 3: Modify employee information , Will Zhao Yun's job Change it to ' bodyguards ',salary Change it to 20000 */
@Test
public void testUpdate() {

// perform sql sentence , Return execution result 
int rows = session.update("EmpMapper.update");
// Commit transaction 
session.commit();
System.out.println(" Number of rows affected :"+rows);
}

1.4.3 Delete employee

1、 edit EmpMapper.xml file , Add... Corresponding to the new employee sql.

<!-- practice 4: Delete name by ' zhaoyun ' The record of -->
<update id="delete">
delete from emp where name=' zhaoyun '
</update>

2、 To write TestMybatis class , add to testDelete Method , Delete employees .

/** practice 4: Delete name by ' zhaoyun ' The record of */
@Test
public void testDelete() {

// perform sql sentence , Return execution result 
int rows = session.update("EmpMapper.delete");
// Commit transaction 
session.commit();
System.out.println(" Number of rows affected :"+rows);
}

1.5 mybatis Placeholder in

1.5.1 #{} Place holder

In the above operation of adding, deleting, modifying and querying ,SQL The value in the statement is written dead in SQL Statement , And in actual development , The value here is often the value submitted by the user , So here we need to put SQL Replace the dead value in with a placeholder .

stay mybatis There are two placeholders in the , Namely #{} Place holder and ${} Place holder : Pass a name inside

  • #{}: amount to JDBC The question mark in (?) Place holder , Is for SQL The parameter value in the statement is occupied , Most of the time it's used #{} Place holder ; And when the #{} A place holder is a place holder for a string or date type value , When the parameter value is passed in to replace the placeholder , It will be used to escape ( Add... To both sides of a string or date type value Single quotation marks );

     stay mapper In file : select * from emp where name=#{name}
    When the program is executed : select * from emp where name=?
    Parameters : Wang Haitao , Pass in parameters to , Replace placeholders
    select * from emp where name= Wang Haitao ; -- error 
    select * from emp where name=‘ Wang Haitao ’; -- correct 
    
  • ${}: Is for SQL fragment ( character string ) To carry on the placeholder , It's coming from SQL The fragments are spliced directly in ${} Where the placeholder is located , There will be no escape processing .( Because the parameters are directly spliced into SQL In the sentence , So it may trigger SQL Injection attack problem )

    It should be noted that : Use ${} The placeholder is SQL When a fragment in a statement takes place , Even if there is only one place holder , There is only one parameter to be passed , The parameters will also need to be passed first !

practice 5: Inquire about emp The table specifies id Employee information

stay mapper In the file SQL sentence :

<!-- practice 5: Inquire about emp The table specifies id Employee information -->
<select id="findById" resultType="com.tedu.pojo.Emp">
select * from emp where id=#{id}
</select>

Java Code implementation :

/** practice 5: Inquire about emp The table specifies id Employee information */
@Test
public void testFindById() {

// perform sql sentence , Return execution result 
Emp emp = session.selectOne( "EmpMapper.findById", 1 );
System.out.println( emp );
}

practice 6: New employee information : Zhang Fei Java Development Engineer 15000

stay mapper In the file SQL sentence :

<!-- practice 6: New employee information : Zhang Fei Java Development Engineer 15000 If you pass map Set transmission parameters , You need to ensure that the variable name in the placeholder and map In the collection key bring into correspondence with If you pass pojo Object transfer parameters , You need to ensure that the variable name in the placeholder Keep consistent with the property name in the object , Or in pojo There is a corresponding getXxx Method -->
<update id="insert2">
insert into emp values (null, #{name}, #{job}, #{salary})
</update>

Java Code implementation :

/** practice 6: New employee information : Zhang Fei Java Development Engineer 15000 */
@Test
public void testInsert2() {

// Encapsulate the parameters to be transferred into map Collection 
//Map map = new HashMap();
//map.put("name", " Zhang Fei ");
//map.put("job", "Java Development Engineer ");
//map.put("salary", 15000);
// You can also encapsulate the parameters to be transmitted into Emp In the object 
Emp emp = new Emp();
emp.setName(" Guan yu 123");
emp.setJob(" Security staff ");
emp.setSalary(8000.0);
// perform sql sentence 
intsession rows = session.update("EmpMapper.insert2", emp);
// Commit transaction 
session.commit();
System.out.println( " Number of rows affected : "+rows );
}

practice 7: Modify employee information : Zhang Fei Architects 25000

stay mapper In the file SQL sentence :

<!-- practice 7: Modify employee information : Zhang Fei Architects 25000 -->
<update id="update2">
update emp set job=#{job}, salary=#{salary}
where name=#{name}
</update>

Java Code implementation :

/** practice 7: Modify employee information : Zhang Fei Architects 25000 */
@Test
public void testUpdate2() {

// Encapsulate the parameters to Emp In the object 
Emp emp = new Emp();
emp.setName(" Zhang Fei ");
emp.setJob(" Architects ");
emp.setSalary(25000.0);
// perform sql sentence 
intsession rows = session.update("EmpMapper.update2", emp);
// Commit transaction 
session.commit();
System.out.println(" Number of rows affected : "+rows);
}

practice 8: Delete emp The table specifies id Employee information

mapper File configuration :

<!-- practice 8: Delete emp The table specifies id Employee information -->
<insert id="delete2" parameterType="String">
delete from emp where id=#{id}
</insert>

java Code example :

/* practice 8: Delete emp The table specifies id Employee information */
public void testDelete2() throws IOException{

......
// perform SQL sentence 
int rows = session.delete("EmpMapper.delete2", 1);
// Commit transaction 
session.commit();
System.out.println(" Number of rows affected :"+rows);
}

In the above addition, deletion, modification and query exercise , When SQL The parameter values contained in the statement are passed , stay SQL In the statement, we will pass #{} Placeholders for placeholders , stay SQL When the statement is actually executed , Then replace the passed value with SQL Placeholders in statements .

Actually ,#{} Namely JDBC The question mark in (?) Place holder , So for safety reasons , During execution, the passed string and value with high date type will be translated .

for example : The query name Employee information ,SQL Statement for :

select * from emp where name=#{name}

In fact, it's equivalent to JDBC in : select * from emp where name=?,

If the passed parameter value is : Wang Haitao , So the final execution SQL Statement for :

-- The parameter is escaped while replacing the placeholder ( Single quotes are placed around the value )
select * from emp where name=' Wang Haitao '

1.5.2 ${} Place holder

So if we don't pass a parameter value , It is a SQL What about the clip ?

for example : In the query , We want to dynamically pass the columns of the query :

select #{columns} from emp

At this time, it should be a SQL fragment , Different from the above parameter values , If you still use it at this time #{}, It will also be translated as above :select 'id,name,job' from emp, This is not what we want to see !

If you don't want it to come SQL The fragment is translated , But directly spliced in SQL In the sentence , So here you can use ${}, for example :

select ${
columns} from emp

After splicing :select id,name,job from emp

practice 9: Dynamically specify the columns to query

stay mapper In the file SQL sentence :

<!-- practice 9: Dynamically specify the columns to display -->
<select id="findAll2" resultType="com.tedu.pojo.Emp">
select ${cols} from emp
</select>

java Code example :

/** practice 9: Dynamically specify the columns to query */
@Test
public void testFindAll2() {

Map map = new HashMap();
//map.put("cols", "id, name");
//map.put("cols", "id, name, salary");
map.put("cols", "id,name,job,salary");
// perform sql sentence , Return results 
List<Emp> list = session.selectList("EmpMapper.findAll2", map);
// Output results 
for ( Emp e : list ) {

System.out.println( e );
}
}

Example 2: according to name Fuzzy query emp surface

stay mapper In the file SQL sentence :

<!-- practice 10: according to name Fuzzy query emp surface -->
<select id="findAll3" resultType="com.tedu.pojo.Emp">
select * from emp
where name like '%${name}%'
</select>
<!-- practice 11: according to name Fuzzy query emp surface -->
<select id="findAll4" resultType="com.tedu.pojo.Emp">
select * from emp
where name like #{name}
</select>

Java Code implementation :

/** * practice 10: according to name Fuzzy query emp surface * '% king %' '% Liu %' */
@Test
public void testFindAll3() {

// Encapsulate the parameters to map Collection 
Map map = new HashMap();
map.put("name", " tao ");
// perform sql, Return results 
List<Emp> list = session.selectList("EmpMapper.findAll3", map);
// Output results 
for (Emp emp : list) {

System.out.println( emp );
}
}
/** * practice 11: according to name Fuzzy query emp surface * '% king %' '% Liu %' */
@Test
public void testFindAll4() {

// Encapsulate the parameters to map Collection 
Map map = new HashMap();
map.put("name", "% Liu %");
// perform sql, Return results 
List<Emp> list = session.selectList("EmpMapper.findAll4", map);
// Output results 
for (Emp emp : list) {

System.out.println( emp );
}
}

It should be noted that , In passing ${} The corresponding value is , Even if there is only one parameter , You also need to store the value in map Collection !!

summary : In most cases, use #{} Place holder , and ${} Used mostly for SQL Segment space occupying !

1.6 dynamic SQL label


1.6.1 if、where label

  • <if> label : It's based on test attribute The value of the Boolean expression in , So as to decide whether to carry out the SQL fragment . If the result is true, Then execute it SQL fragment ; If the result is false, Then we don't implement any of them SQL fragment

    For example, it is used to query based on salary range SQL sentence .

  • <where> label : Used for the inclusion of SQL Search for fragments , Can be generated when needed where Keyword capitalization , And when necessary, it will eliminate redundant conjunctions ( such as and perhaps or)

 Insert picture description here

practice 12: Query employee information according to salary (if label )

  • <if> label : It's based on test attribute The value of the Boolean expression in , So as to decide whether to carry out the SQL fragment . If the result is true, Then execute it SQL fragment ; If the result is false, Then we don't implement any of them SQL fragment

stay mapper In the file SQL sentence :

<!-- practice 12: Query employee information according to salary * If there are no parameters , Do not perform where Clause , Query all employees by default : * select * from emp * If there is only minSal( namely minSal Not for null), be : * ... where salary > minSal * If there is only maxSal( namely maxSal Not for null), be : * ... where salary < maxSal * If the parameter has minSal、maxSal( namely minSal、maxSal Not for null), be : * ... where salary > minSal and salary < maxSal -->
<select id="findAllBySal" resultType="com.tedu.pojo.Emp">
select * from emp
where 1=1
<if test="minSal != null">
and salary>#{minSal}
</if>
<if test="maxSal != null">
and salary <![CDATA[ < ]]> #{maxSal}
</if>
</select>

Java Code implementation :

/* practice 12: Query employee information according to salary * If there are no parameters , Do not perform where Clause , Query all employees by default : * select * from emp * If there is only minSal( namely minSal Not for null), be : * ... where salary > minSal * If there is only maxSal( namely maxSal Not for null), be : * ... where salary < maxSal * If the parameter has minSal、maxSal( namely minSal、maxSal Not for null), be : * ... where salary > minSal and salary < maxSal */
@Test
public void testFindBySal() {

Map<String, Object> map = new HashMap<String, Object>();
//map.put( "minSal" , 3000 );
//map.put( "maxSal", 4000 );
List<Emp> list = session.selectList( "EmpMapper.findBySal", map );
for (Emp emp : list) {

System.out.println( emp );
}
}

practice 13: Query employee information according to salary (where label )

  • <where> label : Used for the inclusion of SQL Search for fragments , Can be generated when needed WHERE keyword , And when necessary, it will eliminate redundant conjunctions ( such as and perhaps or)
<!-- practice 13: Query employee information according to salary * If there are no parameters , Do not perform where Clause , Query all employees by default : * select * from emp * If there is only minSal( namely minSal Not for null), be : * ... where salary > minSal * If there is only maxSal( namely maxSal Not for null), be : * ... where salary < maxSal * If the parameter has minSal、maxSal( namely minSal、maxSal Not for null), be : * ... where salary > minSal and salary < maxSal -->
<select id="findAllBySal2" resultType="com.tedu.pojo.Emp">
select * from emp
<where>
<if test="minSal != null">
and salary>#{minSal}
</if>
<if test="maxSal != null">
and salary <![CDATA[ < ]]> #{maxSal}
</if>
</where>
</select>

Java Code implementation :

/** * practice 13: Query employee information according to salary * If there are no parameters , Do not perform where Clause , Query all employees by default : * select * from emp * If there is only minSal( namely minSal Not for null), be : * ... where salary > minSal * If there is only maxSal( namely maxSal Not for null), be : * ... where salary < maxSal * If the parameter has minSal、maxSal( namely minSal、maxSal Not for null), be : * ... where salary > minSal and salary < maxSal */
@Test
public void testFindAllBySal() {

// Encapsulate parameters to map Collection 
Map map = new HashMap();
map.put("minSal", 3000);
map.put("maxSal", 4000.0);
List<Emp> list = session.selectList("EmpMapper.findAllBySal2", map);
for (Emp emp : list) {

System.out.println( emp );
}
}

1.6.2 foreach Elements

foreach label : You can traverse the passed parameter array or collection , Here are foreach The attributes on the tag are introduced :

attribute Property description
item It's necessary , if collection Is an array or List When the collection ,item Represents the element in it , if collection by map Medium key,item Express map in value( Set or array ) The elements in
open Optional , Represents the generated by traversal SQL What does the clip start with , The most common is the left bracket ’(’
collection It's necessary , The value is the traversal collection type , for example : If the parameter is just an array or List aggregate , be collection The value of is array or list; If you pass multiple parameters , use map encapsulation ,collection Is specified as map Medium key.
close Optional , Represents the generated by traversal SQL What does the clip end with , The most common is the right bracket ’)’
separator Optional , After each traversal, the generated SQL Specify the space after the fragment

practice 14: According to the employee's id Batch delete employee information

stay mapper In the file SQL sentence :

<!-- practice 14: According to the employee's id Batch delete employee information delete from emp where id in (1,3,5,7) collection: If the parameter passed is just an array or List aggregate , collection Can be specified as array or list; If you pass multiple parameters , use map encapsulation ,collection Is specified as map Medium key open: Specify the generated SQL What symbol does the clip begin with close: Specify the generated SQL What symbol does the clip end with item: Specifies that a variable receives elements in an array or collection separator: Specify a spacer , Splice each element in an array or collection into SQL After the clip , Splice a spacer after -->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="array" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</delete>

Java Code implementation :

/* practice 14: According to the employee's id Batch delete employee information */
@Test
public void testDeleteByIds() {

// Get the employee you want to delete id Array 
Integer[] ids = {
1,3,5,7};
int rows = session.delete( "EmpMapper.deleteByIds", ids );
System.out.println( " Number of rows affected : "+rows );
}

practice 15: According to the employee's id Batch update employee information

stay mapper In the file SQL sentence :

<!-- practice 15: According to the employee's id Batch update employee information take id by 2、4、6、8 The salary of our employees has been increased on the original basis 1000 update emp set salary=salary + 1000 where id in(2,4,6,8); -->
<update id="updateByIds">
update emp set salary=salary + #{sal}
where id in
<foreach collection="arrIds" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</update>

Java Code implementation :

/* practice 15: According to the employee's id Batch update employee information * take id by 2、4、6、8 The salary of our employees has been increased on the original basis 1000 */
@Test
public void testUpdateByIds() {

Integer[] ids = {
2,4,6,8}; // Get the of the employee you want to update id Array 
Double sal = 1000.0; // The salary to be raised 
// The parameter passed exceeds 1 individual , Encapsulate the parameters to map Pass... In the collection 
Map<String, Object> map = new HashMap<String, Object>();
map.put( "arrIds" , ids );
map.put( "sal", sal );
int rows = session.update( "EmpMapper.updateByIds", map );
System.out.println( " Number of rows affected : "+rows );
}

Now practice doing it yourself :

/* practice 16: According to the employee's id Batch query specifies id Employee information * Inquire about id by 2、4、6、8 Information about our employees */
@Test
public void testFindByIds() {
}

1.7 Mapper Interface development


1.7.1 Mapper Introduction to interface development

Above Mybatis In the case , adopt SqlSession When an object calls a method to add, delete, modify, and query , The first parameter that needs to be passed in the method is a string value , The content corresponding to this value is : (Mapper In the document )namespace + id, In this way , find Mapper Mapped in the file SQL Statement and execute !!

In this way, the string value is passed in , very It is prone to string spelling errors and will not prompt at compile time .

Here we will explain a simpler way than the above , It is also the most commonly used way in our enterprise development , That is to use mapper Interface development . Use mapper Interface development needs to pay attention to the following points :

Use mapper Advantages of interface development :

1 You don't have to pass strings when writing programs (namespace+id), Mistakes will also prompt .( In fact, or namespace+id It's just a different way of transmitting values )

2. Future and spring After the container is integrated by spring Container to create mybatis The object of , The code becomes simpler .

(Mapper Interface development If you make a mistake, you will be prompted and spring After integration, there are spring Creating objects from containers becomes easier .)

1、 Create an interface , Fully qualified class name and mapper Of documents namespace It's worth the same
2、mapper Each of the SQL sentence , Add a corresponding method to the interface , And the method name and SQL On the label id Same value
3、Mapper The type of parameter received by the method in the interface , and mapper.xml As defined in sql The type of parameters received by should be the same ,xml The in can be omitted , Methods cannot be omitted .(parameterType: Method receives the type of the parameter , It's usually pojo The fully qualified class name of the object .)
4、 The return value type and SQL On the label resultType That is, the return value type is the same ( If the method returns a collection ,resultType Just specify the generics in the collection )

1.7.2 Mapper Interface development and implementation

The following will be used mapper The way of interface development , According to id Query the specified employee information

1、 establish com.tedu.dao.EmpMapper Interface

Due to the full pathname of the interface (com.tedu.dao.EmpMapper) Want to be with EmpMapper.xml Of namespace Consistent values , therefore , There will be namespace To change the value of com.tedu.dao.EmpMapper:

<?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.tedu.dao.EmpMapper">
</mapper>

2、 Provide... In the interface findById Method

/** * according to id Query employee information * @param id * @return Emp */
public Emp findById(Integer id);

Be careful : The name of the method should be the same as that of the mapping sql Labeled id Consistent values

Method's return value type and resultType The types should be consistent

<!-- 1. Inquire about : Inquire about Emp The table specifies id Employee information -->
<select id="findById" resultType="com.tedu.pojo.Emp">
select * from emp where id=#{id}
</select>

3、 Provide implementation classes , test Emp According to... In the interface id How to query employees

(1) establish com.tedu.test.TestMybatisInf class , And provide testFindById Method

public class TestMybatisInf {

@Test
public void testFindById() throws Exception{
}
}

4、 Realization testFindById Method and test

@Test
public void testFindById() throws Exception{

......
//3. obtain Mapper Interface object 
EmpMapper map = session.getMapper(EmpMapper.class);
//4. Call the method of the interface object to query 
Emp e = map.findById(2);
//5. Output results 
System.out.println(e);
}

5、 Provide... In the interface findAll Method

/** * Check all employee information * @return List<Emp> */
public List<Emp> findAll();

Be careful : The name of the method should be the same as that of the mapping sql Labeled id Consistent values

Method's return value type and resultType The types should be consistent , for example :

<!-- 2. Inquire about Emp Information of all employees in the table -->
<select id="findAll" resultType="com.tedu.pojo.Emp">
select * from emp
</select>

6、 Provide implementation classes , test Emp The method of querying all employees in the interface

(1) establish com.tedu.test.TestMybatisInf class , And provide testFindAll Method

public class TestMybatisInf {

...
@Test
public void testFindAll () throws Exception{
}
}

Realization testFindAll Method and test

@Test
public void testFindAll() throws Exception{

...
//3. obtain Mapper Interface object 
EmpMapper map = session.getMapper(EmpMapper.class);
//4. Call the method of the interface object to query 
List<Emp> list = map.findAll();
//5. Output results 
for (Emp e : list) {

System.out.println(e);
}
}

Total test :

pojo(emp Object ellipsis does not write …)

// Test class :
package com.tedu.mybatis;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 org.junit.Before;
import org.junit.Test;
import com.tedu.dao.EmpMapper;
import com.tedu.pojo.Emp;
/**
* Realization mybatis Of mapper Interface development
*/
public class TestMybatis03 {
private SqlSession session = null;
/* @Before How to annotate and mark , Will be in every @Test Annotation marks the method before execution */
@Before
public void testBefore() throws Exception {
//1. Read mybatis Core profile (mybatis-config.xml),Resources yes mybatis Tool class provided
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2. Get through configuration information SqlSession Factory object
SqlSessionFactory fac = new SqlSessionFactoryBuilder().build( in );
//3. obtain SqlSession object ( Open the connection to the database ), Parameters true Indicates setting auto commit transaction , The default value is false, Indicates manual submission
session = fac.openSession( true );
}
/* Use Mapper Interface development needs to pay attention to the following four points :
* (1) Provide an interface , Let the fully qualified interface name of the interface ( Package name + The interface name ) and Mapper Of documents
* namespace Consistent values ( Fully qualified interface name of the interface = namespace value )
* (2) The methods in the interface should correspond to Mapper In the document SQL sentence , Method name and SQL Statement label
* id value Be consistent ( The method name in the interface = SQL Labeled id value )
* (3) The return value type of the method in the interface , and SQL On the label resultType Keep consistent with the type of
* ( If the method returns a collection ,resultType Just specify the generics in the collection ! )
* (4) The parameter type of the method in the interface , and SQL On the label parameterType The type should correspond to
* ( SQL On the label parameterType You can omit it ! However, the parameters on the methods in the interface cannot be omitted , Used to receive parameters )
*/
/* practice 16: Query all employee information */
@Test
public void testFindAll() {
//List<Emp> list = session.selectList( "EmpMapper.findAll01" ); There is no need for this form
// obtain EmpMapper Subclass of interface (mybatis Provide ) example (mybatis establish ) The object created by the accepting subclass of the parent interface
EmpMapper mapper = session.getMapper( EmpMapper.class );
// Call... According to the subclass instance of the interface findAll01 Method , Query all employee information ( The implementation class of the interface is implemented by the framework )
List<Emp> list = mapper.findAll01();
/* How to locate the information of all employees SQL Of the statement ?
* Although there is no explicit incoming namespace and SQL Labeled id value , Only mapper Bytecode of the interface
* object , And called findAll01 Method , The bottom layer of the framework can get Interface [ Fully qualified interface name ] and
* At present [ The name of the method ], [ Fully qualified interface name + Method name ]==[namespace+id value ]
*/
for (Emp emp : list) {
System.out.println( emp );
}
}
/* practice 17: Add employee information : Zhang Fei Java Development Engineer 15000 */
@Test
public void testInsert() {
// obtain EmpMapper Subclass of interface (mybatis Provide ) Example (mybatis establish )
EmpMapper mapper = session.getMapper( EmpMapper.class );
// call EmpMapper Subclass instance insert06 Method , New employee information
Map map = new HashMap();
map.put( "name" , " Zhang Feifei " );
map.put( "job", " Big data Development Engineer " );
map.put( "salary", 20000 );
mapper.insert06(map);
}
/* practice 18: Modify employee information : Zhang Fei Architects 25000 */
@Test
public void testUpdate() {
// obtain EmpMapper Subclass instance of interface
EmpMapper mapper = session.getMapper( EmpMapper.class );
// take SQL The parameters in the statement are encapsulated in Emp In the object
Emp emp = new Emp(null, " Zhang Feifei ", " Data Analyst ", 33000.0);
// Perform modification operations
mapper.update07(emp);
}
@Test
public void testDelete19() {
// obtain EmpMapper Subclass instance of interface
EmpMapper mapper = session.getMapper( EmpMapper.class );
// Delete id value
mapper.delete19( 15 );
}
}
//Mapper Interface We write the declaration of the interface , The implementation class of the interface is implemented by the framework 8888888888
package com.tedu.dao;
import java.util.List;
import java.util.Map;
import com.tedu.pojo.Emp;
/** Mapper Interface
* Fully qualified interface name of the interface : com.tedu.dao.EmpMapper
* com.tedu.dao.EmpMapper
*/
public interface EmpMapper {
/* practice 1: Inquire about emp All employee information in */
public List<Emp> findAll01(); // The query has a return value , What is returned is a record ( Return value types and ressulttype The value is consistent. ), The query is a single item, and the return is emp object , Query multiple items and return emp aggregate . List aggregate , Generics are emp Type of employee table sql If the statement has placeholders, you need to pass parameters .
/* practice 6: New employee information : Zhang Fei Java Development Engineer 15000 */
public void insert06( Map map ); // increase , Delete , Change The returned value is the number of affected rows int value , You can also choose not to receive . ( Because the number of lines will be printed in the log information ) Whether the method needs to pass parameters depends on sql There are no placeholders in the statement , Multiple parameters are encapsulated into Map Collection
/* practice 7: Modify employee information : Zhang Fei Architects 25000 */
public void update07( Emp emp );
/* practice : according to id Delete employee information */
public void delete19( Integer id ); // If sql There is only one placeholder for a statement that can be passed directly to a parameter , Also need not Emp Objects and Mape Set to encapsulate .
}
EmpMapper.xml sql Statement mapped file
<?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.tedu.dao.EmpMapper">
<!-- practice 1: Inquire about emp All employee information in -->
<select id="findAll01" resultType="com.tedu.pojo.Emp">
select * from emp
</select>
<!-- practice 6: New employee information : Zhang Fei Java Development Engineer 15000 -->
<insert id="insert06">
insert into emp value(null, #{name}, #{job}, #{salary})
</insert>
<!-- practice 7: Modify employee information : Zhang Fei Architects 25000 -->
<update id="update07">
update emp set job=#{job}, salary=#{salary}
where name=#{name}
</update>
<!-- practice : according to id Delete employee information -->
<delete id="delete19">
delete from emp where id=#{id}
</delete>
</mapper>

You can also use annotations to develop : Don't use this EmpMapper.xml File configuration sql sentence ( Annotation development is written in use Mapper Methods in interface development )

shortcoming : Annotation is to put sql Statements are written in the program , If you want to change the program in the future , Recompile and republish .

advantage : The code is simple , Development efficiency is faster , You don't have to write xml file Annotation can be used when changes are infrequent .

//mybatis-config.xml Core profile
<?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>
<!-- 0. Import jdbc.properties file -->
<properties resource="jdbc.properties"/>
<!-- 1. Configure the development environment :
id Property specifies a name for the current environment ,default Property specifies which environment to use -->
<environments default="test">
<environment id="test">
<!-- 1.1. Configure transaction management mode type="JDBC|MANAGED"
JDBC: Give the business to JDBC management MANAGED: Manage your own business -->
<transactionManager type="JDBC" />
<!-- 1.2. Configure data sources ( Connection pool ) type: Specify the connection pool method ,
POOLED: Use connection pool , UNPOOLED Indicates that the connection pool is not used , JNDI: Not commonly used -->
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<!-- 2. scanning mapper The package where the interface is located ( Because now it will SQL Statements are written directly on interface methods through annotations )
Just configure package scanning mybatis The framework will know your sql The statement is written in maper Interface, not in xml In the document , He'll scan sql Get the annotation inside sql Statement in execution -->
<mappers>
<package name="com.tedu.dao"/>
</mappers>
</configuration>

Mapper Interface :

package com.tedu.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.tedu.pojo.Emp;
/** Mapper Interface
* Fully qualified interface name of the interface : com.tedu.dao.EmpMapper
* com.tedu.dao.EmpMapper
*/
public interface EmpMapper {
/* practice 1: Inquire about emp All employee information in */
@Select("select * from emp")
public List<Emp> findAll01();
/* practice 6: New employee information : Zhang Fei Java Development Engineer 15000 */
@Insert("insert into emp value(null,#{name},#{job},#{salary})")
public void insert06( Map map );
/* practice 7: Modify employee information : Zhang Fei Architects 25000 */
@Update("update emp set job=#{job},salary=#{salary} where name=#{name}")
public void update07( Emp emp );
/* practice : according to id Delete employee information */
@Delete("delete from emp where id=#{id}")
public void delete19( Integer id );
}

1.8 Several areas that can be optimized


1.8.1 Join in log4j Log framework

mybatis Default Integration log4j., It only needs Add... To the project log4j Configuration file for , You can print log information , Easy to develop and debug .

stay src/main/resources( Or a similar directory ) Right click new —file— Create log4j.properties as follows :

The file name must be log4j.properties, Must be placed in this directory resources.

# Global logging configuration Specify the location of log information output stdout: Output console . DEBUG The output level of log information
log4j.rootLogger=DEBUG, stdout
# Console output... Specify which Appender Equivalent to a pen
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Back 2 Specify the format of the output log information
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mybatis By default log4j As output log information .

1. Just put the file in the specified location ,log4j The tool will automatically load the above files to the specified location , Read the configuration information in the file and use ! When specified, the warning disappears .

2. You also need to import jar package

1.8.2 SQL Special symbols in sentences

Example : Add a query function : Query salary less than 3500 All employees .

1、 edit EmpMapper.xml file , Add the corresponding query sql.

<!-- practice 12: Query employee information according to salary -->
<select id="findBySal" resultType="com.tedu.pojo.Emp">
select * from emp
where 2=2
<if test="minSal != null">
and salary >= #{minSal}
</if>
<if test="maxSal != null">
and salary <= #{maxSal}
</if>
</select>

2、 But after writing ,xml There is an error in the file prompt :

 Insert picture description here

original , Less than no. (<) stay xml There are special characters in the file , By xml The file is used as the starting symbol of the label .

3、 resolvent : have access to &lt; Instead of <, for example :

<select id="findBySal" resultType="com.tedu.pojo.Emp">
select * from emp
where 2=2
<if test="minSal != null">
and salary >= #{minSal}
</if>
<if test="maxSal != null">
and salary &lt;= #{maxSal}
</if>
</select>

perhaps Is to include special symbols in CDATA District ( <![CDATA[ ]]> ) in , This is because it is placed in CDATA Content in the area , Will only be xml The parser treats it as plain text . Instead of being treated as part of the label .

<!-- Query salary less than 3500 All employees -->
<select id="findBySal" resultType="com.tedu.pojo.Emp">
select * from emp
where 2=2
<if test="minSal != null">
and salary >= #{minSal}
</if>
<if test="maxSal != null">
and salary <![CDATA[ <= ]]> #{maxSal}
</if>
</select>

1.8.3 jdbc.properties file

In development , Usually, we will put the configuration information of connecting to the database in a separate properties In file ( Easy to manage and maintain ),
And then in MyBatis Of mapper Introduce in the file properties The configuration information of the file !

( Don't write this directly in , mybatis In the core configuration file )

1、 stay src/main/resources Create a directory named jdbc.properties The file of File file

[ 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-GvDIO9p1-1638456215510)(JAVAWEB-NOTE04.assets/c689eb39f8139c834ce014974d446229.png)]

2、jdbc.properties The contents of the document are as follows : This file is key----value structure

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
// The prefix jdbc It can be changed , Just need and introduce $ Inside key Just be consistent

3、 stay mybatis-config.xml Introduce in the file jdbc.properties file

This file will also be compiled and placed in the class directory ,resource It refers to the class directory , So send it directly Just copy the file name .

Make sure the inside of the placeholder is key And this properties In the document key bring into correspondence with .

[ 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-ZnD7nOuf-1638456215510)(JAVAWEB-NOTE04.assets/7f967dea070cc2df6038dc0a11fcfc7e.png)]

1、 among <properties resource="jdbc.properties"/> Tags are used to introduce jdbc.properties file , Default to classpath That is, find the specified file in the class directory ;

2、properties On the label value Property ${jdbc.xxx}:

${jdbc.driver}: In fact, that is jdbc.properties In the document jdbc.driver Value , namely :

com.mysql.jdbc.Driver

${jdbc.url}: In fact, that is jdbc.properties In the document jdbc.url Value , namely :

jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf-8

${jdbc.username}: In fact, that is jdbc.properties In the document jdbc.username Value , namely :

root

${jdbc.password}: In fact, that is jdbc.properties In the document jdbc.password Value , namely :

root

1.9 Extended content


1.9.1 Jdbc review

adopt JDBC Inquire about Emp All records in the table , And encapsulated in a List Returns... In the collection

1、 establish TestJdbc class , Complete the query of all employees :

package com.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.tedu.pojo.Emp;
/** Jdbc review */
public class TestJdbc {

public static void main(String[] args) {

/* Inquire about emp All employee information in the table , Encapsulate the information of each employee into one * Emp In the object , Then it encapsulates all employee information Emp Objects in List aggregate * in , And traverse and output all employee information */
List<Emp> empList = findAll();
for(Emp emp : empList){

System.out.println(emp);
}
}
/** * Inquire about emp All employee information in the table , Package to List Assemble and return to Because the return is emp A collection of types , So price generics The bottom of the framework does the same , First encapsulate into an object , Then save the object to the collection . */
private static List<Emp> findAll() {

Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {

//1. Register database driver 
Class.forName("com.mysql.jdbc.Driver");
//2. Get database connection (Connection)
conn = DriverManager.getConnection(
"jdbc:mysql:///yonghedb",
"root", "root");
//3. Get the transmitter 
stat = conn.createStatement();
//4. Use the transmitter to send sql To database execution , And return the execution result 
String sql = "select * from emp";
rs = stat.executeQuery(sql);
//5. Processing results 
//5.1. Statement List aggregate , Used to encapsulate all employee information 
List<Emp> empList = new ArrayList();
//5.2. Traverse ResultSet Result set 
while(rs.next()) {

//5.3. Get each piece of employee information in the result set 
int id = rs.getInt("id");
String name = rs.getString("name");
String job = rs.getString("job");
double salary = rs.getDouble("salary");
//5.4. Encapsulate each piece of employee information into one Emp In the object 
Emp emp = new Emp();
emp.setId(id);
emp.setName(name);
emp.setJob(job);
emp.setSalary(salary);
//5.5. take Emp Objects in List Collection 
empList.add(emp);
}
return empList;
} catch (Exception e) {

e.printStackTrace();
System.out.println(" The query fails !");
} finally{

//6. Release resources 
if(rs != null){

try {

rs.close();
} catch (SQLException e) {

e.printStackTrace();
}finally{

rs = null;
}
}
if(stat != null){

try {

stat.close();
} catch (SQLException e) {

e.printStackTrace();
}finally{

stat = null;
}
}
if(conn != null){

try {

conn.close();
} catch (SQLException e) {

e.printStackTrace();
}finally{

conn = null;
}
}
}
return null;
}
}

2、 Statement Emp Entity class , Used to encapsulate employee information :

package com.tedu.pojo;
/** * Entity class , For encapsulation Emp A piece of user information in the table */
public class Emp {

//1. Declare the attributes in the entity class 
private Integer id;
private String name;
private String job;
private Double salary;
//2. Provide the corresponding getter and setter Method 
public Integer getId() {

return id;
}
public void setId(Integer id) {

this.id = id;
}
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public String getJob() {

return job;
}
public void setJob(String job) {

this.job = job;
}
public Double getSalary() {

return salary;
}
public void setSalary(Double salary) {

this.salary = salary;
}
//3. rewrite toString Method 
@Override
public String toString() {

return "Emp [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
}
}

1.9.2 mybatis-config The solution without prompt in the file

If there is no network ( Extranet ) Under the circumstances , To write mybatis-config.xml The file does not prompt , You can follow the following steps to configure : This is to use local search instead of Find it on the Internet

(1) find mybatis-3-config.dtd The location of the file , for example : This is the previous picture , Now in day14-15mybatis in

[ 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-ubutjY9M-1638456215511)(JAVAWEB-NOTE04.assets/065e6b731aa74d5650821fdc63cbd4b9.png)]

(2) Copy the following url Address :

http://mybatis.org/dtd/mybatis-3-config.dtd

(3) stay eclipse In the menu bar : window --> Preferences --> Search... In the search box [ xml ] XML --> XML Catalog --> User Specified Entries --> Add…

[ 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-XkvNsRPm-1638456215512)(JAVAWEB-NOTE04.assets/eef68594c0d7b072e09702b3d6289831.png)]

(4) In the pop-up window :

[ 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-TDSeUVui-1638456215513)(JAVAWEB-NOTE04.assets/364a97a96fcb74e6ca14d4a9c8b89e6b.png)]

1.9.3 Mapper The solution without prompt in the file

If there is no network ( Extranet ) Under the circumstances , To write XxxMapper.xml The file does not prompt , You can follow the following steps to configure :

(1) find mybatis-3-mapper.dtd The location of the file , for example :

[ 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-fqJ2i9xg-1638456215513)(JAVAWEB-NOTE04.assets/50f2e9357bd4d42791f85098a75795c0.png)]

(2) Copy the above url Address , namely :

http://mybatis.org/dtd/mybatis-3-mapper.dtd

(3) stay eclipse In the menu bar : window --> Preferences --> Search... In the search box [ xml ] XML --> XML Catalog --> User Specified Entries --> Add…

[ 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-50mzcTdY-1638456215514)(JAVAWEB-NOTE04.assets/eef68594c0d7b072e09702b3d6289831.png)]

(4) In the pop-up window :

[ 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-c1lqZ4tP-1638456215515)(JAVAWEB-NOTE04.assets/e907b64d04d56389acba7c7e2f6bd74c.png)]

1.9.4 Configure Dane XML Schema proxy server

1、 open Eclipse Configuration preferences

[ 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-KEnRxDJ1-1638456215515)(JAVAWEB-NOTE04.assets/eb81455caf93624c289a4e60105b6aca.png)]

2、 find XML -> XML Catalog, Add configuration items :

[ 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-H64IdH4o-1638456215516)(JAVAWEB-NOTE04.assets/bf2d8978925006db94220c283a695f57.png)]

3、 add to URI Agent configuration , such as : To configure Spring Schema

[ 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-fKbJfL5B-1638456215516)(JAVAWEB-NOTE04.assets/7e5343736b72ca605ac7e577025ccd9e.png)]

4、 The agents that can be configured are

http://ibatis.apache.org http://doc.tedu.cn
http://www.springframework.org http://doc.tedu.cn
http://mybatis.org http://doc.tedu.cn
http://hibernate.sourceforge.net, http://www.hibernate.org http://doc.tedu.cn
http://struts.apache.org http://doc.tedu.cn

2 spring frame

2.1 spring brief introduction

2.1.1 What is? Spring?

Light weight : It means that the code is less intrusive .

spring It's layered JavaSE And JavaEE be applied to Full stack lightweight open source framework , With IoC(Inverse Of Control: Inversion of control / Inversion control ) and AOP(Aspact Oriented Programming: Section oriented programming ) At the core , Provides The presentation layer SpringMVC and Persistence layer SpringJDBC as well as The business layer Enterprise application technology of many modules such as transaction management , It can also integrate many famous third-party frameworks and class libraries in the open source world , Gradually become the most used JavaEE Enterprise application open source framework .( namely spring Not a single framework )

SSH(struts2 spring hibernate) Basically ssm To replace the

SSM(springmvc spring mybatis)

Spring The essence of is to manage the objects in software , namely Create objects and Maintain the relationship between objects

explain : c: representative controller, The bottom layer is servlet

v: Representative view

M: representative model

spring All three layers involve . Their object is made up of Spring Container to create . Premise is mybatis Need and spring Integrate .springmvc You don't need to be with spring Integrate .pojo The three layers are also related to .(pojo Encapsulate the request parameters and transfer them to the database , The database is encapsulating the queried data into pojo Pass the object back .)

Divided into three parts :

[ 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-qNi1YKaG-1638456215518)(JAVAWEB-NOTE04.assets/123.PNG)]

2.1.2 Spring Development history of

1997 year IBM Put forward EJB Thought

1998 year ,SUN Develop standard specifications EJB1.0

1999 year ,EJB1.1 Release

2001 year ,EJB2.0 Release

2003 year ,EJB2.1 Release

2006 year ,EJB3.0 Release

Rod Johnson ( Rod · Johnson ,spring The father of )

Expert One-to-One J2EE Development without EJB(2004)

Elaborated J2EE Development does not use EJB The solution (Spring embryonic form )

2017 year 9 Released in spring Latest version spring 5.0 General version

2.1.3 Spring The advantages of

1). Easy decoupling , Simplify the development

adopt Spring Provided IoC Containers , You can delegate dependencies between objects to Spring Control , Avoid excessive program coupling caused by hard coding . Users no longer have to write code for lower level requirements , You can focus more on the upper level of the application .

Can only reduce the coupling , Can't completely eliminate .

2).AOP Programming support

adopt Spring Of AOP function , Convenient for section oriented programming , Many traditions are not easy to use OOP(Object Oriented Programming: object-oriented programming ) The functions can be realized through AOP Easy to deal with .

3). Support for declarative transactions

We can get rid of the tedious transaction management code , Flexible transaction management through declarative way , Improve development efficiency and quality .

4). Convenient program testing

Almost all testing can be done in a container independent programming way , Testing is no longer an expensive operation , It's something you can do .

5). Easy integration of various excellent frameworks

Spring Can reduce the difficulty of using a variety of frameworks , Offers a variety of excellent frameworks (Struts、Hibernate、Hessian、Quartz etc. ) Direct support for .

6). Reduce JavaEE API The difficulty of using .

Spring Yes JavaEE API( Such as JDBC、JavaMail、 Remote call, etc ) Thin packaging layer , To make these API The use difficulty is greatly reduced .

7).Spring The framework source code is a classic learning example

Spring The source code of is well designed 、 The structure is clear 、 Ingenuity alone , The master's right to Java Flexible use of design patterns and Java Advanced technology . Its source code is undoubtedly Java Examples of best practices in technology .

2.1.4 spring The architecture of

Spring The initial goal is to integrate all excellent resources , And then provide a unified service to the outside world .Spring Modules are built on top of core containers , The core container defines the creation of 、 Configure and manage bean The way , As shown in the figure below :

[ 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-0eXYu1ql-1638456215518)(JAVAWEB-NOTE04.assets/bf0676465991176183ba7d0765728e57.png)]

form Spring Every module of the framework ( Or component ) Can exist alone , Or in combination with one or more other modules . The functions of each module are as follows :

modular explain
Core container Spring Core Core container , Provide Spring The basic functions of the framework . The main components of the core container are BeanFactory, It's the implementation of the factory model .BeanFactory Use inversion of control (IOC) Pattern , Separate application configuration and dependency specifications from the actual application code .
Spring Context Spring Context , Is a profile , towards Spring The framework provides context information .Spring Context includes enterprise services , for example JNDI、EJB、 E-mail 、 internationalization 、 Check and dispatch function .
Spring AOP Through configuration management features ,Spring AOP Module directly integrates aspect oriented programming functions into Spring In the frame . It's easy to make Spring Any object support for framework management AOP.Spring AOP The module is based on Spring Objects in the application provide transaction management services . By using Spring AOP, You can integrate declarative transaction management into your application .
Spring DAO JDBC DAO The abstraction layer provides a meaningful exception hierarchy , This structure can be used to manage exception handling and error messages thrown by different database vendors . Exception hierarchies simplify error handling , And greatly reduces the number of exception code to be written ( For example, opening and closing the connection ).Spring DAO Face of JDBC The exception of follows the general DAO Exception hierarchy .
Spring ORM Spring The frame inserts several ORM frame , Thus providing ORM Object relation tools , These include JDO、Hibernate and iBatis SQL Map. All of this follows Spring General affairs and DAO Exception hierarchy .
Spring Web Web The context module is built on top of the application context module , Based on Web The application provides context . therefore Spring Framework support and Jakarta Struts Integration of .Web The module also simplifies the processing of multipart requests and binding request parameters to domain objects .
Spring MVC frame MVC Framework is a full-featured construction Web Application's MVC Realization . Through the strategic interface ,MVC The frame becomes highly configurable ,MVC It contains a lot of view technology , These include JSP、Velocity、Tiles、iText and POI.

2.2 Coupling and decoupling in the program

2.2.1 What is program coupling

Coupling (Coupling), It's also called coupling , Is a measure of the degree of correlation between modules . The strength of coupling depends on the complexity of the interface between modules 、 How to call the module and how much data is transferred through the interface . The coupling between modules refers to the dependency between modules , Including control relationships 、 Call relationship 、 Data transfer relationship . The more connections between modules , The stronger the coupling , At the same time, it shows that the less independent it is ( Reduce coupling , It can improve its independence ). Coupling exists in all fields , Not unique in software design , But we only talk about coupling in Software Engineering .

summary : In software engineering , Coupling refers to the dependencies between objects . The higher the degree of dependency between objects , The higher the coupling . The higher the coupling between objects , The higher the maintenance cost . So objects should be designed to minimize the coupling between classes and components .

Reduce The degree of dependency between programs , That is, the process of reducing the coupling between programs is called decoupling .( Can't completely eliminate )

for example : In the early Jdbc In operation , When registering the database driver , Why is Class.forName The way , Instead of adopting DriverManager.registerDriver The way ?

public class TestJdbc {

public static void main(String[] args) throws Exception {

//1. Register database driver 
// DriverManager.registerDriver( new Driver() );
Class.forName("com.mysql.jdbc.Driver");
//2. Get database connection 
//3. Get the transmitter 
//4. send out sql Go to the server to execute and return the execution result 
//5. Processing results 
//6. Release resources 
}
}
// Dependency relationship : For example, create objects in one class by relying on another class 
class A{

private B b=new B(); //A rely on B Create objects This design is too dependent. Once an error is reported, many places need to be changed , Very unreasonable ( It's like a company depends on this employee , Once he leaves, the company may be paralyzed )
}
class B{

}

except DriverManager.registerDriver This will cause the driver to register twice , what's more , If you use this method ,JDBC The program will depend on the driver class of the database (MySQL Of Driver class ), If the later program is upgraded to... Due to the amount of data and performance Oracle database , You need to modify the program source code —— Re import the new driver class , This will add a lot of unnecessary trouble !

It's about using Class.forName Way to register driver , The advantage of this is Jdbc Programs no longer rely on specific driver classes , Even delete ( Or not import )mysql Drive pack , The program can still compile ( Of course, it's impossible to run , Because the runtime must rely on drivers ).

At this point, the class will just mysql The fully qualified class name of the driver class is written in the program ( Just a string ), You can extract this string into the configuration file , You can modify the configuration file later ( Without modifying the program code ) Easily replace database products .

2.2.2 Introduction to factory mode decoupling

In actual development, three layers can be ( The presentation layer 、 The business layer 、 Persistence layer ) All objects are configured using configuration files , When starting the server to load the application , Can pass The factory reads the configuration file , according to The configuration in the configuration file creates these objects , In the next use , Just take it and use it .

that , This Responsible for reading configuration files , The class that creates and returns these objects according to the configuration file is the factory .

Can pass 【 factory + Interface + The configuration file 】 To decouple the program .

2.2.3 Factory mode decoupling example


Decoupling programming steps :


1、 Create a Maven Of Java engineering (day16-spring)

2、 Create persistence layer interfaces and interface implementation classes

com.tedu.dao.EmpDao ( Interface )

com.tedu.dao.EmpDaoImpl ( Implementation class )

3、 Create business layer interfaces and interface implementation classes

com.tedu.service.EmpService ( Interface )

com.tedu.service.EmpServiceImpl ( Implementation class )

4、 Create presentation layer test program (com.tedu.controller.EmpController) And run the test program

5、 Through engineering + The configuration file + Interface ( existing ) The way to decouple

(1) Create a factory class (com.tedu.factory.BeanFactory) And implement

(2) Provide configuration files , take service Interface and dao The fully qualified class name of the implementation class of the interface is written into the configuration file .

6、 Use the factory to get service Interface and dao An instance of an interface , Replace with new To get an instance of the interface .


The detailed code is as follows :


1、 Create persistent layer interface (com.tedu.dao.EmpDao)

package com.tedu.dao;
/** * Of the employee module Dao( Persistence layer ) Interface */
public interface EmpDao {

/** Add employee information */
public void addEmp();
}

2、 Create a persistence layer interface implementation class (com.tedu.dao.EmpDaoImpl)

package com.tedu.dao;
/** * Of the employee module Dao( Persistence layer ) Interface implementation class */
public class EmpDaoImpl implements EmpDao {

@Override
public void addEmp() {

System.out.println(
"Dao Layer of addEmp() Method executed .. Successfully saved an employee information .."
);
}
}

3、 Create business layer interface (com.tedu.service.EmpService)

package com.tedu.service;
/** * Of the employee module service( The business layer ) Interface */
public interface EmpService {

/** Add employee information */
public void addEmp();
}

4、 Create a business layer interface implementation class (com.tedu.service.EmpServiceImpl)

package com.tedu.service;
import com.tedu.dao.EmpDao;
import com.tedu.dao.EmpDaoImpl;
/** * Of the employee module service( The business layer ) Interface implementation class * service layer ---> dao layer */
public class EmpServiceImpl implements EmpService {

/* obtain Dao Subclass instance of interface * —— Use here new The way objects are used to increase the coupling between programs */
private EmpDao dao = new EmpDaoImpl();
@Override
public void addEmp() {

System.out.println(" call dao Add employee information by layer method ...");
dao.addEmp();
}
}

5、 Create a presentation layer test class (com.tedu.controller.EmpController)

If not in pom Add test dependencies to the file , You can add the library directly .

[ 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-qA5sUfbX-1638456215519)(JAVAWEB-NOTE04.assets/cccc.PNG)]

package com.tedu.controller;
import org.junit.Test;
import com.tedu.service.EmpService;
import com.tedu.service.EmpServiceImpl;
/** * Simulation presentation layer * Controller( The presentation layer ) --> Service( The business layer ) -->Dao( Persistence layer ) */
public class EmpController {

/* obtain EmpService Subclass instance of interface * Here the new In the form of Service The object of the layer , Improves dependencies between objects , In other words, the coupling is improved ! * If EmpServiceImpl Once this class is replaced , There will be a compilation error in the following line of code ( The whole project may * There are many mistakes like this , You need to modify the program , After the change, you need to recompile 、 Re release , Will improve the quality of the project * Maintenance cost , Cause a lot of unnecessary trouble !!) */
//private EmpService service = new EmpServiceImpl(); new The way 
EmpService service = (EmpService)BeanFactory.getBean( "EmpService" );// Get the instance of which interface subclass and pass that interface name in The return value is object, Now let's use EmpService Interface to receive , So we need a strong turn advantage : If we need to replace this subclass , Just change the class name of the configuration file , No more new Object change code 
@Test
public void testAddEmp() {

System.out.println(" call service Add employee information by layer method ...");
service.addEmp();
}
}

In the above procedure ,EmpController To call Service Layer method , So pass new Object to get EmpService Instance of interface subclass , The code is as follows :

private EmpService service = new EmpServiceImpl();

stay EmpService To be called in the implementation class of Dao Layer method , So pass new Object to get EmpDao Instance of interface subclass , The code is as follows :

private EmpDao dao = new EmpDaoImpl();

If in the above program EmpDaoImpl perhaps EmpServiceImpl remove , It will cause code compilation errors in other classes . At this point, the presentation layer and the business layer , And the dependence between the business layer and the persistence layer is too high , If you replace a layer in the future , It is likely that other layers will not work , Only by modifying the program code can the program run , In this way, dependency will increase maintenance costs and cause unnecessary trouble .

and In the program new The method of object causes the dependency between such programs to increase , That is, it improves the coupling between programs .

Use the factory + The configuration file + Interface decoupling The code is as follows


6、 establish com.tedu.factory.BeanFactory class , Used to create objects needed for each layer .

package com.tedu.factory;
import java.io.InputStream;
import java.util.Properties;
/** * --------------------------------------------------------- * Bean: Reusable components ( Computer English ) * JavaBean: Use Java Reusable components written in language , for example :service layer 、dao Layer, etc. * JavaBean: It is usually divided into business Bean And entities Bean * Business Bean: Process business logic ,service layer 、dao layer * Entity Bean: Encapsulated data , for example , Written to encapsulate employee information Emp Entity class . * --------------------------------------------------------- * Remove the coupling : * simulation spring How containers create instances * (1) A configuration file is required , Configure in profile service and dao Implementation class of * Configuration content is : Unique identification = The fully qualified class name of the implementation class (key=value structure ) * (2) Read the fully qualified class name configured in the configuration file through the factory , Using reflection to create objects . * xml The configuration file 、properties The configuration file */
/** * simulation spring How containers create instances * (1) Provide a config.properties The configuration file , Configure the corresponding relationship between interface and implementation class in this file * EmpService=com.tedu.EmpServiceImpl The underlying layer creates an instance of this class through reflection * (2) Read... In the current class config.properties Configuration information in the file , Read all configurations in the file to * Properties In the object * (3) Provide a getBean Method , Receive interface name ( for example :EmpService), According to the interface name to Properties * Object to obtain the fully qualified class name of the implementation class corresponding to the interface (com.tedu.EmpServiceImpl), * Create an instance of this class based on reflection , As the return value of the method, you can directly return ! * */
public class BeanFactory {

// Make a statement Properties object , Used for loading config.properties Everything in the document , Initialize it in a static code block Read the configuration information, and the frame will automatically read , There is no frame to read manually 
private static Properties prop;
static {

try {

// initialization prop This new object It usually doesn't change, so it's OK to rely on This prop It can be thought of as key --value structure The contents of the saved configuration file 
prop = new Properties();
// Get directions config.properties The stream object of the file 
// A class is loaded from the hard disk into memory ( Through class loader ) You can get the bytecode object of this class 
ClassLoader loader = BeanFactory.class.getClassLoader();// Get a class loader You can load not only classes but also configuration files 888888888888 Get the class loader through the bytecode object of the class 
// This file is placed in the source directory, loaded and placed in the class directory ,load Method loads the class directory , So we just need to pass in the file name directly Directly on the file ctrl +c Copy class name 
InputStream in = loader.getResourceAsStream("config.properties");
// take config.properties All contents in the file are loaded prop In the object 
prop.load( in );
} catch (Exception e) {

e.printStackTrace();
}
}
/** * By interface name , To config.properties Get the fully qualified class name of the subclass corresponding to the interface in the file ( According to key obtain value) * Then create an instance of the subclass based on reflection * @param interName The interface name ( It's also config.properties In the document key) * @return Object According to the incoming interface name , Return the subclass instance corresponding to the interface */
public static Object getBean(String interName) {
// Change the static method to directly call 
try {

// By interface name , To config.properties Get the fully qualified class name of the subclass corresponding to the interface in the file 
String className = prop.getProperty( interName );
// Get the bytecode object of the subclass through the fully qualified class name of the subclass 
Class clz = Class.forName(className);
// In the bytecode object passing through this class , Get an instance of this class The return value is one Object object 
Object obj = clz.newInstance();
return obj;
} catch (Exception e) {

e.printStackTrace();
}
return null; // This is because if the program executes After getting the bytecode object and throwing an exception, the program will not execute as null, Add one return Make sure to return a null value . Only one of them can perform , When the program throws an exception, it executes return null On the contrary, it will not execute 
}
}

7、 In the source directory src/main/resources Next create a config.properties file , The file content is configured as follows :

new — File Configure interface Relationship with implementation class

EmpService=com.tedu.service.EmpServiceImpl
EmpDao=com.tedu.dao.EmpDaoImpl

8、 take EmpController Pass in class “new Object to get EmpService Instance of interface subclass ” And in EmpServiceImpl Pass in class “new Object to get EmpDao Instance of interface subclass ” Change to use BeanFactory The factory gets Service and Dao Examples of layers . as follows :

/* obtain Service Subclass instance of interface * —— Use here new The way objects are used to increase the coupling between programs */
//private EmpService service = new EmpServiceImpl();
private EmpService service = (EmpService)BeanFactory.getBean("EmpService");
/* obtain Dao Subclass instance of interface * —— Use here new The way objects are used to increase the coupling between programs */
//private EmpDao dao = new EmpDaoImpl();
private EmpDao dao = (EmpDao)BeanFactory.getBean( "EmpDao" );

2.4 Spring IOC Inversion of control


2.4.1 What is inversion of control

IOC(Inverse Of Control) Inversion of control , namely **, Leave the right to create objects to the framework .**

That is to say, the of the object establish 、 Object's Storage 、 Object's management To spring Containers .

(spring The container is spring One of the core modules in , The value will follow the monitor , The bottom layer can be understood as a map aggregate )

spring Integrated mybaitis after ,mybatis The frame object of is also composed of spring Container object creation .


[ 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-1EDkG9ej-1638456215520)(JAVAWEB-NOTE04.assets/0a11c44a30f5a7328589e4031d624ffd.png)]


Before that , When you need an object , It's usually the use of new Keyword to create an object :

/* obtain Service Subclass instance of interface * —— Use here new The way objects are used to increase the coupling between programs */
private EmpService service = new EmpServiceImpl();
//private EmpService service = (EmpService)BeanFactory.getBean("EmpService");

But because of new object , Will increase the dependency between classes and classes , The coupling between the code .

And now we can put The creation of objects is left to the framework

/* obtain Service Subclass instance of interface * —— Use here new The way objects are used to increase the coupling between programs */
//private EmpService service = new EmpServiceImpl();
private EmpService service = (EmpService)BeanFactory.getBean("EmpService");// This is a simulation spring How to create objects at the bottom of the container 

Just configure the class in the configuration file in advance , You can leave the creation of objects to the framework . When you need an object , You don't need to create , Instead, it can be obtained directly through the framework , No new Object procedure , Naturally reduce the dependency between classes , That is coupling .

2.5 IOC Introductory cases


The following will be used spring Of IOC Solve the coupling between programs

2.5.1 Create a project , introduce jar package

establish Maven engineering , introduce spring Dependent package

1、 establish Maven—Java engineering

[ 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-IGTleAoP-1638456215520)(JAVAWEB-NOTE04.assets/e38fbdb8819178517de105a52e112a84.png)]

2、 introduce junit、spring Of jar package : stay maven engineering pom.xml The root tag of the file **(project)** Add the following configuration in :

<dependencies>
<!-- add to junit Of jar package -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- add to spring Of jar package -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
</dependencies>

Save after import pom file , The project is shown in the figure : dependencies: rely on

[ 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-Y6ZT6q8V-1638456215521)(JAVAWEB-NOTE04.assets/ffe9287f31af4c4bf68f5d098b1d2039.png)]

2.5.2 establish spring The configuration file

establish spring Core profile —applicationContext.xml

1、 In the engineering of src/main/resources Source directory , establish applicationContext.xml file :

[ 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-XcBg47Sf-1638456215521)(JAVAWEB-NOTE04.assets/3b521e8ba5d563ec21a2e142fa6cf623.png)]

2、 stay applicationContext.xml Add header information to :

<?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.xsd">
</beans>

3、 take EmpService An instance of the implementation class of the interface
as well as EmpDao The instance of the implementation class of the interface is handed over to Spring Container to create , Add the following configuration in the core configuration file :( Through the configuration file, you can tell spring The container needs him to help us create those objects )

<?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.xsd">
<!-- take EmpService Subclasses of the interface are used as bean(bean It's the object ), Declare to spring In the container ( by spring The container creates an instance of the class ) If the label has no content, it can be written as autistic or not id The value of an attribute is a unique number , Used to get an instance of the current class map Medium key (id The value is named , If this class has an interface, it usually uses the interface name , No interface with class name , Lowercase initials ) class The value of the attribute is the fully qualified class name of a class , You can let the framework create instances of this class through reflection at the bottom The object is to value Save properties to map in ,id The corresponding is key Press ctrl The underlined key indicates that it is written correctly Similar to the previous configuration : EmpService=com.tedu.EmpServiceImpl ( The interface name = The full name of the subclass defines the category ) This bean label . -->
<bean id="empService" class="com.tedu.EmpServiceImpl01"></bean>
<!-- take User As bean Declare to spring In the container , from spring The container creates an instance of the class scope Property is used to create multiple objects -->
<bean id="user" class="com.tedu.pojo.User" scope="prototype">
<!-- adopt set Method is User Object's property assignment : setName(" Han Shaoyun ");setAge(18); setInfo( adopt userInfo The object of acquisition ); As long as this line of information is configured ,spring The framework will call... At the bottom setname Method , to name Attribute assignment , The value passes through the configured value Appoint . It has nothing to do with attributes, only with the corresponding attributes <property name="name" value=" Han Shaoyun " /> The bottom tone is setName Method , Assigned to Han Shaoyun <property name="age" value="18" /> There's nothing in the tag that can or can't be autistic <property name="info" ref="userInfo" value and ref Can't reuse ( For string and numeric types, use value attribute , If the attribute is an object type, the same as ref,ref Point to bean Labeled id value . In the future through id namely key Go to map Set value , Getting is userinfo Object is assigned to info object , Of course, the assignment is also setinfo Method )/> name The value inside is like :name It has nothing to do with the value name in the attribute , Different values can still be assigned , It is and setName Method names are related to -->
<!-- The construction method is User Object's property assignment : requirement : name Property Want to be with The names of formal parameters in the constructor are consistent ! Write three labels to represent The constructor with three parameters matches -->
<constructor-arg name="age" value="28"/>
<constructor-arg name="name" value=" Jack ma, "/>
<constructor-arg name="info" ref="userInfo"/>
</bean>
<!-- take UserInfo As bean Declare to spring In the container ,spring The container will create userInfo The instance of class is saved to map Collection .key Namely userinfo,value Namely com.tedu.pojo.UserInfo Value -->
<bean id="userInfo" class="com.tedu.pojo.UserInfo"></bean>
</beans>

2.5.3 Create test classes for decoupling

Create test class —TestSpring, adopt spring Of IOC Solve the coupling problem in the program

1、 Create test class

[ 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-D0rioj7f-1638456215521)(JAVAWEB-NOTE04.assets/30070bf2108c5dcd69ad97c00021d08b.png)]

2、 The test steps and codes are as follows :

package com.tedu.spring;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tedu.EmpService;
import com.tedu.pojo.User;
/** * test spring Of IoC( Inversion of control ) * test spring Of DI( Dependency injection ) */
public class TestSpring {

/* 1、 test spring Of IoC( Inversion of control ) * 2、 test spring Single instance and multi instance * Single instance : adopt spring The container gets the instance of the same class multiple times ,spring The container will only create one instance of this class from beginning to end * advantage : Can save memory space , Reduce waste of resources * shortcoming : Because the same object is obtained every time , Access is also a member of the same object , May cause thread safety issues . * Multiple instances : adopt spring The container gets the instance of the same class multiple times ,spring Each time the container creates a new instance of the class * advantage : No thread safety issues * shortcoming : Consumes memory space * summary : On the premise of ensuring that there will be no thread safety problems , Single instance is recommended , Otherwise, use multiple instances ! */
@Test
public void testIoC() {

// Acquired spring The container object of ( Need to read a spring Configuration file for container , The file name is usually called applicationContext.xml There are also people called. bean.xml) The location of the configuration file This container will scan the configuration file for the objects to be configured , At the bottom of it is a map This file name is also compiled in the root directory of the class directory , So write the class name directly 
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
// adopt spring Container acquisition EmpService Subclass instance of interface If you want to spring Container helps you create a class object , You need to treat this class as a bean Declare to spring Containers The type returned is object A strong turn is needed 
EmpService service = (EmpService)ac.getBean( "empService" );
System.out.println( service );// The address value of the object is printed, indicating that the printing is successful .
// adopt spring Container acquisition User Class ( This object is called bean object )
User user1 = (User)ac.getBean( "user" );
User user2 = (User)ac.getBean( "user" );
/* Bean Object : * If user1==user2, shows user1 and user2 It's pointing to the same object * spring A container for User Class creates only one instance from beginning to end ( The server shuts down and the instance is destroyed ) * Bean Multiple instances of objects : stay bean Add an attribute to the tag scope attribute * If user1!=user2, shows user1 and user2 It's pointing to different objects * spring A container for User Class creates different instances each time */
System.out.println( user1 == user2 );
}
/* * 3、 test spring Of DI( Dependency injection ) * DI: Through spring When or after the container creates the object , from spring The framework assigns values to the properties of the object * (1)set Methods to inject : Call the object's setXxx Method is xxx Attribute assignment * for example : call user.setName() by name Attribute assignment * (2) Constructor injection : stay spring While the container creates objects , Assign values to the properties of an object through a parameter constructor * for example : User user = new User(" Han Shaoyun ", 18); * by user Object's name Properties and age Attribute assignment */
@Test
public void testDI() {

// obtain Spring The container object of 
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
// adopt spring Container acquisition User Class 
User user = (User)ac.getBean( "user" );
//set Methods to inject 
System.out.println( user );
}
}
// Provide a User class , There are member variables , Construction method ,get and set Method , toString Method 
A little

3、 Running results :

[ 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-b3Rku89o-1638456215522)(JAVAWEB-NOTE04.assets/96cee091183ae525af0bf5314bf057c1.png)]

4、 Introduction case summary :

This is it. spring Framework of the IOC—— Inversion of control . Before, we ourselves new object , for example :

User u = new User();

And now , Becomes an initialized xml Profile to create , That is, by spring Container to create .

User user = (User) ac.getBean(“user”);

When the program runs ,spring After the start of work , Will load the entire xml Core profile , Read , Get class The full path of the class in the property , Create objects of this class with reflection .

2.6 Bean Single and multiple instances of objects


2.6.1 Bean Overview of single and multiple instances of objects

stay Spring Managed in a container Bean Object scope , Can pass scope attribute Or specify its scope with relevant annotations .

The most common is singleton( Single case ) or prototype( Multiple cases ). Its meaning is as follows :

1) singleton: single example , Is the default value . The objects identified by this scope are globally unique .

 When one bean Define settings scope by singleton When scoped , that Spring IOC The container only creates the bean The only instance of the definition . in other words , Whole Spring IOC Only one object of the current class will be created in the container .
The single instance is stored in the single instance cache (singleton cache) in , And all for this bean Subsequent requests and references are Will return cached 、 The only instance of this object .
singleton Responsible for the creation of objects 、 initialization 、 The destruction .

2) prototype: Multiple instances . Each time the object identified by this scope is acquired, a new object will be created .

 When one bean Define settings scope by singleton When scoped ,Spring IOC The container gets the current... Every time Bean when , Will produce a new Bean example ( amount to new The operation of )
prototype Only responsible for the creation and initialization of objects , Not responsible for destroying .

2.6.2 Single or multiple instances ?

The reason for using a single instance , There is no problem with thread safety , There is no need to create an object for every request , It's a waste CPU It's a waste of memory ;

There are many examples , To prevent concurrency problems ; A request changes the state of an object ( for example , Changeable member variables ), At this point, the object processes another request , However, the change of the object state caused by the previous request caused the object to deal with another request incorrectly ;

There is only one criterion for single and multiple cases : When an object contains a changeable state ( More precisely, in practical application, the state will change ), Use multiple instances , Otherwise, a single instance ;

stay Spring Middle configuration Bean Whether the instance is single or multiple, the method is :

Single case :

<bean id="user" scope="singleton" class="com.tedu.pojo.User"></bean>

Multiple cases :

<bean id="user" scope="prototype" class="com.tedu.pojo.User"></bean>

2.6.3 test spring Single instance and multi instance

1、 establish TestIOC2 class , The test code is as follows :

package com.tedu.spring;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestIOC2 {

public static void main(String[] args) {

/* adopt spring Container creation User object , * And call User Medium sayHi Method */
//1. load spring Core profile for 
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext(
"applicationContext.xml"
);
//2. from spring Get... In the container bean object ( Not myself new)
User user1 = (User) ac.getBean("user");
User user2 = (User) ac.getBean("user");
//3. test 
if(user1 == user2){

System.out.println(" The current instance is a single instance ...");
}else{

System.out.println(" The current instance is multi instance ...");
}
}
}

3、 take applicationContext.xml in ,User class bean Labeled scope Value is set to singleton:

<bean id="user" scope="singleton" class="com.tedu.pojo.User"></bean>

function TestIOC2, The running result is :

[ 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-gwjaL0iU-1638456215522)(JAVAWEB-NOTE04.assets/4f79acd66228d70451ef21a27911d21b.png)]

4、 take applicationContext.xml in ,User class bean Labeled scope Value is modified to prototype

<bean id="user" scope="prototype" class="com.tedu.pojo.User"></bean>

Run again TestIOC2, The running result is :

[ 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-I8cFOSYI-1638456215522)(JAVAWEB-NOTE04.assets/805f9db5f3eed078dc77876db32298ac.png)]

2.7 Spring DI Dependency injection


2.7.1 Two injection methods are introduced

DI(Dependency Injection) Dependency injection . Injection: Inject

Dependency injection , That is, the dependency relationship between components is determined by the container during the runtime of the application system , In other words, the container dynamically injects the target object instance of a certain dependency into each associated component in the application system .


Simply speaking , So called dependency injection is actually , At or after creating an object , How to assign values to the properties of an object .

If objects are created by ourselves , It all becomes very simple , for example :

User user = new User();
user.setName(" Han Shaoyun "); // adopt setName Method is name Attribute assignment 
user.setAge(18); // adopt setAge Method is age Attribute assignment 

perhaps :

User user = new User(" Han Shaoyun ", 18); // While creating objects , Assign values to the properties of an object through a parameter constructor 

If the object is from spring establish , that spring How to assign values to attributes ?spring There are two ways to assign values to properties :

(1).Set Way into

(2). Constructor injection

2.8 set Way into

2.8.1 Common attribute injection

demand : adopt Spring establish User example , And for User Example of name and age attribute ( General attribute ) assignment

1、 establish User class , Statement name and age attribute , And add the corresponding setter and getter Method , as well as toString Method

package com.tedu.spring;
public class User {

private String name;
private Integer age;
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public Integer getAge() {

return age;
}
public void setAge(Integer age) {

this.age = age;
}
@Override
public String toString() {

return "User [name=" + name + ", age=" + age + "]";
}
}

2、 stay applicationContext.xml In a statement User Class bean example

<!-- Statement User Class bean example -->
<bean id="user" class="com.tedu.spring.User"></bean>

3、 Create test class —TestDI

package com.tedu.spring;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDI {

public static void main(String[] args) {

//1. load applicationContext.xml Core profile 
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext(
"applicationContext.xml"
);
//2. obtain User Class 
User user = (User) ac.getBean("user");
//3. Output User example 
System.out.println( user );
}
}

Because there is no for User Object's property assignment , So run the test at this time , The result is :

[ 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-SkmSpy2d-1638456215523)(JAVAWEB-NOTE04.assets/1175a00c572e203e5413862754583a75.png)]

4、 modify applicationContext.xml in User Instance declaration , by User Instance injection properties

<!-- Statement User Class bean example -->
<bean id="user" class="com.tedu.spring.User">
<!-- adopt set Assign a value to a common attribute -->
<property name="name" value=" Han Shaoyun "></property>
<property name="age" value="20"></property>
</bean>

among name The value of the property , And User Class 【 Corresponding set Remove the method name set after 、 Names with lowercase initials 】 identical .

for example : by User Class age Attribute assignment , because name Property corresponds to set The method name is setAge,seAge Get rid of set And the name after the initial letter becomes lowercase is age, Therefore age The configuration content of attribute injection is :

<property name="age" value="20"></property>

Ordinary properties go directly through value Just inject .

5、 Run test class TestDI, The result is :

Through the top spring Provided set Way to User The properties of the object are assigned , So run the test at this time , The result is :

[ 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-3hs1dZPc-1638456215524)(JAVAWEB-NOTE04.assets/abda0664c744fdef3e8ece4ea2db2a45.png)]

2.8.2 Object attribute injection

demand : adopt Spring establish User example , And for User Object's userInfo attribute ( Object properties ) assignment

1、 establish UserInfo class

package com.tedu.spring;
public class UserInfo {

}

2、 stay applicationContext.xml in , Statement UserInfo Class bean example

<!-- Statement UserInfo Class bean example -->
<bean id="userInfo" class="com.tedu.spring.UserInfo"></bean>

3、 modify User class , Statement userInfo attribute , Add corresponding setter and getter Method , And regenerate toString Method

public class User {

...
private UserInfo userInfo;
public UserInfo getUserInfo() {

return userInfo;
}
public void setUserInfo(UserInfo userInfo) {

this.userInfo = userInfo;
}
...
public String toString() {

return "User [name=" + name + ", age=" + age + ", userInfo=" + userInfo + "]";
}
}

4、 stay applicationContext.xml in , take UserInfo Object as value , Assign a value to User Object's userInfo attribute

<!-- Statement User Class bean example -->
<bean id="user" class="com.tedu.spring.User">
<!-- adopt set Assign a value to a common attribute -->
<property name="name" value=" Han Shaoyun "></property>
<property name="age" value="20"></property>
<!-- adopt set Assign a value to an object property by -->
<property name="userInfo" ref="userInfo"></property>
</bean>

This will be due to UserInfo Object as a value assigned to another object's property , therefore ref The value of the property , by UserInfo object bean Labeled id value .

Object properties are passed through ref Attribute injection .

5、 Run test class TestDI, The result is :

[ 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-8BgicHdt-1638456215524)(JAVAWEB-NOTE04.assets/62c1243d1a13010db1a3c3cd8b116759.png)]

2.9 Constructor injection


demand : adopt Spring establish User object , And for User Object properties (name、age、UserInfo attribute ) assignment

1、 by User Class declaration constructor

// Declare a parameterless constructor 
public User() {

}
// Declare a constructor with parameters 
public User(String name, Integer age, UserInfo userInfo) {

super();
this.name = name;
this.age = age;
this.userInfo = userInfo;
}

2、 modify applicationContext.xml file , take set The method is modified to construct method injection .

<bean id="user" class="com.tedu.spring.User">
<!-- adopt set Assign a value to a common attribute <property name="name" value=" Han Shaoyun "></property> <property name="age" value="20"></property> <property name="userInfo" ref="userInfo"></property> -->
<!-- Assign values to attributes through parameters in the constructor -->
<constructor-arg name="name" value=" Jack ma, "></constructor-arg>
<constructor-arg name="age" value="35"></constructor-arg>
<constructor-arg name="userInfo" ref="userInfo"></constructor-arg>
</bean>
<!-- Statement UserInfo Class bean example -->
<bean id="userInfo" class="com.tedu.spring.UserInfo"></bean>

among ,constructor-arg label name The value of the property must be the same as the name of the parameter in the constructor !

alike , Ordinary properties go directly through value Just inject ;

Object properties are passed through ref Attribute injection .

3、 Run test class TestDI, The result is :

[ 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-MKWrVqjU-1638456215525)(JAVAWEB-NOTE04.assets/4b1ba956af8e1244bd1a30553f4fe6bf.png)]

2.10 Extended content


2.10.1 applicationContext.xml No prompt solution

1、 To configure spring-beans-4.1.xsd file

(1) find spring-beans-4.1.xsd The location of the file , for example :

[ 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-U0Jbp8vh-1638456215527)(JAVAWEB-NOTE04.assets/3526b8f7cb18db7def8c59c6b8f5a8c6.png)]

(2) Copy the following url Address :

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

(3) stay eclipse In the menu bar : window --> Preferences --> Search... In the search box [ xml ]

XML --> XML Catalog --> User Specified Entries --> Add…

[ 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-qR2HfJ1c-1638456215528)(JAVAWEB-NOTE04.assets/eef68594c0d7b072e09702b3d6289831.png)]

(4) In the pop-up window :

[ 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-QX8APka1-1638456215529)(JAVAWEB-NOTE04.assets/10a6f5e3901af4d2fd9cba0d644e00bd.png)]

2、 To configure spring-context-4.1.xsd file

(1) find spring-context-4.1.xsd The location of the file , for example :

[ 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-ZeAQLO6M-1638456215530)(JAVAWEB-NOTE04.assets/f88878c81816bfccdaf534b48ecbf37d.png)]

(2) Copy the following url Address :

http://www.springframework.org/schema/context/spring-context-4.0.xsd

(3) stay eclipse In the menu bar : window --> Preferences --> Search... In the search box [ xml ] XML --> XML Catalog --> User Specified Entries --> Add…

[ 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-dM5HLRW9-1638456215530)(JAVAWEB-NOTE04.assets/eef68594c0d7b072e09702b3d6289831.png)]

(4) In the pop-up window :

[ 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-lp2NQy2m-1638456215531)(JAVAWEB-NOTE04.assets/bab1eb1bf264e64de4a3672c96f23e8b.png)]

3 springmvc frame

3.1 MVC Design patterns


3.1.1 What is design pattern Reference resources day14–day18 springmvc

Design patterns (Design Pattern) It's a set that's been used over and over again 、 Most people know that 、 classified 、 Summary of code design experience .

The purpose of using design patterns : For code reusability 、 Make code easier to understand 、 Ensure code reliability .

Design patterns make coding really Engineering ;

Design pattern is the foundation of software engineering , Like the structure of a building .

Design pattern is a kind of mold , After years of practice, it has formed a set of effective steps and methods to complete a specific task .

for example : The brewing process of Xifeng wine , Brewing process , You can't change before and after , The temperature difference cannot change , This is good to drink , A little change will change the taste .

Again , Beijing Roast Duck , Just do that , It's those seasonings pickled , Variable ratio , The taste is not as good as others .

3.1.2 MVC Design patterns

MVC Design pattern is a general software programming idea

stay MVC The design pattern says , Any software can be divided into three parts

(1) The controller that controls the flow of programs (Controller) Servlet

(2) Encapsulating data processing models (Model) javaBean stay MVC In the design mode, the corresponding model is (Model), But I can't say Model yes javaBean The correspondence is different under different design modes . If you can't say that an animal is a cat .

(3) The view responsible for presenting data (view) JSP

And in MVC The design idea requires one to meet MVC The software with the design idea should ensure that the above three parts are independent of each other , Mutual interference , Each part is only responsible for what they are good at .

If a module changes , Try not to affect the other two modules . The advantage of this is , The structure of the software will become clearer , High readability . It is conducive to later expansion and maintenance , And the code can be reused .

[ 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-OCCU9LAV-1638456215532)(JAVAWEB-NOTE04.assets/20e60e831a34d3a4a68805e386aa1779.png)]

3.2 First time to know SpringMVC


3.2.1 Servlet The shortcomings of

1、 Usually , One Servlet Class is only responsible for processing one request , If there are hundreds of requests to be processed in a project , You need hundreds of Servlet class , This will make the project Servlet The number of classes has soared ;( However, multiple requests can also be accessed through configuration : The access path is changed to / If you configure another path label . He gives priority to other paths . Because wildcards have the lowest priority *. stay web.xml file )

And in the springmvc There is no need to write servlet, It helps you write . We just need to write controller class . You can add multiple methods to a class , A method can process a request .

2、 stay Servlet3.0 Before the release , every last Servlet Need to be in web.xml There are at least eight lines of configuration information in the file , The configuration content is numerous and cumbersome . When Servlet Especially when ,web.xml Too much configuration , Not good for team development ;

controller Class is an ordinary class and does not need to be in web.xml Configuration in file .

3、 When submitting parameters to the server through the client , adopt Servlet When receiving , No matter what format the data itself is , stay Servlet All are received according to the string , Type conversion is required in the later stage , Complex types also require special treatment , Especially troublesome

springmvc With parameter binding mechanism, it is easy to accept the parameters in the request .

String value = request.getParameter(String name);

4、servlet Container dependent , Must be run in the server , Not conducive to unit testing ;

servlet It's like a housekeeper Used to assign tasks javaBean Used to process requests

controller Class is an ordinary class that can be used for unit testing .

These shortcomings SpringMVC Will help you solve .

3.2.2 SpringMVC brief introduction

Springmvc yes spring A module of the framework ,spring and springmvc There is no need for intermediate integration layer to integrate ( From the same company , The default integration has been )

Springmvc It's based on mvc Of web frame

3.2.3 springmvc Execution principle

[ 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-CTQQbZGb-1638456215532)(JAVAWEB-NOTE04.assets/14c0c2f53620fb0e29c11170729226f0.png)]

(1). User sends request to Front controller (DispatcherServlet);

Tips :DispatcherServlet The role of : Receiving request , Call other components to process the request , In response to the results , It's like a transponder 、 a central processor , It is the center of the whole process control

(2). Front controller (DispatcherServlet) Invoke the processor mapper after receiving the request (HandlerMapping)

Processor mapper (HandlerMapping) Find specific Controller( According to xml To configure 、 Annotation to find ), And will Controller Return to DispatcherServlet;

(3). Front controller (DispatcherServlet) Call processor adapter (HandlerAdapter). The processor adapter calls the specific... After adaptation Controller;(Controller–> service --> Dao --> database )

Controller Return... After execution ModelAndView,

Tips :Model( model data , namely Controller Results of processing ,Map) View( Logical view name , That is, the person responsible for displaying the results JSP The name of the page )

Processor adapter (HandlerAdapter) take controller Results of execution (ModelAndView) Back to the front controller (DispatcherServlet);

(4). Front controller (DispatcherServlet) The result of the execution (ModelAndView) Pass it to the view parser (ViewReslover)

view resolver (ViewReslover) according to View( Logical view name ) Return details after parsing JSP page

(5). Front controller (DispatcherServlet) according to Model Yes View Rendering ( Fill model data into view );

Front controller (DispatcherServlet) The web page response filled with data is sent to the user .

The parts that need to be written by developers in the whole process are ControllerServiceDaoView;

3.3 springmvc Introductory cases


demand :

(1) Access... Through a browser http://localhost:8080/ Project name /hello Address , Output at console “hello springmvc”

(2) Turn the request to ( Jump to ) /WEB-INF/pages/home.jsp page

3.3.1 establish Maven—web engineering

1、 adopt Maven establish web engineering

[ 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-ObhSWLRk-1638456215533)(JAVAWEB-NOTE04.assets/image-20200410140300719.png)]

2、 stay pom.xml Introduction in springmvc what is needed jar package : Copy the following configuration directly to pom.xml Inside the root tag in

<dependencies>
<!-- unit testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- SpringMVC Of jar package ( In the import springmvc Of jar Package at the same time , It also introduced spring The basic operation of jar package , because springmvc At run time, you need to rely on spring frame ) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<!-- servlet and jsp Of jar package -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- java Object conversion json Tool class of <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.1</version> </dependency> -->
</dependencies>

3.3.2 stay web.xml Configure the front end controller

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- To configure springmvc Front controller , Give all requests to springmvc To deal with it ctrl+shift+t Collection -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- To configure springmvc Location of core profile , Default Springmvc The configuration file for is in WEB-INF Under the table of contents , The default name is springmvc-servlet.xml, If you want to put it in another directory , You need to specify the following configuration : contextConfigLocation It's a fixed name , Can't write wrong classpath: Specifies the class directory of the file This file is compiled and placed in the class directory , So write the class name directly here <param-name label > The contents can be specified at will , But ask up and down 2 Keep the same name . -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
</servlet>
<!-- The slash in it (/) Means to intercept all requests ( except JSP outside ), All requests go through springmvc Front controller /* The representative intercepts all requests , But it doesn't match -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

explain /* (* The wildcard )

After interception, it will cause a dead cycle .

[ 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-pKoHHu6G-1638456215533)(yonghe-ssm.assets/aaaa.PNG)]

3.3.3 Create and configure springmvc-config.xml

Just copy the contents of the following configuration file ! stay resources Create under directory spring-mvc Core profile for

<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 1. Configure the front-end controller to release static resources (html/css/js etc. , Otherwise static resources will not be accessible ) -->
<mvc:default-servlet-handler/>
<!-- 2. Enable default configuration , Configure annotation driver , Used to identify comments ( such as @Controller) -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 3. Configure packages that need to be scanned :spring Auto scan base-package Next class , If the scanned class has @Controller、@Service、@Component( Want to create an instance of a class , But I don't know which floor it belongs to. You can use this ) Etc , The class will be automatically registered as bean -->
<context:component-scan base-package="com.tedu.controller">
</context:component-scan>
<!-- 4. Configure the internal resource view parser prefix: Configure path prefixes jsp Root directory of the file suffix: Profile suffix jsp Extension of the file http://localhost:8080/day17-springmvc/hello perform testHello Method , Method finally return "home"; It's actually a jump to the name home Of jsp file /WEB-INF/pages/home.jsp The prefix and suffix are actually configured to return home The path is shorter Back to home Value is actually jsp file , It will spell... In the front Prefix , Spell the suffix after Namely jsp Access path of -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

3.3.4 Create and implement HelloController class

1、 establish com.tedu.controller.HelloController class

[ 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-hfgTL42X-1638456215534)(JAVAWEB-NOTE04.assets/image-20200411120818696.png)]

2、 Realization HelloController class


package com.tedu.controller;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tedu.pojo.User;
/* @Controller effect :(1) Identifies that the current class belongs to controller layer * (2) stay spring The container scans to com.tedu.controller Package class , If there are * @Controller、@Service When waiting for comments , Will give the instance of this class to spring Container to create use bean Labels are too cumbersome , Using packet scanning : If the package of the current class is configured with spring Package scan , The class with this annotation , Will act as bean Sign up to spring In the container , from spring Create an instance of the container . */
@Controller
//@RequestMapping("/abc")
public class HelloController {

/* 2.springmvc Get request parameters ( Parameter binding ) -- Simple parameter binding * /testParam01?name= Liu peixia &age=35&addr= tianjin adopt ? Spell the request parameters * How to get the data carried in the request ( That is, get the parameters in the request )? * springmvc Parameter binding mechanism is provided in : * If it is a single acquisition , You can declare the same number of parameters as the request on the method 、 With the same name * request.getParameter("name") It will call this method at the bottom , Then pass the obtained value to the formal parameter * Write a few formal parameters and then take a few parameters */
// Note that it doesn't matter if the parameter names of the method name and the access path are different .
@RequestMapping("/testParam01")
public String testParam01(String name, Integer age, String addr) {

System.out.println( "name="+name );
System.out.println( "age="+age );
System.out.println( "addr="+addr );
return "home";
}
/* 3. Simple parameter binding exercise : * /testParam02?username= zhaoyun &psw=123&nickname= Zhao Zilong * add to controller Method , Get... In the request username、psw、nickname Parameter values for */
@RequestMapping("/testParam02")
public String testParam02(String username,String psw,String nickname) {

System.out.println( "username="+username );
System.out.println( "psw="+psw );
System.out.println( "nickname="+nickname );
return "home";
}
/* 4.springmvc Get request parameters ( Parameter binding ) -- Packing type parameter binding * /testParam03?name= Liu peixia &age=35&addr= tianjin * How to get the data carried in the request ( That is, get the parameters in the request )? * springmvc Parameter binding mechanism is provided in : * If you get through an object , You need to ensure that there is a corresponding parameter in the packaging object set Method * Provide a User class : In order to accept and encapsulate Number attribute value , Provide the corresponding set get Method * The tone of the interview is set get Method * If there are many parameters , Or just want to encapsulate parameters with objects , Just bind with the parameters of the wrapper type Its bottom layer will automatically call the corresponding in the request parameters pojo Object's set Method , Encapsulate the request parameters on the object , Note the difference from the data in the table in the query database before ? mybatis, Previously, the packaging was setxxx Method , If there is no direct assignment to the attribute ( Access permissions need to be set ) springmvc, Now the encapsulation request parameter is , Only use setxxx Method assignment . */
@RequestMapping("/testParam03")
public String testParam03( User user ) {

System.out.println( user );
return "home";
}
/* Details of parameter binding : * 5.1. How to get multiple parameter values corresponding to a parameter name ? Declare an array of parameter types to accept .(request There is a method to get the parameter array , You only need to define a formal parameter of parameter array type . Through the parameter binding mechanism, the bottom layer will automatically call this method ) * 5.2. How to get a date type parameter ? What problems might exist ? How to solve ? Just in the way Make a statement Date Type parameters . * /testParam04?like= Basketball &like= football &like= Volleyball &date=2020/7/22 11:41:32 * /testParam04?like= Basketball &like= football &like= Volleyball &date=2020-7-22 11:41:32 * String[] like = request.getParameterValues("like") * 400 error , It is caused by mismatched parameter types , for example , Use Integer/int Receive a non numeric value * Or use a date object to receive a string in a non date format * because springmvc The default date format is in "/"( Slash ) Separate , So when the browser passes the date with a slash * Separate ,springmvc It can be obtained through parameter binding * But if the date passed by the browser is separated by other symbols ( for example :- Horizontal bar ), stay springmvc It seems that this is not a date * So it's impossible to get , Will report 400 error ! * resolvent : (1) When passing the date parameter through the browser , Don't use a bar to separate , But with slashes (/) Separate * (2) take springmvc The default received date format is changed to a horizontal bar (-) Separate ! Use , Custom date format converter , In this class Write . */
@RequestMapping("/testParam04")
public String testParam04( String[] like, Date date ) {

System.out.println( Arrays.toString( like ) );
System.out.println( date );
return "home";
}
/* 1. Quick start * @RequestMapping Configure the access path for the current class or method , * requirement : Access path on class + The access path on the method cannot be repeated , Otherwise, it will throw an exception ! * If there is an access path on the class , First add the path on the class and the access path of the method * Publish the project to the server ,java File resource files cannot be accessed directly We need to configure the access path ourselves , First access the path of the project, and then configure the access path on the spelling . servlet You can directly access : Right click ---run as and jsp Files can be accessed indirectly , By means of controller Write a method with return value type , Configure the access path through annotation on the class and method , The return value of the method jumps to jsp page . The premise is that web.xml Interceptor in file Publish the project to the server ,java File resource files cannot be accessed directly ,servlet Sure . How to access the : Right click the item on the left --run as( This is publishing to the server on the project , Start the server ) Then add the access path of the method to access the methods in this class . Jump to... Through this return value jsp. web Resources can be directly right clicked run--as */
@RequestMapping("/hello01")
public String testHello01() {

System.out.println("testHello01()...");
// Jump to /WEB-INF/pages/home.jsp 
// Why write a home You can jump to Specific directory files , Because the prefix and suffix are configured in the configuration file .
return "home";
}
@RequestMapping("/hello02")
public String testHello02() {

System.out.println("testHello02()...");
return "home";
}
/* Custom date format converter * take springmvc Default to slash (/) Separate dates with horizontal bars instead (-) */
@InitBinder
public void InitBinder (ServletRequestDataBinder binder){

binder.registerCustomEditor(java.util.Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true)
);
}
}
//usesr class Used to encapsulate multiple request parameters Omit ( Pay attention to this pojo It encapsulates the request parameters , Before that, query the records of the database )

[ 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-wzxwZsFU-1638456215535)(yonghe-ssm.assets/bbbb.PNG)]

3.3.5 Create and implement home.jsp

stay WEB-INF/pages/ Under the table of contents , establish home.jsp page . Right click to create a directory Folder Creating a jsp file

WEB-INF/pages/home.jsp

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>day16-springmvc...home.jsp....</h1>
</body>
</html>

3.3.6 Access test

Open the browser , Input url Address :http://localhost:8080/day16-springmv/hello Address , The results are as follows :

[ 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-wSZdWVJO-1638456215535)(JAVAWEB-NOTE04.assets/image-20200411120516046.png)]

3.4 springmvc Parameter binding


When... Is introduced into the project springmvc After the framework , All requests will be circulated by springmvc Control , When the request sent by the client contains data ( That is, request parameters ) when , So how to be in controller The layer obtains these parameters ?

springmvc It will automatically match the parameters contained in the request with the parameters of the method , That is, as long as you guarantee , The parameter name in the request corresponds to the parameter name in the method ( another , The format of parameters should also be correct ), These parameters can be used in methods — That is, the parameters in the request .

3.4.1 Basic type parameter binding

When you need to get a small amount of data sent by the client , Can be in Controller On the method declared in , Receive these parameters one by one by declaring method parameters , Specific examples are as follows :

demand : Send a request to access... Through the browser Controller, And carry... In the request name、age Data access server , On the server side
Controller Get these data from .

1、 stay HelloController Class testParam1 Method , Used to receive parameters of basic types , The code implementation is as follows :

package com.tedu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller /* This annotation indicates that the current class belongs to the control layer */
public class HelloController {

/* 1、 test springmvc Simple type parameter binding * ../testParam1?name= Zhang Fei &age=20&addr= hebei * How to get the information in the request name、age、addr Parameter values for ? * request.getParameter("name") -- Zhang Fei * Add three of the same type to the method 、 The formal parameters with the same name are name、age、addr * Used to receive requests name、age、addr The value of the parameter */
@RequestMapping("/testParam1")
public String testParam1(String name, Integer age, String addr) {

System.out.println( "name="+name );
System.out.println( "age="+age );
System.out.println( "addr="+addr );
return "home";
}
}

2、 visit HelloController Medium testParam1 Method , During the visit , Pay attention to name、age、addr Parameters are sent to the server together :

[ 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-EnZGlTJj-1638456215536)(JAVAWEB-NOTE04.assets/image-20200411121233000.png)]

The console output is :

[ 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-Zg1jgePf-1638456215536)(JAVAWEB-NOTE04.assets/image-20200411121322974.png)]

3.4.2 Packing type parameter binding

When you need to obtain multiple data sent by the client , Can be in Controller On the method declared in , It is troublesome to receive these data one by one by declaring method parameters , You can declare the parameters of the object type on the method , Through the unified acceptance of these data ,springmvc The received parameters will be automatically encapsulated in the object , Specific examples are as follows :

1、 stay HelloController Class param2 Method , Parameters used to receive object types , The code implementation is as follows :

package com.tedu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller /* This annotation indicates that the current class belongs to the control layer */
public class HelloController {

/* 2、 test springmvc Wrapper type parameter binding * ../testParam2?name= Guan yu &age=30&addr= Beijing * How to get the information in the request name、age、addr Parameter values for ? * Provide a User class , Add an attribute with the same name as the request parameter to the class * The bottom layer calls setName、setAge、setAddr Method encapsulates the parameter value into User In the object */
@RequestMapping("/testParam2")
public String testParam2(User user) {

System.out.println( "user.name="+user.getName() );
System.out.println( "user.age="+user.getAge() );
System.out.println( "user.addr="+user.getAddr() );
return "home";
}
}

3、 establish User class , Statement name、age、addr attribute , Provide the corresponding set and get Method

package com.tedu.pojo;
/** * Encapsulating user information Multiple request parameters are encapsulated in one User Object, that is, the parameter binding of wrapper type , adopt set and get Method to access . The encapsulated parameter name should have a corresponding set and get Method , If so, it will be encapsulated successfully , No encapsulation will fail . mybatis The data in the queried database is encapsulated into pojo In the object , Can pass set and get Method , If not, you can assign values directly through private attributes . and springmvc Parameter binding of wrapper type can only be through set and get Method to obtain the data of the request parameters . */
public class User {

private String name;
private Integer age;
private String addr;
public User() {
} // Parameter free constructor 
public User(String name, Integer age, String addr) {

super();
this.name = name;
this.age = age;
this.addr = addr;
}
//get、set Method 
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public Integer getAge() {

return age;
}
public void setAge(Integer age) {

this.age = age;
}
public String getAddr() {

return addr;
}
public void setAddr(String addr) {

this.addr = addr;
}
}

4、 visit HelloController Medium param2 Method , During the visit , Pay attention to name and age Parameters are sent to the server together :

[ 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-kAqMPSM7-1638456215537)(JAVAWEB-NOTE04.assets/image-20200411125305873.png)]

The console output is :

[ 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-rk9GQ4PZ-1638456215537)(JAVAWEB-NOTE04.assets/image-20200411125340557.png)]

3.4.3 Date type parameter binding

1、 stay HelloController Class testParam3 Method , The code implementation is as follows :

@Controller /* This annotation indicates that the current class belongs to the control layer */
public class HelloController {

/* 3、 test springmvc Date type parameter binding * ../testParam3?date=2020-4-10 16:40:39 newspaper 400 error , Indicates that the parameter types do not match * ../testParam3?date=2020/4/10 16:40:39 * How to get the information in the request date The value of the parameter ? * springmvc The default is to receive date type parameters with slashes , If the submission date is a slash * separated , springmvc You can receive parameters of this date type , Otherwise, you will not be able to receive * If the submitted date parameter is separated by a horizontal bar , You can also modify springmvc Default receive format * To be separated by a horizontal bar !! */
@RequestMapping("/testParam3")
public String testParam3(Date date) {

System.out.println( "date="+date );
return "home";
}
}

2、 visit HelloController Medium testParam3 Method , During the visit , Pay attention to date Parameters are sent to the server together :

The console output is :

common problem :

1、 When accessing HelloController Medium testParam3 Method , If the date data passed to the server is in the following format :

[ 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-8mg2UiAy-1638456215538)(JAVAWEB-NOTE04.assets/image-20200410165410638.png)]

As you can see from the diagram , If the date parameter is yyyy-MM-dd Format ( Separated by a bar ) Will appear 400 error , In fact, it's because the parameter format matches incorrectly , because springmvc The default date format is yyyy/MM/dd( Separated by slashes ), So if the date parameter is not yyyy/MM/dd Format , Will appear 400 error !!

2、 Solution :

stay springmvc in , Provides @InitBinder annotation , Used to specify a custom date conversion format , therefore , All we need to do is Controller Add the following code to the class , When accepting parameters of date type , It will be automatically converted according to the custom date format .

 /* Custom date format converter * take springmvc Default to slash (/) Separate dates with horizontal bars instead (-) */
@InitBinder
public void InitBinder (ServletRequestDataBinder binder){

binder.registerCustomEditor(java.util.Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true)
);
}

3、 The test again :

[ 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-2N0sWatm-1638456215539)(JAVAWEB-NOTE04.assets/image-20200411125752937.png)]

The console output is :

[ 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-N8nZOErD-1638456215539)(JAVAWEB-NOTE04.assets/image-20200411125827915.png)]

3.5 Jump and garbled code processing


3.5.1 Implement forwarding (forward)

in front request Object learning , adopt request Object can realize request forwarding ( That is, the jump of resources ). alike ,springmvc It also provides the way of request forwarding , The specific implementation is as follows :

demand : Access... Through a browser testForward Method , perform testForward After the method , Forward the request to (HelloController)hello, That is to say home.jsp page .

1、 stay HelloController in , Provide testForward Method , The code implementation is as follows :( The premise is the same web application )

Be careful : java Files cannot be accessed directly , Can only be accessed by configuring annotations on class methods .

And the others web- Resource files can be accessed directly , But if web-inf The directory cannot be accessed directly ( It's safer to put it in this directory ), Put it in web-inf The directory of resources can only be forwarded by request , Redirection doesn't work .

@Controller
public class HelloController02 {

/* 1、 test springmvc Forwarding * (1) If in controller Methods the internal 【 return “jsp Name ”】 From the current method * Forward to this jsp ( Only forwarding can jump to /WEB-INF Resources in the directory ) This form is forwarding by default * (2) If it is from the current controller Method jump to another controller Method * At this time need 【return "forward:/ Resource path "】 * for example : When a browser accesses "/testForward" when ,testForward Method execution , Inside the method * Jump to "/test" The method corresponding to the path (test Method ) forward: forward */ Mapping: Provide information / It can be omitted
@RequestMapping("/testForward")
public String testForward() {

System.out.println("testForward() Yes ... About to jump to /test route ..");
return "forward:/test"; // Jump to the test Method 
}
@RequestMapping("/test")
public String test() {

System.out.println("test Method executed ... About to jump to test.jsp...");
// Forwarding to test.jsp ( The default is forward , So there's no need to add forward)
return "test"; // Jump to test.jsp, This is also forwarding , Forward through the return value of the method, and jump to... By default jsp page , There is no need to write forward.
}
}

test,jsp file

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>day17-springmvc~~~test.jsp~~~</h1>
</body>
</html>

2、 Open the browser , Enter... In the browser :http://localhost/day16-springmvc/testForward Address , The interview effect is as follows :

[ 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-zprNCdfP-1638456215540)(JAVAWEB-NOTE04.assets/image-20200411125952494.png)]

forward The way is equivalent to :

request.getRequestDispatcher("url").forward(request,response);

Forwarding is a request , One response ;

The address in the address bar has not changed after forwarding ( Or visit testForward The address of );

Before and after forwarding request and response The object is the same .

3.5.2 Implement redirection (redirect)

in front response Object learning , adopt response Object can implement request redirection ( That is, the jump of resources ).

alike ,springmvc It also provides a way to request redirection , The specific implementation is as follows :

demand : Access... Through a browser testRedirect Method , perform testRedirect After the method , Redirect request to
(HelloController)hello, That is to say home.jsp page .

1、 stay HelloController in , Provide testRedirect Method , The code implementation is as follows :

/* 2、 test springmvc The redirection of * (1) From the current controller Redirect the method in to another controller Method * (2) You can also start from the current controller Method to redirect to other application resources * (3) You can also start from the current controller Method to redirect to resources inside other servers * 【return "redirect:/ Resource path "】 * The redirection address bar path will change from testRedirect Turn into test */
@RequestMapping("/testRedirect")
public String testRedirect() {

System.out.println("testRedirect Method executed .. About to jump to /test...");
Redirect different methods //return "redirect:/test"; // Redirect to /test
Redirect different resources //return "redirect:http://localhost:8080/day11-jsp/home.jsp";
Redirect different server resources return "redirect:http://www.baidu.com";
}
@RequestMapping("/test")
public String test() {

System.out.println("test Method executed ... About to jump to test.jsp...");
// Forwarding to test.jsp This place writes forwarding just to test redirection 
return "test"; // Jump to test.jsp
}

2、 Open the browser , Enter... In the browser :http://localhost/day16-springmvc/testRedirect Address , The interview effect is as follows :

[ 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-Hhbd1hup-1638456215540)(JAVAWEB-NOTE04.assets/image-20200411130114886.png)]

redirect The way is equivalent to :

response.sendRedirect(url);

Redirection is two requests , Two responses ;

After the reset, the address in the address bar has changed ( Change to the address after forwarding );

And before and after redirection ,request and response The object is not the same .

3.5.3 Jumble handling

In front of Servlet I am learning , We learned GET and POST How to solve the garbled request parameters .

springmvc It also provides a solution to the garbled request parameters , Is in the web.xml Add the following code to ( Configure request parameter garbled filter ), Can solve POST The Chinese parameters submitted are garbled !

<!-- Configure filters , solve POST The Chinese parameters submitted are garbled -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern> <!--/*: On behalf of intercepting all garbled code problems , Filter all requests -->
</filter-mapping>

Test class The method in : Use Post Submit : Provide a html Medium form Form submission parameters

/* 3、 test springmvc Request parameter garbled processing
* (1) If it is GET Submit 、tomcat by 8.0 And later versions ,GET When obtaining the submitted Chinese parameters , yes
* There's no messy code !
* (2) If it is POST Submit , No matter which version of tomcat,POST When obtaining the submitted Chinese parameters , All are
* There are garbled , request The solution in is : Before getting the code for any parameters , Add the following code
* request.setCharacterEncoding("utf-8");
* If it is springmvc, solve post The Chinese parameters submitted are garbled , You only need to configure one filter , Can
* Achieve the effect of once and for all .( Effective for the whole project )
* Need to be in web.xml Start... In file springmvc Filter , solve POST The Chinese parameters submitted are garbled !
* // Get... In the request user and like The corresponding parameter value */
@RequestMapping("/testParam05")
public String testParam05(String user, String[] like) {
System.out.println( "user="+user );
System.out.println( "like="+ Arrays.toString( like ) );
return "test";
}

Servlet in , Two kinds of request methods and garbled code solution review :( Only for the present servlet It works , If something else servlet Also need to get, then there will be the problem of garbled code .)

(1) If the request method is POST Submit , There is bound to be garbled code , The solution is before any code that gets parameters , Add the following code :

request.setCharacterEncoding("utf-8");

(2) If the request method is GET Submit ,tomcat8 And later versions have solved GET The Chinese parameters submitted are garbled , Therefore, no processing is required ; stay tomcat7 And previous versions , obtain GET The Chinese parameters submitted are still garbled , The solution is : Only need [tomcat]/conf/server.xml The following configuration can also solve the problem of garbled code .

[ 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-24aDzjVh-1638456215541)(JAVAWEB-NOTE04.assets/31a1d635302b07dcec001a8cb8a27a4f.png)]

3.6 springmvc The response data


3.6.1 Model Use

When requesting access Controller Method in , It can be declared by parameters , Used within methods Model.( from controller The way to jump to jsp file )

@RequestMapping("/doorList")
public String doorList(Model model){
}

Model The object is actually a Map aggregate , for example : Go to model Add an attribute to

model.addAttribute(String name, Object value);

among ,addAttribute Method will save the attribute to request domain , Then, the attribute data is brought to the corresponding... By forwarding JSP in , adopt ${} Take out and Show .

Example , Go to Model Add attributes in :

/* * 4、springmvc The response data : * How to go from Servlet Bring data to JSP? * request Domain object + Request forwarding * How to go from controller Method to bring data to JSP? * Model( The bottom is request Domain )+ Request forwarding */
@RequestMapping("/testModel01")
public String testModel01( Model model ) {
 //Model When you want to use it, you can directly declare and call 
// The request is processed , The result of processing is a User object 
// Make a statement User object , take User Objects in Model in stay User Class Declare a construction method with parameters 
User user = new User(" Zhang Sanfan ",30," Beijing Shijingshan ");
model.addAttribute( "user", user );
//request.setAttribute( "user", user );
// Forwarding to test.jsp
return "test";
}
@RequestMapping("/testModel02")
public String testModel02( Model model ) {

// The request is processed , The result of processing is a List<User> object 
// Make a statement List aggregate , And save the collection in Model domain 
List<User> userList = new ArrayList();
userList.add( new User(" Zhang Sanfan ", 30, " Beijing Shijingshan ") );
userList.add( new User(" Li Si ", 38, " Beijing changping ") );
model.addAttribute( "list", userList );
//request.setAttribute( "user", user );
// Forwarding to test.jsp
return "test";
}

stay home.jsp Take out the attribute and display :

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>day17-springmvc~~~test.jsp~~~</h1>
<%-- ${} It can be downloaded from request Domain Get data in Object's data The bottom is Map aggregate , adopt key obtain value--%>
${ user.getName() }
${ user.getAge() }
${ user.getAddr() }
<hr/> <!--EL Labels can be abbreviated : -->
${ user.name }
${ user.age }
${ user.addr }
<hr/>
<%-- adopt ${} from request Get... In domain List aggregate Data in the collection --%>
${ list[0] } <br/>
${ list[1] } <br/>
</body>
</html>

3.7 Extended content


3.7.1 springmvc The solution for the front-end controller to release static resources

In the configuration SpringMVC When developing the environment , Will be in web.xml Configuration in file SpringMVC Front end controller for , Send all requests to the front-end controller for processing , So in url-pattern A slash is configured in (/):

<!-- 1. To configure springmvc Front controller , And submit all requests to springmvc Handle -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- To configure springmvc Location of core profile , Default Springmvc The configuration file for is in WEB-INF Under the table of contents , The default name is springmvc-servlet.xml, If you want to put it in another directory , You need to specify the following configuration : -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- A slash indicates that all requests are blocked ( except JSP outside ) -->
<url-pattern>/</url-pattern>
</servlet-mapping>

url-pattern Slashes configured in (/) Means that it will be in addition to JSP Other requests are blocked , hand spring Front end controller to handle .

But this configuration , Access to static resources will also be blocked , Cause access to static resources , appear 404( Resource not found ), because spring The front-end controller of takes the access to static resources as an controller request , To configure the corresponding mapping path , Of course I can't find .

For example, visit :http://localhost/day15-springmvc/home.html, Because the configuration is a slash (/), So static resources will be intercepted at this time , To controller The matching path in is /home.html Methods , At this time, it is naturally unmatched .

If you need to access static resources , Let the front-end controller release the request for static resources . You can do it in springmvc-config.xml Add the configuration of releasing static resources to the file :

<!-- 1. Configure the front-end controller to release static resources (html/css/js etc. , Otherwise static resources will not be accessible ) -->
<mvc:default-servlet-handler/>

3.7.2 applicationContext.xml There is no prompt solution

1、 To configure spring-beans-4.1.xsd file

(1) find spring-beans-4.1.xsd The location of the file , for example :

[ 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-yT4nKBGM-1638456215542)(JAVAWEB-NOTE04.assets/3526b8f7cb18db7def8c59c6b8f5a8c6.png)]

(2) Copy the following url Address :

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

(3) stay eclipse In the menu bar : window --> Preferences --> Search... In the search box [ xml ]

XML --> XML Catalog --> User Specified Entries --> Add…

[ 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-TSqxnod1-1638456215542)(JAVAWEB-NOTE04.assets/eef68594c0d7b072e09702b3d6289831.png)]

(4) In the pop-up window :

[ 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-XiKX8OGE-1638456215543)(JAVAWEB-NOTE04.assets/10a6f5e3901af4d2fd9cba0d644e00bd.png)]

2、 To configure spring-context-4.0.xsd file

(1) find spring-context-4.0.xsd The location of the file , for example :

[ 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-RqOMXLzh-1638456215543)(JAVAWEB-NOTE04.assets/f88878c81816bfccdaf534b48ecbf37d.png)]

(2) Copy the following url Address :

http://www.springframework.org/schema/context/spring-context-4.0.xsd

(3) stay eclipse In the menu bar : window --> Preferences --> Search... In the search box [ xml ]

XML --> XML Catalog --> User Specified Entries --> Add…

[ 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-G9FyvctI-1638456215544)(JAVAWEB-NOTE04.assets/eef68594c0d7b072e09702b3d6289831.png)]

(4) In the pop-up window :

[ 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-oYQ9QtNQ-1638456215544)(JAVAWEB-NOTE04.assets/bab1eb1bf264e64de4a3672c96f23e8b.png)]

copyright:author[Cool breeze AAA],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/02/202202130735392887.html