1. 使用构建者模式
| public class UsersDaoImpl implements UsersDao { |
| @Override |
| public List<Users> selectUsersAll() throws IOException { |
| InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml"); |
| |
| |
| |
| SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); |
| |
| |
| |
| SqlSession sqlSession = sqlSessionFactory.openSession(); |
| |
| |
| |
| List<Users> list = sqlSession.selectList("com.bjsxt.mapper.UsersMapper.selectUsersAll"); |
| |
| sqlSession.close(); |
| return list; |
| } |
| } |
2. 标签中的属性
| |
| |
| |
| |
| |
| <select id="selectUsersById" parameterType="int" resultType="com.bjsxt.pojo.Users"> |
| select * from users where userid=#{suibian} |
| </select> |
3. 关于sql注入问题
{} 和 ${}的区别:
{}解析为一个JDBC预编译语句PreparedStatement的参数标记符占位符?。使用该方式可避免SQL注入。
仅仅为一个纯粹的String替换,在Mybatis的动态SQL解析阶段将会进行变量替换。{}在预编译之前已经被变量替换了,存在SQL注入问题。
| 预编译补充: |
| 关于sql语句:select * from user where id=? |
| 情况1. 预编译(先编译后执行)PrepareStatement: |
| 当我们把语句传给mysql服务器的时候,服务器就已经帮我们编译了,编译成了一个SQL模板(可以类比函数),同时占位符?成了参数, |
| 当我们插入数据时,实际上只是往SQL模板里传入参数,这个过程编译与执行是分开的,模板被放入了模板池,当需要时取出插入数据即可, |
| 不需要继续编译。 |
| 情况2. 编译并执行 Statement: |
| 给sql服务器传递了完整的sql语句,sql服务器需要给整个语句进行编译,这时候如果进行了sql注入,sql服务器编织出得结果就会与预期有误差。 |
4. ThreadLocal
| ThreadLocal提供了线程内存存储变量的能力,这些变量不同之处在于每一个线程读取的变量是对应的互相独立的。 |
| 通过get和set方法就可以得到当前线程对应的值。 |
| |
| 使用ThreadLocal来存储,保证一个线程中的操作使用的都是一个SqlSession. |
5. mybatis事务提交
| |
| SqlSession sqlSession = sqlSessionFactory.openSession(); |
| sqlSession.commit(); |
| |
| |
| SqlSession sqlSession = sqlSessionFactory.openSession(true); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?