Mybatis realizes CRUD operation based on dynamic proxy
- Requirements:
- The mapping configuration of the persistence layer interface (UserDao) and the persistence layer interface must be in the same package
- The value of the namespace attribute of the mapper tag in the persistence layer mapping configuration must be the fully qualified class name of the persistence layer interface
<select>,<insert>,<delete>,<update>
The id attribute of the configuration tag of the SQL statement must be the same as the method name of the persistence layer interface.
Query by ID
- Add findById method in the persistence layer interface
/** * 根据 id 查询 * @param userId
* @return
*/
User findById(Integer userId);
- Configured in the user's mapping profile
<!-- 根据 id 查询 -->
<select id="findById" resultType="cn.myp666.domain.User" parameterType="int">
select * from user where id = #{uid}
</select>
detail:
-
resultType attribute: Used to specify the type of result set.
-
parameterType attribute: used to specify the type of the incoming parameter.
-
The # {} character is used in the sql statement:
- It represents a placeholder, equivalent to jdbc ? , are used to replace the actual data when the statement is executed.
- The specific data is determined by the content in # {}.
-
How to write content in # {}:
- Since the data type is a basic type, you can write it here at will.
- Add test in test class
/**
*
* <p>Title: MybastisCRUDTest</p>
* <p>Description: 测试 mybatis 的 crud 操作</p>
*
*/
public class MybastisCRUDTest {
private InputStream in ;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Test
public void testFindOne() {
//6.执行操作
User user = userDao.findById(41);
System.out.println(user);
}
@Before//在测试方法执行之前执行
public void init()throws Exception {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.创建 SqlSession 工厂对象
factory = builder.build(in);
//4.创建 SqlSession 对象
session = factory.openSession();
//5.创建 Dao 的代理对象
userDao = session.getMapper(IUserDao.class);
}
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
session.commit();
//7.释放资源
session.close();
in.close();
}
}
Save operation
- Add new methods in the persistence layer interface
/**
* 保存用户
* @param user
* @return 影响数据库记录的行数
*/
int saveUser(User user);
- Configured in the user's mapping profile
<!-- 保存用户-->
<insert id="saveUser" parameterType="cn.myp666.domain.User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
detail:
-
parameterType attribute:
represents the type of the parameter, because we are passing in an object of a class, so the type is written with the full name of the class. -
The # {} character is used in the sql statement:
it represents a placeholder, equivalent to jdbc ?, and is used to replace the actual data when executing the statement.
The specific data is determined by the content in # {}. -
How to write content in # {}:
Since the parameter of our saving method is a User object, we need to write the attribute name in the User object.
It uses ognl expressions. -
ognl expression:
- It is an expression language provided by Apache, the full name is:
Object Graphic Navigation Language Object Graphic Navigation Language
It obtains data according to a certain grammatical format. - The syntax format is to use # {
object.object} # {user.username} It will first find the user object, then find the username attribute in the user object, and call the
getUsername () method to retrieve the value. But we specified the entity class name on the parameterType attribute, so we can omit user.
And write username directly.
- It is an expression language provided by Apache, the full name is:
- Add test method in test class
@Test
public void testSave(){
User user = new User();
user.setUsername("modify User property");
user.setAddress("北京市顺义区");
user.setSex("男");
user.setBirthday(new Date());
System.out.println("保存操作之前:"+user);
//5.执行保存方法
userDao.saveUser(user);
System.out.println("保存操作之后:"+user);
}
Open Mysql database and found that no records have been added, what is the reason?
This is the same as jdbc. We must control the submission of transactions when implementing additions, deletions, and changes, so how to control the
submission of transactions in mybatis ?
You can use: session.commit();
to achieve transaction commit. The code after joining the transaction is as follows:
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
session.commit();
//7.释放资源
session.close();
in.close();
}
Problem extension: add the return value of user id
- After adding a user, the id value of the newly added user is also returned. Because the id is realized by the automatic growth of the database, it is
equivalent to returning the value of auto_increment after the new increase.
<insert id="saveUser" parameterType="USER">
<!-- 配置保存时获取插入的 id -->
<selectKey keyColumn="id" keyProperty="id" resultType="int">
select last_insert_id();
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
User update
- Add update method in the persistence layer interface
/**
* 更新用户
* @param user
* @return 影响数据库记录的行数
*/
int updateUser(User user);
- Configured in the user's mapping profile
<!-- 更新用户 -->
<update id="updateUser" parameterType="cn.myp666.domain.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},
address=#{address} where id=#{id}
</update>
- Add updated test method
@Test
public void testUpdateUser()throws Exception{
//1.根据 id 查询
User user = userDao.findById(52);
//2.更新操作
user.setAddress("北京市顺义区");
int res = userDao.updateUser(user);
System.out.println(res);
}
User delete
- Add and delete methods in the persistence layer interface
/**
* 根据 id 删除用户
* @param userId
* @return
*/
int deleteUser(Integer userId);
- Configured in the user's mapping profile
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid}
</delete>
- Add delete test method
@Test
public void testDeleteUser() throws Exception {
//6.执行操作
int res = userDao.deleteUser(52);
System.out.println(res);
}
User fuzzy query
- Add fuzzy query method in persistence layer interface
/**
* 根据名称模糊查询
* @param username
* @return
*/
List<User> findByName(String username);
- Configured in the user's mapping profile
<!-- 根据名称模糊查询 -->
<select id="findByName" resultType="cn.myp666.domain.User" parameterType="String">
select * from user where username like #{username}
</select>
- Test method with fuzzy query
@Test
public void testFindByName(){
//5.执行查询一个方法
List<User> users = userDao.findByName("%王%");
for(User user : users){
System.out.println(user);
}
}
The executed SQL statement output in the console is as follows:
- We did not add% to the configuration file as a condition for fuzzy query, so when passing in the string argument, we need to give the fuzzy query identifier%. # {Username} in the configuration file is also just a placeholder, so the SQL statement displays as "?".
Another configuration method of fuzzy query
- The first step: modify the configuration of the SQL statement, the configuration is as follows:
<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="cn.myp666.domain.User">
select * from user where username like '%${value}%'
</select>
- We changed the original # {} placeholder to $ {value} above. Note that such an approach if the fuzzy query, then the
${value}
writing
method is fixed and can not be written other names.
- Step 2: Test, as follows:
@Test
public void testFindByName(){
//5.执行查询一个方法
List<User> users = userDao.findByName("王");
for(User user : users){
System.out.println(user);
}
}
- The executed SQL statement output in the console is as follows:
- It can be found that we do not need to add the matching character% of the fuzzy query in the program code. The effect of the two methods is the same, but the executed statement is different. Recommend the first way
The difference between # {} and $ {}:
- # {} Represents a placeholder
- The # {} can be used to set the preparedStatement to a placeholder and automatically convert the java type and jdbc type.
# {} Can effectively prevent SQL injection. - # {} Can receive simple type values or pojo attribute values. If parameterType transmits a single simple type value, # {} can be in parentheses
value 或其它名称。
- The # {} can be used to set the preparedStatement to a placeholder and automatically convert the java type and jdbc type.
- $ {} Indicates splicing sql string
- Through $ {}, the content passed in parameterType can be spliced in sql without jdbc type conversion,
- $ {} Can receive simple type values or pojo attribute values, if parameterType transmits a single simple type value, in $ {} brackets
只能是 value。
Query using aggregate functions
- Add fuzzy query method in persistence layer interface
/**
* 查询总记录条数
* @return
*/
int findTotal();
- Configured in the user's mapping profile
<!-- 查询总记录条数 -->
<select id="findTotal" resultType="int">
select count(*) from user;
</select>
- Test method for adding aggregate query
@Test
public void testFindTotal() throws Exception {
//6.执行操作
int res = userDao.findTotal();
System.out.println(res);
}