Mybatis-获取参数值的两种方式

2024-03-28 13:52

本文主要是介绍Mybatis-获取参数值的两种方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. ${ } 和 #{ }

MyBatis获取参数值的两种方式:${ } 和 #{ }


对于初学者来说,理解MyBatis中获取参数值的两种方式——#{}${},关键在于明白它们如何影响SQL语句的构建以及为何在安全性、灵活性上有显著差异。下面我将用简单易懂的语言来解释这两者的本质、工作原理及使用注意事项。

1. ${}:字符串拼接

本质${}在MyBatis中被视为字符串替换符。当你在SQL语句中使用${}时,MyBatis会直接将它包围的变量名替换为实际传入的值。这种方式类似于在编程语言中进行字符串拼接操作,即将传入的值作为文本片段插入到SQL语句中。

工作原理

SELECT * FROM users WHERE username = '${username}'

假设传入的username参数为 'zhangsan',MyBatis会将上述SQL语句中的${username}替换为 'zhangsan',生成如下已拼接好的SQL:

SELECT * FROM users WHERE username = 'zhangsan'

特点与注意事项

  • 手动处理引号:由于${}直接参与字符串拼接,因此对于字符串类型或日期类型的字段值,你需要确保传入的值已经正确地加上了单引号。例如,如果你传入的是 'zhangsan' 而不是 zhangsan,MyBatis不会帮你自动加上单引号。
  • SQL注入风险:由于${}直接将传入的值作为原始文本插入到SQL语句中,没有进行任何预处理或转义,因此它不提供对SQL注入攻击的防护。如果传入的值来自不可信的用户输入,恶意用户可能通过构造特定的输入来篡改SQL语句的结构和意图,从而对数据库造成潜在威胁。因此,除非有明确需求且能够确保输入安全,否则应避免在条件查询等涉及用户输入的地方使用${}
  • 适用场景${}通常用于那些需要原样插入到SQL语句中且不会引起SQL注入风险的情况,如动态表名、列名(虽然不推荐),或者在你已经确保传入值安全的情况下。

2. #{}:预编译占位符

本质#{}在MyBatis中是一个预编译占位符。当SQL语句中包含#{}时,MyBatis会将其替换为一个问号(?),并在执行SQL时使用PreparedStatement来设置参数值。这种方式利用数据库的预编译机制,确保了参数值的安全性和类型正确性。

工作原理

SELECT * FROM users WHERE username = #{username}

同样假设传入的username参数为 'zhangsan',MyBatis会将上述SQL语句中的#{username}替换为 ?,然后使用PreparedStatement向数据库发送如下预编译SQL:

SELECT * FROM users WHERE username = ?

同时,MyBatis会将 'zhangsan' 作为参数值,通过PreparedStatement的set方法安全地绑定到SQL语句中的对应位置。

特点与注意事项

  • 自动处理引号:使用#{}时,MyBatis会根据参数的实际类型自动为其添加合适的引号或进行其他必要的类型转换。对于字符串和日期类型,MyBatis会自动加上单引号。所以你不需要担心引号问题,只需传入值即可。
  • 防SQL注入#{}利用预编译机制,确保参数值与SQL语句主体分离,由数据库在执行时负责正确的参数绑定。这从根本上杜绝了SQL注入攻击的可能性,极大地增强了系统的安全性。
  • 适用场景#{}是推荐的参数传递方式,适用于所有需要动态传入值的场景,特别是涉及到用户输入或敏感信息的条件查询、更新操作等。

举个代码例子:

1. ${}:字符串拼接

想象一下,我们有一个简单的executeQuery()方法,它接受一个用户输入的字符串(比如用户名),然后拼接到SQL查询语句中。

public List<User> executeQuery(String unsafeUsername) {// 直接拼接字符串,模拟${}的行为String sql = "SELECT * FROM users WHERE username = '" + unsafeUsername + "'";// 假设这里有代码执行SQL查询并返回结果...// executeSQL(sql);return null; // 这里仅作演示,实际应返回查询结果
}

现在,假设用户输入了一个恶意的用户名,如:

String maliciousUsername = "' OR '1'='1"; // 模拟SQL注入攻击

