In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "summarizing from single architecture to distributed data persistence, Mybatis of ORM framework". In daily operation, I believe many people have doubts about summarizing the Mybatis problem of ORM framework from single architecture to distributed data persistence. The editor consulted all kinds of materials and sorted out simple and useful operation methods. I hope to answer "summary from single architecture to distributed data persistence." The confusion of "Mybatis of the ORM framework" helps! Next, please follow the editor to study!
1 pre-concept
01 persistence
Persistence is saving data to a storage device that can be permanently stored, such as a disk.
02 JDBC
In the process of learning Java, when learning Java to access the database, most programmers must first learn JDBC, which is a Java API used to execute SQL statements, provides unified access to the database, and "persists" the data to the database.
Let me explain it again (students who have some knowledge of JDBC can just skip it):
Sun released JDK1.1 in 1997, JDBC is an important technical point in this version, to use Java language to connect to the database, the normal thinking is Sun company to achieve how to connect to the database, if the implementation of SQL statements, but there are too many databases in the market, there are great differences between databases, and it is impossible for Sun company to know the internal details of each database.
So in order to make Java code better connect with the database, Sun company then developed a series of interfaces, that is, interfaces, in fact, it is a set of [standards], a set of [specifications], specific code how to achieve by the various database manufacturers to knock the code; so we often say that the "driver class" is the implementation class of each manufacturer.
So when we connect to the database with JDBC, the first step is to register the driver, which is to tell JVM which database implementation class to operate on.
03 ORM
Before we had the ORM framework, we needed to manipulate the database like this:
We can see that using JDBC to operate the database, the code is more tedious, the parameter spelling is easy to make mistakes in SQL, and the readability is relatively poor, which increases the difficulty of code maintenance.
With the ORM framework, we manipulate the database as follows:
ORM framework makes a mapping between Java objects and database tables, which encapsulates the access details of the database. When we need to operate database statements, we can directly manipulate Java objects.
2Spring Boot integrated MyBatis
The ORM frameworks commonly used in Java are Hibernate, MyBatis, JPA and so on. I will compare the advantages and disadvantages of this framework later. This chapter mainly introduces the Spring Boot project integrating MyBatis to access the database.
Step 1. Add dependency
Mysql mysql-connector-java org.mybatis.spring.boot mybatis-spring-boot-starter 2.0.1
Step 2. Configure database links
Configure database-related information in the application.yml file.
# data Source configuration spring: datasource: # Database driver driver-class-name: com.mysql.cj.jdbc.Driver # Database url url: jdbc:mysql://127.0.0.1:3306/arch?characterEncoding=UTF-8&serverTimezone=UTC # username username: root # password password: root
Step 3. Configure database links
On our local database, create a user table and insert a piece of data:
CREATE TABLE IF NOT EXISTS `user` (`id` INT UNSIGNED AUTO_INCREMENT, `userid` VARCHAR (100) NOT NULL, `username` VARCHAR (100) NOT NULL, `gender` CHAR (1) NOT NULL, `age` INT NOT NULL, PRIMARY KEY (`id`) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into user (userid, username, gender, age) values ('Uncle dashu','', 'Maure.18)
Step 4. Create a Model layer
For objects that are usually used to receive data from a database, I create a separate model package, and I am used to keeping the properties in the class the same as the fields.
Package com.archevolution.chapter4.model; public class User {private int id;// primary key ID, self-growing private String userId;// user ID, or as login private String userName;// user name private String gender;// gender private int age;// age / / omitting get, set, toString methods}
Step 5. Create a Dao layer
The code that usually deals directly with the database, we put them in the DAO layer (Data Access Object), where the data access logic is all here.
Let's create a new dao package and create a new * * API * * below. Note that it is an interface:
@ Mapper public interface UserDao {@ Select ("SELECT id, userId, userName, gender, age FROM USER WHERE id = # {id}") public User queryUserById (@ Param ("id") int id);}
Let me say a few more words here!
From a technical point of view, the attributes in model can be different from the fields in the table. For example, the field in which we add a mobile phone number in the database is called [mobilephone]:
-- add the mobile number field ALTER TABLE user ADD mobilephone varchar (15);-- update the mobile number of userid = 1: update user set mobilephone = '13800000000' where userid =' 1'
We add a field to the User.java called [telephone]:
We know that [telephone] corresponds to [mobilephone] in the database, but how do we let Mybatis know that these two fields correspond? There are several ways:
01. Control in the SQL statement to alias fields with different names:
@ Select ("SELECT id, userId, userName, gender, age, mobilephone as telephone FROM USER WHERE id = # {id}") public User queryUserTelById (@ Param ("id") int id)
02. Use the @ Results tag to map settings with different attributes and fields (those with the same name may not be written):
Select ("SELECT id, userId, userName, gender, age, mobilephone FROM USER WHERE id = # {id}") @ Results ({@ Result (property = "telephone", column = "mobilephone")}) public User queryUserTelById2 (@ Param ("id") int id)
However, I still suggest that when you write the model class, the properties and the fields in the table should be kept exactly the same, which can not only reduce the complexity of the code, but also greatly increase the readability of the code and reduce the possibility of errors.
Some students may wonder that the data structures of many projects are not so standardized. For example, the field name may be a very strange name, such as flag01 and flag02. If such a field is queried from the database and returned through the interface, will the readability of the interface be too poor?
Usually we will not directly package the contents of model to return, model is a lot of database and Java object mapping, and transfer data, we usually need DTO; we query the data from the database into model, before returning data in the interface, convert model to DTO, while the attributes in DTO need to ensure its standardization and see the name.
Step 6. Create a Service layer
Our project now has a Dao layer for accessing data, a Controller layer, and users provide interface access, so can Controller directly call methods in Dao? It's best not to call it directly!
Usually we will create a Service layer to store the business logic, and the complete invocation process at this time is:
Controller-Service-Dao
After creating the Service package, create a UserService in it:
@ Service public class UserService {@ Autowired UserDao userDao; public User queryUserById (int id) {return userDao.queryUserById (id);}}
Step 7. Add interfaces to the Controller layer
Add an interface to query customer information through userId and return customer information:
@ RequestMapping (value = "/ queryUser/ {id}") @ ResponseBody public String queryUserById (@ PathVariable ("id") int id) {User user = userService.queryUserById (id); return user = = null? "User is not find": user.toString ();}
Step 8. Test verification
If you access the interface in the browser or client for debugging and testing, you can query the customer information:
Http://127.0.0.1:8088/queryUser/1 User [id=1, userId=dashu, Uncle userName=, gender=M, age=18, telephone=null]
Other operations of 03MyBatis
Only the key code is given. Please refer to the project code in this chapter for the complete code.
01. Add
Insert ("INSERT INTO USER (userId, userName, gender, age) values" + "(# {userId}, # {userName}, # {gender}, # {age})") public void insertUser (User user)
02. Modify
@ Update ("UPDATE USER SET mobilephone = # {telephone} WHERE id = # {id}") public void updateUserTel (User user)
03. Delete
@ Delete ("DELETE FROM USER WHERE id = # {id}") public void deleteUserById (@ Param ("id") int id)
4 the code is perfect
Above, we have completed the simplest integration of Spring Boot and MyBatis, which can read the database and do CRUD normally, but because it is the simplest integration, there are some details that need to be improved, such as:
The parameters are displayed in url.
Return directly to Object.toString (), which is not very friendly
No data was found or an exception occurred, and no special handling was done.
Next, let's gradually improve.
01. Send a Post request using Json as a parameter
If you strictly follow the Restful style, you need to follow:
Query: GET / url/xxx
Added: POST / url
Modified: PUT / url/xxx
Delete: DELETE / url/xxx
Here we simply think that if we write the parameters in url, it is easy to see the contents of our parameters at a glance, and if there are too many parameters, the url will be too long, so we are usually used to using Json as a parameter to send Post requests. For example, the API for adding User can be written as follows:
Add DTO package and create a new UserDTO:
/ / using Josn as a parameter, you need to set headers = {"content-type=application/json"} / / @ RequestBody UserDto userDto to automatically bind and convert the JSON string to UserDto @ RequestMapping (value = "/ insertUser2", headers = {"content-type=application/json"}) @ ResponseBody public String insertUser2 (@ RequestBody UserDto userDto) {/ / DTO to Model User user = new User (); user.setUserId (userDto.getUserId ()); user.setUserName (userDto.getUserName ()) User.setGender (userDto.getGender ()); user.setAge (userDto.getAge ()); userService.insertUser (user); return "Success";}
Add the API of User:
/ / using Josn as a parameter, you need to set headers = {"content-type=application/json"} / / @ RequestBody UserDto userDto to automatically bind and convert the JSON string to UserDto @ RequestMapping (value = "/ insertUser2", headers = {"content-type=application/json"}) @ ResponseBody public String insertUser2 (@ RequestBody UserDto userDto) {/ / DTO to Model User user = new User (); user.setUserId (userDto.getUserId ()); user.setUserName (userDto.getUserName ()) User.setGender (userDto.getGender ()); user.setAge (userDto.getAge ()); userService.insertUser (user); return "Success";}
Let's call the interface to test:
{"userId": "lisi", "userName": "Li Si", "gender": "F", "age": "40", "telephone": "18600000000"}
02. Standard return parameter
Return directly to Object.toString (), which is not very friendly
Let's design a simple return parameter object, including code- status code, message- exception information description, data- data:
Public class JsonResponse {private String code; private String message; private Object data; / / omit set, get methods}
For code, we refer to Http status codes and use several commonly used ones:
Public class ResponseCode {public static final String SUCCESS = "200"; / / query success public static final String SUCCESS_NULL =" 204"; / / query success, but no data public static final String PARAMETERERROR = "400"; / / Parameter error public static final String FAIL =" 500"; / / Server exception}
At this point, let's rewrite the query interface:
@ RequestMapping (value = "/ queryUser2") @ ResponseBody public JsonResponse queryUser2ById (@ RequestBody UserDto userDto) {JsonResponse res = new JsonResponse (); / / omit parameter check User user = userService.queryUserById (userDto.getUserId ()); if (user! = null) {/ / can query the result and encapsulate it in the return parameter res.setCode (ResponseCode.SUCCESS); res.setData (user) } else {/ / if the query does not get a result, return '204' res.setCode (ResponseCode.SUCCESS_NULL); res.setMessage ("data not found");} return res;}
The encapsulated return parameter can be seen in the call result, which seems to be a lot of specification:
{"code": "200"," message ": null," data ": {" id ": 3," userId ":" lisi "," userName ":" Li Si "," gender ":" F "," age ": 40," telephone ": null}}
03. Exception handling
What if an exception occurs while the code is running? Return the abnormal information directly to the front end? This is not very friendly to the caller. Usually we print the error log locally and return an exception status code to the caller.
The set of Service and Dao layers is thrown up:
Public User queryUserById (int userId) throws Exception {return userDao.queryUserById (userId);}
Catch the exception in the Controller layer and encapsulate the return parameter:
User user = new User (); try {user = userService.queryUserById (userDto.getId ());} catch (Exception e) {res.setCode (ResponseCode.FAIL); res.setMessage ("Service exception");}
Frequently asked questions about 4MyBatis
01. Why is MyBatis called the semi-automatic ORM framework?
If there is semi-automatic, there will be full automatic.
Hibernate belongs to the fully automatic ORM framework, and using Hibernate can operate completely according to the object-relational model, that is, operating Java objects does not need to write SQL, so it is fully automatic; while MyBatis needs to write SQL statements manually when associating objects, so it is called "semi-automatic".
02. Use annotations or XML?
I believe that when most projects use MyBatis, they use XML to configure SQL statements, and the examples in our course use annotations, so what's the difference between the two? How should we choose in the actual development?
First of all, it is officially recommended to use XML, because the use of annotations, stitching dynamic SQL is more laborious, if your SQL is more complex and requires multi-table association, it is better to use XML; and now there are many plug-ins that can automatically generate MyBatis XML.
But there are always two sides to things, complex SQL is not something to be proud of, if your project can do without complex SQL, using annotations would be a better choice (more than 95% of our current projects are single-table queries).
03. What is the difference between # {} and ${}?
${} is a string substitution and # {} is a precompiled process; using # {} can prevent SQL injection and improve system security.
04. How to do bulk insertion?
You can also use dynamic SQL for annotations:
@ Insert ({"" + "INSERT INTO USER (userId, userName, gender, age) values" + "+" (# {item.userId}, # {item.userName}, # {item.gender}, # {item.age}) public void insertUserList (@ Param (value= "userList") List userList) At this point, the study of "summarizing the Mybatis of the ORM framework from single architecture to distributed data persistence" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.