MIKU MOE

SSM_MyBatis_CRUD_配置优化

3. CRUD

dao.DaoMapper

 public interface UserDao {
     //获取全部用户
     List<User> getUserList();
     //根据ID查询用户
     User getUserById(int id);
     //插入
     int addUser(User user);
     //修改
     int updateUser(User user);
     //删除
     int deleteUser(int id);
 }

 

dao.UserMapper

 <?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.study.dao.UserDao">
     <select id="getUserList" resultType="com.study.pojo.User">
         select * from mybatis.user
     </select><select id="getUserById" parameterType="int" resultType="com.study.pojo.User">
         select * from mybatis.user where id = #{id}
     </select><insert id="addUser" parameterType="com.study.pojo.User">
         insert into mybatis.user(id,name,pwd) values (#{id},#{name},#{pwd});
     </insert><update id="updateUser" parameterType="com.study.pojo.User">
         update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id};
     </update><delete id="deleteUser" parameterType="int">
         delete from mybatis.user where id = #{id}
     </delete>
 </mapper>

 

Test

 public class UserDaoTest extends TestCase {
     @Test
     public void test(){
         //1. 获得SqlSession对象
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //2. 方式一: 执行SQL
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         List<User> userList = mapper.getUserList();
         for (User user : userList) {
             System.out.println(user);
         }
         //2. 方式二:(旧方法,不推荐)
         /*
         List<Object> objects = sqlSession.selectList("com.study.dao.UserDao.getUserList");
         for (Object user : objects) {
             System.out.println(user);
         }
         */
         //3. 关闭SqlSession
         sqlSession.close();
     }
 ​
     @Test
     public void testGetUserById(){
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //====================================
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         User user = mapper.getUserById(1);
         System.out.println(user);
         //====================================
         sqlSession.close();
     }
 ​
     /*增删改需要提交事务*/
     @Test
     public void testaddUser(){
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //====================================
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         int i = mapper.addUser(new User(8, "小四", "123456"));
         if (i>0) {
             System.out.println("插入成功!");
         }
         //提交事务
         sqlSession.commit();
         //====================================
         sqlSession.close();
     }
 ​
     @Test
     public void testupdateUser(){
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //====================================
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         int i = mapper.updateUser(new User(2, "呵呵", "123456"));
         if (i>0) {
             System.out.println("修改成功!");
         }
         //提交事务
         sqlSession.commit();
         //====================================
         sqlSession.close();
     }
 ​
     @Test
     public void testdeleteUser(){
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //====================================
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         int i = mapper.deleteUser(11);
         if (i>0) {
             System.out.println("删除成功!");
         }
         sqlSession.commit();
         //====================================
         sqlSession.close();
     }
 }

 