调用executeQuery(maliciousUsername)后,生成的SQL语句将是:

SELECT * FROM users WHERE username = '' OR '1'='1'

由于直接拼接字符串,恶意用户成功篡改了SQL语句的结构,导致查询结果不受控制,暴露了SQL注入风险。


2. #{}:预编译占位符

接下来,我们用类似的方式模拟#{}的工作原理,使用PreparedStatement来设置参数值。

public List<User> executePreparedQuery(String safeUsername) {String sql = "SELECT * FROM users WHERE username = ?"; // 使用占位符try (Connection conn = getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, safeUsername); // 安全地设置参数值// 假设这里有代码执行PreparedStatement并返回结果...// ResultSet rs = pstmt.executeQuery();// return processResultSet(rs); // 这里仅作演示,实际应处理结果集并返回结果} catch (SQLException e) {throw new RuntimeException(e);}return null; // 这里仅作演示,实际应返回查询结果
}

同样,假设用户输入了恶意的用户名:

String maliciousUsername = "' OR '1'='1";

调用executePreparedQuery(maliciousUsername)时,尽管恶意用户名被传递给了PreparedStatement,但由于预编译机制,数据库会将它视为一个独立的字符串值,而不是SQL语句的一部分。生成并执行的SQL实际上等同于:

SELECT * FROM users WHERE username = ''' OR ''1''=''1''

可以看到,尽管用户输入了恶意内容,但预编译机制确保了参数值被正确地转义和隔离,有效地防止了SQL注入攻击。


小总结

  • ${}就像在Java代码中直接拼接字符串,将用户输入的值原样插入到SQL语句中,需要手动处理引号,并且存在SQL注入风险。仅在确保输入安全且有特殊需求时考虑使用。
  • #{}则是通过预编译机制(如Java中的PreparedStatement),将参数值与SQL语句主体分离,由数据库在执行时负责正确的参数绑定。这样既自动处理了引号和类型转换,又从根本上杜绝了SQL注入攻击,是所有常规参数传递场景的推荐选择。

2. 单个字面量类型参数

当MyBatis的mapper接口中的方法参数仅为一个字面量类型(如Integer、String、Date等基本类型或其包装类),并且您需要在对应的SQL映射文件中引用这个参数时,可以使用${}#{}来获取该参数的值。


考虑到使用#{}更加安全可靠,所以就用它举个代码例子

UserMapper.java接口

package com.sakurapaid.mybatis3.demo01.mapper;import com.sakurapaid.mybatis3.demo01.bean.User;import java.util.List;public interface UserMapper {// 1.添加用户public int addUser(User user);// 2.修改用户public int updateUser(User user);// 3.查询所有用户public List<User> findAllUser();// 4.根据id删除指定用户public int deleteUserById(int id);// 5. 根据用户名查询用户public User findUserByName(String name);
}

UserMapper.xml映射文件

这里的parameterType不是全类名,是因为我在配置文件中做了取别名操作

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 定义mapper接口的命名空间 -->
<mapper namespace="com.sakurapaid.mybatis3.demo01.mapper.UserMapper"><!--1.添加用户--><insert id="addUser" parameterType="User">insert into user(name,age,sex) values(#{name},#{age},#{sex})</insert><!--2.修改用户--><update id="updateUser" parameterType="User">update user set name=#{name},age=#{age},sex=#{sex} where id=#{id}</update><!--3.查询所有用户--><select id="findAllUser" resultType="User">select * from user</select><!--4.根据id删除指定用户--><delete id="deleteUserById" parameterType="int">delete from user where id=#{id}</delete><!--5.根据用户名查询用户--><select id="findUserByName" resultType="User">select * from user where name=#{name}</select>
</mapper>

测试输出

package com.sakurapaid.mybatis3.demo01.test;import com.sakurapaid.mybatis3.demo01.bean.User;
import com.sakurapaid.mybatis3.demo01.mapper.UserMapper;
import com.sakurapaid.mybatis3.demo01.utils.SqlSessionUtils;
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.jupiter.api.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** 用户测试类*/
public class UserTest {@Testpublic void test() throws IOException {// 从SqlSessionUtils工具类获取SqlSession对象SqlSession sqlSession = SqlSessionUtils.getSqlSession();// 获取UserMapper接口的代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 1.添加用户/*User user1 = new User(0, "小明", 18, "男");int i = userMapper.addUser(user1);if (i > 0) {System.out.println("添加成功");} else {System.out.println("添加失败");}*/// 2.修改用户/*User user2 = new User(1, "萨达姆", 26, "男");int i = userMapper.updateUser(user2);if (i > 0) {System.out.println("修改成功");} else {System.out.println("修改失败");}*/// 3.查询所有用户/*List<User> users = userMapper.findAllUser();if (!users.isEmpty()) {for (User user : users) {System.out.println(user);}} else {System.out.println("没有数据");}*/// 4.根据id删除指定用户/*int i = userMapper.deleteUserById(4);if (i > 0) {System.out.println("删除成功");} else {System.out.println("删除失败");}*/// 5.根据用户名查询用户User user = userMapper.findUserByName("萨达姆");if (user != null) {System.out.println("查询成功");System.out.print(user);} else {System.out.println("没有数据");}}
}


3. 多个字面量类型参数

当MyBatis的mapper接口中的方法参数有多个字面量类型(如Integer、String、Date等基本类型或其包装类),MyBatis会以特定方式组织这些参数,以便在SQL映射文件中引用它们。


参数组织方式

  • 默认键名MyBatis会自动将这些参数放入一个Map集合中。每个参数以其在方法参数列表中的位置作为键名,arg0, arg1, arg2, ...。例如,对于方法getUserInfo(int id, String name),参数id对应的键为arg0,参数name对应的键为arg1
  • 自定义键名:如果在方法参数上使用@Param("paramName")注解,MyBatis会使用注解中指定的名称作为键。例如,@Param("userId") int id@Param("userName") String name,则键分别为userIduserName

引用参数

  • 使用${}#{}:在SQL映射文件中,可以通过${argN}#{argN}(或使用自定义键名的${paramName}#{paramName})来访问Map集合中对应的值。其中,N表示参数在方法参数列表中的位置(从0开始计数),paramName为使用@Param注解指定的名称。
  • 手动添加单引号:对于${},与单个参数情况相同,对于字符串或日期类型的值,需要手动添加单引号。而对于#{},仍然无需手动添加任何引号,MyBatis会自动处理。

示例

假设mapper接口方法为:

public User getUserInfo(@Param("userId") int id, @Param("userName") String name);

对应的SQL映射文件片段:

SELECT * FROM users WHERE id = #{userId} AND username = '${userName}'

再举一个代码例子

现在我要传入两个参数,id和name,来查询对应的用户信息

UserMapper.java

package com.sakurapaid.mybatis3.demo01.mapper;import com.sakurapaid.mybatis3.demo01.bean.User;import java.util.List;public interface UserMapper {// 1.添加用户public int addUser(User user);// 2.修改用户public int updateUser(User user);// 3.查询所有用户public List<User> findAllUser();// 4.根据id删除指定用户public int deleteUserById(int id);// 5.根据用户名查询用户public User findUserByName(String name);// 6.输入id和姓名,查询用户public User findUserByIdAndName(int id, String name);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 定义mapper接口的命名空间 -->
<mapper namespace="com.sakurapaid.mybatis3.demo01.mapper.UserMapper"><!--1.添加用户--><insert id="addUser" parameterType="User">insert into user(name,age,sex) values(#{name},#{age},#{sex})</insert><!--2.修改用户--><update id="updateUser" parameterType="User">update user set name=#{name},age=#{age},sex=#{sex} where id=#{id}</update><!--3.查询所有用户--><select id="findAllUser" resultType="User">select * from user</select><!--4.根据id删除指定用户--><delete id="deleteUserById" parameterType="int">delete from user where id=#{id}</delete><!--5.根据用户名查询用户--><select id="findUserByName" resultType="User">select * from user where name=#{name}</select><!--6.输入id和姓名,查询用户--><select id="findUserByIdAndName" resultType="User"><!--select * from user where id=#{param1} and name=#{param2}-->select * from user where id=#{arg0} and name=#{arg1}</select>
</mapper>

如果此时sql语句还像单个字面量直接写标识符,编译就会报错

<!--6.输入id和姓名,查询用户-->
<select id="findUserByIdAndName" resultType="User"><!--select * from user where id=#{param1} and name=#{param2}--><!--select * from user where id=#{arg0} and name=#{arg1}-->select * from user where id=#{id} and name=#{name}
</select>
// 6.输入id和姓名,查询用户
User user = userMapper.findUserByIdAndName(1, "萨达姆");
if (user != null) {System.out.println("查询成功");System.out.print(user);
} else {System.out.println("没有数据");

报错的关键简单总结就是,在执行MyBatis的数据库查询时,查询语句中引用了一个名为id的参数,但在对应的Mapper接口方法调用时并没有提供这个参数。MyBatis在处理SQL映射时未能找到与#{id}占位符相对应的参数值,因此抛出了org.apache.ibatis.binding.BindingException: Parameter 'id' not found的错误。这意味着在编写Mapper接口方法时,应当确保方法签名中包含所有在映射文件中使用的参数,同时在实际调用该方法时,也需要正确传递这些参数。

如何解决,此时就可以使用,也就是我注释上写的代码

默认键名:MyBatis会自动将这些参数放入一个Map集合中。每个参数以其在方法参数列表中的位置作为键名,即arg0, arg1, arg2, ...。或者param1, param2, param3, ...。

<!--6.输入id和姓名,查询用户-->
<select id="findUserByIdAndName" resultType="User"><!--select * from user where id=#{param1} and name=#{param2}--><!--select * from user where id=#{arg0} and name=#{arg1}-->
</select>

还有有种方法是--自定义键名:如果在方法参数上使用@Param("paramName")注解,MyBatis会使用注解中指定的名称作为键。例如,@Param("userId") int id@Param("userName") String name,则键分别为userIduserName

这个到文章的后面再讲


4. map集合类型的参数

若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${ }需要手动加单引号


又举个代码例子

map集合方式输入id和姓名,查询用户

在 MyBatis 中,当一个 Mapper 接口方法需要接收多个参数时,可以使用 Map 集合作为参数类型,将各个参数以键值对的形式封装在 Map 中。这样,只需一个参数即可传递多个值,使得接口签名更为简洁。以下是具体的步骤和示例:

1. 定义 Mapper 接口方法

首先,在 UserMapper.java 中定义一个使用 Map 类型参数的方法,如:

public User findUserByIdAndName2(Map<String, Object> map);

此方法表示我们要根据 idname 两个属性查询用户信息。

2. 编写 XML 映射文件

接着,在 UserMapper.xml 中编写对应的 SQL 查询语句,使用 #{} 占位符来引用 Map 中的键值:

<!-- 7.map集合方式输入id和姓名,查询用户 -->
<select id="findUserByIdAndName2" resultType="User">select * from user where id = #{id} and name = #{name}
</select>

这里,#{id}#{name} 分别代表 Map 参数中键为 "id""name" 的值。MyBatis 会在执行时自动从传入的 Map 中取出对应的值,并将其作为预编译参数插入 SQL 查询中,保证安全性。

3. 准备参数与调用查询

最后,在应用程序中创建一个 HashMap 实例,填充所需的 idname 值,然后调用 Mapper 方法执行查询:

// 7.map集合方式输入id和姓名,查询用户
Map<String, Object> map = new HashMap<>();
map.put("id", 1);
map.put("name", "萨达姆");User userByIdAndName2 = userMapper.findUserByIdAndName2(map);if (userByIdAndName2 != null) {System.out.println("查询成功");System.out.println(userByIdAndName2); // 修改为 println 输出整行
} else {System.out.println("没有数据");
}

这段代码首先创建了一个 HashMap 并放入 "id""name" 的键值对。然后,调用 userMapper.findUserByIdAndName2(map) 执行查询。根据查询结果,判断是否找到了匹配的用户,并打印相应的信息。


总结

通过上述步骤,我们展示了如何使用 Map 类型参数在 MyBatis 中实现多参数查询。关键要点如下:

  • 使用 Map 集合封装多个查询参数,简化接口定义。
  • 在 Mapper 接口中声明接受 Map 参数的方法。
  • 在 XML 映射文件中,使用 #{mapKey} 格式引用 Map 中的键值,确保 SQL 安全性。
  • 在应用中创建 Map 实例,填充参数,调用 Mapper 方法执行查询,并处理查询结果。

这种做法尤其适用于参数数量不确定或变动频繁的场景,有助于保持代码的灵活性和可维护性。初学者在实际编程中可以借鉴此模式,根据需求适配自己的查询逻辑。


5. 实体类类型的参数

若mapper接口中的方法参数为实体类对象时 此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号


在 MyBatis 中,当一个 Mapper 接口方法的参数为实体类对象时,可以直接使用实体类属性作为 SQL 语句中的占位符值。这种方式简化了参数传递,无需手动构建 Map 或其他数据结构。

以User实体类作为参数,添加用户

1. 定义 Mapper 接口方法

首先,在 UserMapper.java 中定义一个使用 User 实体类作为参数的方法,如:

public int addUser2(User user);

此方法表示我们要根据 User 实例的属性值来添加一个新的用户记录到数据库。

2. 编写 XML 映射文件

接着,在 UserMapper.xml 中编写对应的 SQL 插入语句,使用 #{属性名} 占位符来引用实体类对象的属性:

<!-- 8.以User实体类作为参数,添加用户 -->
<insert id="addUser2">insert into user values(0, #{name}, #{age}, #{sex})
</insert>

这里,#{name}, #{age}, 和 #{sex} 分别代表 User 对象的 name, age, 和 sex 属性值。MyBatis 会在执行时自动从传入的 User 实例中取出对应的属性值,并将其作为预编译参数插入 SQL 插入语句中,保证安全性。

3. 准备参数与调用添加方法

最后,在应用程序中创建一个 User 实例,填充所需的属性值,然后调用 Mapper 方法执行添加操作:

// 8.以User实体类作为参数,添加用户
User user = new User(0, "小明", 18, "男");int i = userMapper.addUser2(user);if (i > 0) {System.out.println("添加成功");
} else {System.out.println("添加失败");
}

这段代码首先创建了一个 User 对象,并设置了 name, age, 和 sex 属性。然后,调用 userMapper.addUser2(user) 执行添加操作。根据返回的受影响行数判断添加是否成功,并打印相应的信息。


总结

通过上述步骤,我们展示了如何使用实体类类型参数在 MyBatis 中实现用户添加操作。关键要点如下:

  • 直接使用实体类对象作为 Mapper 方法的参数,简化参数传递。
  • 在 Mapper 接口中声明接受实体类对象的方法。
  • 在 XML 映射文件中,使用 #{属性名} 格式引用实体类对象的属性,确保 SQL 安全性。
  • 在应用中创建实体类实例,填充属性值,调用 Mapper 方法执行添加操作,并根据返回结果判断操作是否成功。

这种做法适用于参数与实体类属性紧密关联的场景,能够简化代码结构,提高代码的可读性和一致性。初学者在设计数据操作接口时,可以优先考虑使用实体类作为参数,以充分利用 MyBatis 对实体类属性的自动映射功能。


6. 使用@Param标识参数

可以通过@Param注解标识mapper接口中的方法参数 此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;以 param1,param2...为键,以参数为值;只需要通过${}和#{}访问map集合的键就可以获取相对应的值, 注意${}需要手动加单引号


在 MyBatis 中,@Param 注解可以用于为 Mapper 接口方法的参数提供别名,特别是在方法包含多个参数时,有助于清晰地标识每个参数的作用,并在 XML 映射文件中通过别名引用它们。以下是如何使用 @Param 注解查询用户的步骤和示例:

使用@Param输入id和姓名,查询用户

1. 定义 Mapper 接口方法

首先,在 UserMapper.java 中定义一个带有 @Param 注解的方法,为 idname 参数赋予别名:

// 9.使用@Param输入id和姓名,查询用户
public User findUserByIdAndName3(@Param("id") int id, @Param("name") String name);

这里,@Param("id")@Param("name") 分别为 int idString name 参数指定了别名 "id""name"。这些别名将在 XML 映射文件中作为占位符的键来使用。

2. 编写 XML 映射文件

接着,在 UserMapper.xml 中编写对应的 SQL 查询语句,使用 #{别名} 占位符来引用带有 @Param 注解的参数:

<!--9.使用@Param输入id和姓名,查询用户-->
<select id="findUserByIdAndName3" resultType="User">select * from user where id = #{id} and name = #{name}
</select>

这里,#{id}#{name} 分别代表方法参数中被 @Param 注解标记为 "id""name" 的值。MyBatis 会在执行时自动从方法参数中取出对应的值,并将其作为预编译参数插入 SQL 查询中,保证安全性。

不写id和name的话,也可以以 param1,param2...为键,以参数为值;

3. 调用查询方法

最后,在应用程序中直接调用 Mapper 方法,传入 idname 参数值:

// 9.使用@Param输入id和姓名,查询用户
User userByIdAndName3 = userMapper.findUserByIdAndName3(1, "萨达姆");if (userByIdAndName3 != null) {System.out.println("查询成功");System.out.println(userByIdAndName3); // 修改为 println 输出整行
} else {System.out.println("没有数据");
}

这段代码直接调用 userMapper.findUserByIdAndName3(1, "萨达姆"),传入 idname 的具体值。根据查询结果,判断是否找到了匹配的用户,并打印相应的信息。


总结

通过上述步骤,我们展示了如何使用 @Param 注解在 MyBatis 中实现多参数查询。关键要点如下:

  • 使用 @Param 注解为 Mapper 接口方法的参数指定别名,增加代码可读性。
  • 在 Mapper 接口中声明带有 @Param 注解的方法。
  • 在 XML 映射文件中,使用 #{别名} 格式引用 @Param 注解标记的参数,确保 SQL 安全性。
  • 在应用中直接调用 Mapper 方法,传入相应参数值,并处理查询结果。

这种做法特别适用于方法参数较多且需要清晰标识其用途的场景,增强了代码的可理解性和维护性。初学者在编写多参数的 MyBatis 查询方法时,应优先考虑使用 @Param 注解来提升代码质量。注意,这里并不涉及将参数放入 Map 集合中,而是直接使用注解提供的别名与方法参数关联。

这篇关于Mybatis-获取参数值的两种方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855789

相关文章

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息,然后展示在页面上。 效果展示 首次发送需要设置昵称 发送消息与消息展示 提示用户不能发送空消息 后端接口 发送消息 DB = []@ro

脏页的标记方式详解

脏页的标记方式 一、引言 在数据库系统中,脏页是指那些被修改过但还未写入磁盘的数据页。为了有效地管理这些脏页并确保数据的一致性,数据库需要对脏页进行标记。了解脏页的标记方式对于理解数据库的内部工作机制和优化性能至关重要。 二、脏页产生的过程 当数据库中的数据被修改时,这些修改首先会在内存中的缓冲池(Buffer Pool)中进行。例如,执行一条 UPDATE 语句修改了某一行数据,对应的缓

Spring+MyBatis+jeasyui 功能树列表

java代码@EnablePaging@RequestMapping(value = "/queryFunctionList.html")@ResponseBodypublic Map<String, Object> queryFunctionList() {String parentId = "";List<FunctionDisplay> tables = query(parent

Mybatis中的like查询

<if test="templateName != null and templateName != ''">AND template_name LIKE CONCAT('%',#{templateName,jdbcType=VARCHAR},'%')</if>

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

JavaWeb【day09】--(Mybatis)

1. Mybatis基础操作 学习完mybatis入门后,我们继续学习mybatis基础操作。 1.1 需求 需求说明: 根据资料中提供的《tlias智能学习辅助系统》页面原型及需求,完成员工管理的需求开发。 通过分析以上的页面原型和需求,我们确定了功能列表: 查询 根据主键ID查询 条件查询 新增 更新 删除 根据主键ID删除 根据主键ID批量删除