• Mybatis


    Mybatis知识点

    • 需要进行配置,查看前面的配置笔记
    • 分为两种写法,一种是注解,一种是xml文件
    • 事务
    • 缓存

    注解写法

    把JdbcTemplate改成Mybatis

    // 把前面写个接口的service层的代码改成这个
    // service/TestService.java
    
    @Repository  // 同 @Controller
    public class TestService {
        @Autowired
        private TestDao testDao;
    
        // 通过JdbcTemplate的方法才能操作数据库
        public ArrayList get(TestBean testBean) {
            return testDao.get(testBean);
        }
    }
    
    // dao/TestDao.java
    
    public interface TestDao {
        @Select("select * from t_user where id = #{id}")
        ArrayList<TestBean> get(TestBean testBean);
        // 这个ArrayList是返回值的意思,select的返回值有bean,list
        // 其他的几个注解,增,改,删都是返回的数字Integer
    }
    

    注解有哪些

    // 常用的
    @Insert:实现新增 
    @Update:实现更新 
    @Delete:实现删除 
    @Select:实现查询
    
    // 不用的
    @Result:实现结果集封装
    @Results:可以与@Result 一起使用,封装多个结果集 
    @ResultMap:实现引用@Results 定义的封装 
    @One:实现一对一结果集封装 
    @Many:实现一对多结果集封装 
    @SelectProvider: 实现动态 SQL 映射 
    @CacheNamespace:实现注解二级缓存的使用
    

    这种复杂的注解我是没学的,很麻烦,很难记,只会用在简单的增删改查上,还有就是这种写法是拼接sql,一旦某个值没传,sql就是错的,所以一定要把必要的参数验证好

    xml文件

    • 实现可传可不传的参数的查询,比如有些接口他可以不分页也可以分页
    • 复杂的多表查询
    • 同样全程需要bean的配合

    实现一个可以不分页也可以分页的接口
    可以写两个注解的接口,判断有没有传分页的参数决定用哪个接口,但是一旦也改动就得改很多接口,BUG就会被制造出来

    // service/TestService.java
    
    @Repository  // 同 @Controller
    public class TestService {
        @Autowired
        private ItDaoImpl itDaoImpl;
    
        // 通过JdbcTemplate的方法才能操作数据库
        public ArrayList get(TestBean testBean) {
            return itDaoImpl.get(testBean);
        }
    }
    
    // dao/impl/ItDaoImpl.java
    
    @Repository
    public class ItDaoImpl {
    
        @Autowired
        private SqlSessionTemplate sqlSessionTemplate;
    
        public ArrayList get(TestBean testBean) {
            return (ArrayList) sqlSessionTemplate.selectList("mapper.TestDao.get",testBean);
        }
    }
    
    <!-- 需要再新建一个文件夹 ssm/mapper/test.xml -->
    
    <?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">
    
    <!-- 这个namespace + 下面的id 就是dao层的第一个参数 -->
    <!-- 为什么不用TestDao,要用mapper.TestDao,因为要配合日记log4j记录-->
    <mapper namespace="mapper.TestDao">
        <!-- parameterType就是你接受的参数的类型 -->
        <!-- 返回数据有两种写法,一是resultType,另一个是resultMap -->
        <select id="get" 
                parameterType="com.pdt.ssm.bean.TestBean"
                resultType="com.pdt.ssm.bean.TestBean" >
            select * from t_test
            <if test="pageSize != null and pageNo != null">
                limit #{pageNo},#{pageSize}
            </if>
        </select>
    </mapper>
    

    展示resultMap的使用
    用于当多表查询后有多个表的数据相互掺杂使用,比如A表对于一个bean,B表对应一个bean,C表对应一个Bean,突然有需求需要三个表的相关数据,但是正常的做法是在A表的bean里加成员变量,如下

    public class ABean {
        // 本来bean只有这两个字段的
        private String id;
        private String name;
        // 因为需求加两个
        private BBean bBean;
        private ArrayList<ABean> aBeanList;
    }
    
    <mapper namespace="mapper.ADao">
        <select id="test" 
                parameterType="com.pdt.ssm.bean.ABean"
                resultMap="TestMap" >
            // 逻辑就按需求来了,这里只做假设
            select A.id id,A.name name,B.id bId,B.name bName,C.id cId,C.name cName from t_A,t_B,t_C ...
        </select>
    </mapper>
    
    <resultMap id="TestMap" type="com.pdt.ssm.bean.ABean">
       <result column="id" property="id"></result>
       <result column="上面mapper查出来的字段name" property="bean里的key值"></result>
    
       <!-- 内嵌的另一个bean --> 
       <association property="bBean" javaType="com.pdt.ssm.bean.BBean">
         <result column="bId" property="id"></result>
         <result column="bName" property="name"></result>
       </association>
    
       <!-- 内嵌的另一个bean的ArrayList --> 
       <collection property="bean里的key值" ofType="com.pdt.ssm.bean.CBean">
         <result column="cId" property="id"></result>
         <result column="cName " property="name"></result>
       </collection>
    </resultMap>
    

    常用标签

    <mapper namespace="id名字" >
       <select id="id名字" parameterType="com.pdt.ssm.bean.ABean" resultMap和resultType></select>
       <where></where>
       <when></when>
       <choose></choose>
       <if test="pageSize != null and pageNo != null"></if>
       <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach>
    </mapper>
    <resultMap id="id名字" type="com.pdt.ssm.bean.ABean">
       <result column="id" property="id"></result>
       <!-- 内嵌的另一个bean --> 
       <association property="bBean" javaType="com.pdt.ssm.bean.BBean"></association>
       <!-- 内嵌的另一个bean的ArrayList --> 
       <collection property="bean里的key值" ofType="com.pdt.ssm.bean.CBean"></collection>
    </resultMap>
    

    有个注意的点是sql里的大于小于在mapper里不能用符号,因为跟标签的<>是一样的,所以需要改成&gt;&lt;

    事务
    有个例子是A向B转钱,A扣100,B还没加100程序报错,为了避免这个情况应该用事务,原理就是等整个程序运行完没问题再把数据提交,@Transactional

    缓存
    相关链接,没用过

    逆向生成文件

    <dependency>
         <groupId>org.mybatis.generator</groupId>
         <artifactId>mybatis-generator-core</artifactId>
         <version>1.3.5</version>
    </dependency>
    
    <!-- generatorConfig.xml 放在跟pom.xml同一级就行 -->
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
        <context id="testTables" targetRuntime="MyBatis3">
            <commentGenerator>
                <!-- 是否去除自动生成的注释 true:是 : false:否 -->
                <property name="suppressAllComments" value="true"/>
            </commentGenerator>
    
            <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                            connectionURL="jdbc:mysql://localhost:3306/mydb"
                            userId="root"
                            password="123456">
            </jdbcConnection>
    
            <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false"/>
            </javaTypeResolver>
    
            <!-- 生成模型(PO)的包名和位置 -->
            <javaModelGenerator targetPackage="com.shaw.bean"
                                targetProject="src/main/java">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false"/>
                <!-- 从数据库返回的值被清理前后的空格 -->
                <property name="trimStrings" value="true"/>
            </javaModelGenerator>
    
            <!-- 生成映射文件的包名和位置-->
            <sqlMapGenerator targetPackage="mapper"
                             targetProject="src/main/resources">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false"/>
            </sqlMapGenerator>
    
            <!-- 生成DAO的包名和位置-->
            <javaClientGenerator type="XMLMAPPER"
                                 targetPackage="com.shaw.dao"
                                 targetProject="src/main/java">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false"/>
            </javaClientGenerator>
    
            <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
            <table tableName="t_it" domainObjectName="IT"/>
        </context>
    </generatorConfiguration>
    
    public class MyBatisGeneratorApp {
        public void generator() throws Exception{
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
            //指定 逆向工程配置文件
            File configFile = new File("generatorConfig.xml");
            ConfigurationParser cp = new ConfigurationParser(warnings);
            Configuration config = cp.parseConfiguration(configFile);
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback, warnings);
            myBatisGenerator.generate(null);
        }
        public static void main(String[] args) throws Exception {
            try {
                MyBatisGeneratorApp generatorSqlmap = new MyBatisGeneratorApp();
                generatorSqlmap.generator();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    虽然文件是生成出来了,但是我还是决定自己去手写,看不懂,也不好改

  • 相关阅读:
    前端和后端的区别和分工
    IntelliJ和tomcat中的目录结构
    JAVA开发环境和IntelliJ工具安装
    Linux下Python+Selenium自动化模拟用户登录(备注:记录一次强行卸载rpm依赖包,引发的rpm、yum等命令异常,无法远程xftp工具)
    Docker 操作命令梳理(镜像下载、容器创建、Dockerfile)
    Centos 6.6 Docker安装(内网坏境)
    C# 连接Access2010 数据库之初探
    C#使用NLog记录日志
    现实两种
    C#中的两把双刃剑:抽象类和接口
  • 原文地址:https://www.cnblogs.com/pengdt/p/12240622.html
Copyright © 2020-2023  润新知