使用Map

 // -- 使用Map插入
 int addUser2(Map<String,Object> map);

 <insert id="addUser2" parameterType="map">
     insert into mybatis.user(id,name,pwd) values (#{userid},#{username},#{userpwd});
 </insert>

 @Test
     public void testaddUser2(){
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //====================================
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         Map<String, Object> map = new HashMap<>();
         map.put("userid", 12);
         map.put("username", "张三");
         map.put("userpwd", "123456");
         mapper.addUser2(map);
         //提交事务
         sqlSession.commit();
         //====================================
         sqlSession.close();
     }

 

优点: 当修改参数时可以指定的修改部分参数,(或许是因为pojo构造函数只写了无参和全参?)

模糊查询

 // -- 模糊查询
 List<User> getUserLike(String name);

 

  • 在SQl拼接中使用通配符 : 此种方法可能导致sql注入

 <select id="getUserById2" resultType="com.study.pojo.User">
         select * from mybatis.user where name like "%"#{id}"%"
     </select>

 

  • 在Java代码执行时,传递通配符% %
 <select id="getUserLike" resultType="com.study.pojo.User">
         select * from mybatis.user where name like #{value}
     </select>

 @Test
     public void testgetUserLike(){
         SqlSession sqlSession = MybatisUtil.getSqlSession();
         //====================================
         UserDao mapper = sqlSession.getMapper(UserDao.class);
         List<User> users = mapper.getUserLike("%小%");
         for (User user : users) {
             System.out.println(user);
         }
         //====================================
         sqlSession.close();
     }

 

 


 

4. 配置及优化

configuration(配置)

4.1环境配置environments

MyBatis 可以配置成适应多种环境

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

 <environments default="development">
  <!--通过default选择配置环境的id-->
<environment id="development"> <!--事务管理器:JDBC MANAGED--> <transactionManager type="JDBC"> <property name="..." value="..."/> </transactionManager> <!--数据源:UNPOOLED 连接池POOLED JNDI--> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>

 

注意一些关键点:

  • 默认使用的环境 ID(比如:default="development")。

  • 每个 environment 元素定义的环境 ID(比如:id="development")。

  • 事务管理器的配置(比如:type="JDBC")。

  • 数据源的配置(比如:type="POOLED")。

4.2属性properties

我们可以通过properties属性来实现引用配置文件

这些属性都是可外部配置且可动态替换的,既可以在典型的Java属性文件中配置,亦可通过properties 元素的子元素来传递。

[db.properties]

 driver=com.mysql.jdbc.Driver
 url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
 username=root
 password=root

在核心配置引入

注意:在配置文件中大标签有先后顺序:properties-->setting-->typeAloases ......

 <configuration>
     <!--引入外部配置文件(中文注释可能会导致报错)-->
     <!--可以直接引入外部文件-->
     <properties resource="db.properties">
         <!--可以增加一些属性字段,注意:重复的话优先使用外部配置文件-->
         <property name="username" value="root"/>
     </properties><environments default="development">
         <environment id="development">
             <transactionManager type="JDBC"/>
             <dataSource type="POOLED">
                 
                 <property name="driver" value="${driver}"/>
                 <property name="url" value="${url}"/>
                 <property name="username" value="${username}"/>
                 <property name="password" value="${password}"/>
             </dataSource>
         </environment>
     </environments>
     <mappers>
         <mapper resource="com/study/dao/UserMapper.xml"/>
     </mappers>
 </configuration>

 

4.3类型别名typeAliases

1.为Java类型设置一个短的名字,存在的意义为减少类完全限定名的冗余

 <!--起别名,简化代码-->
 <typeAliases>
         <typeAlias type="com.study.pojo.User" alias="User"/>
     </typeAliases>

 

也可以指定一个包名,MyBatis会在包名下面搜索需要的Java Bean

2.扫描实体类的包,默认别名就是这个类的类名,首字母小写 . 为整个包下的包取别名

 <package name="com.study.pojo"/>

 

3.使用注解取别名

 @Alias("user")
 public class User { ... }

 

  • 实体类较少的时候用第一种 , 且可以DIY别名

  • 实体类较多使用第二种 , 不能DIY , 如果非要改别名 ,使用第三种注解方式,优先使用注解别名

4.4设置

  • cacheEnabled 全局的开启或关闭配置文件中的所有映射器已经配置的任何缓存

  • lazyLoadingEnabled 延迟加载的全局开关

  • logImpl 指定MyBatis所用日志的具体实现,未指定时自动查找

4.5其它配置

4.6映射器mapper

MapperRegistry : 绑定注册Mapper文件

方式一

 <mappers>
     <mapper resource="com.study.dao.UserDao.xml"/>
 </mappers>

 

方式二:使用class绑定

  • 注意:接口和Mapper配置文件必须同名

  • 接口和Mapper配置文件必须在同一个包下

 <mappers>
     <mapper class="com.sutdy.dao.UserDao"/>
 </mappers>

 

方式三 : 使用扫描包注入绑定 , 注意点与方式二相同

 <mappers>
     <package name="com.study.dao">
 </mappers>

 

4.7生命周期和作用域

1

生命周期,和作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题

SqlSessionFactoryBuilder:

  • 一旦创建了SqlSessionFactory,就不再需要它了

  • 局部变量

SqlSessionFactory:

  • 理解为数据库连接池

  • SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。

  • 因此 SqlSessionFactory的最佳作用域是应用作用域。

  • 最简单的就是使用单例模式或者静态单例模式

SqlSession:

  • 连接到连接池的一个请求

  • SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。

  • 用完之后需要赶紧关闭,否则资源被占用!


 

5. 解决字段名问题

实体类字段与数据库中的字段不一致

如以上数据库: id name pwd --> 实体类定义变量 id name password

 select * from mybatis.user where id = #{id}
 //类处理器自动处理为
 select id,name,pwd from mybatis.user where id = #{id}
 //pwd查询为空

 

解决方法:

  • 起别名

     <select id="getUserById" resultType="com.study.pojo.User">
         select id,name,pwd as password from mybatis.user where id = #{id}
     </select>

     

  • resultMap

resultMap结果集映射

 <!--结果集映射-->
 <resultMap id="UserMap" type="User">
     <!--column数据库中的宁段,property实体类中的属性-->
     <result column="id" property="id"/>
     <result column="name" property="name"/>
     <result column="pwd" property="password"/>
 </resultMap><select id="getUserById" resultMap="UserMap">
     select * from mybatis.user where id = #{id}
 </select>

 

  • resultMap元素是MyBatis中最重要最强大的元素

  • ResultMap的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

  • ResultMap最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。



posted @ 2021-09-03 21:31  miku_moe  阅读(55)  评论(0)    收藏  举报