3.2 Log4j===(log For java)
Log4j专门为我们的javat程序记录日志使用的;小工具无外乎都是jar包+配置文件;
日志-->日记-->流水账;
- 没有使用log4j的时候,如何打印信息呢?
System.out.println(“====”); |
这种方式记录日志只有信息,想加上时间,这句话是在哪个类里面,哪个方法里面;
console.info(“====”); js中打印到控制台
想为信息加上级别(如天气预报一样:橙,黄,蓝,红预警)
上述期望,Log4j已经帮忙实现了。
从镜像上下载
http://mirrors.ustc.edu.cn/apache/logging/log4j/2.10.0/
目录介绍
就是一堆jar包
1、添加jar包;将log4j-api-2.10.0.jar和log4j-core-2.10.0.jar拷贝到项目的lib中,并且增加到classpath中
- 配置文件_基本的:
配置文件的名字必须是:log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration status="OFF"> <!-- 信息定义处 --> <appenders> <!-- 将信息打印到控制台 name:有多种输出的位置 --> <Console name="Console" target="SYSTEM_OUT"> <!-- 信息打印的格式 --> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </Console> </appenders> <loggers> <!-- 信息使用处 level:可以定义打印信息的级别 大于等于此级别的信息都会打印出来; --> <root level="info"> <!-- 引入appenders中的子标签name --> <appender-ref ref="Console" /> </root> </loggers> </configuration> |
- 配置文件_最全的:
包含了日志(日记的分类)和按天记(一天一个)
<?xml version="1.0" encoding="UTF-8"?> <!-- status=debug 可以查看log4j的装配过程 --> <configuration status="off" monitorInterval="1800"> <appenders> <!-- 定义控制台输出 --> <Console name="Console" target="SYSTEM_OUT" follow="true"> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" /> </Console> <!-- 系统打印日志 ,按照天记录日志;filePattern文件的格式--> <RollingRandomAccessFile name="System" fileName="logs/system.log" filePattern="logs/system_%d{yyyy-MM-dd}_%i.log"> <!-- 日志文件中内容的格式 --> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" /> <Policies> <!-- 一天记录的日志如果大于100m,重新再创建一个新的日志 --> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <SizeBasedTriggeringPolicy size="100M" /> </Policies> </RollingRandomAccessFile> </appenders> <loggers> <!-- Root Logger --> <root level="info"> <!-- 引入了一个Console和System --> <appender-ref ref="Console" /> <appender-ref ref="System" /> </root> <!-- 外部日志,只记录到文件中,不记录到控制台中 --> <logger name="SystemLog" level="info" additivity="false"> <appender-ref ref="System" /> </logger> </loggers> </configuration> |
代码:
package com.carlinfo.mybatis.test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * log4j的测试类 * @author as */ public class Log4jTest { public static void main(String[] args) { /* 注意别导错包了 * LogManager.getLogger()和 * LogManager.getLogger(log4jTest.class); * 效果一样 * */ Logger logger = LogManager.getLogger(Log4jTest.class); /* 打印信息 * 是按照信息的分类来划分的(级别;从最低的到最高的) * */ logger.trace("==trace=="); logger.debug("==debug=="); logger.info("==info=="); logger.warn("==warn=="); logger.error("==error==");
/** * 参数是:配置文件中(log4j2.xml)中的loggers-->logger的name属性 */ Logger loggerName = LogManager.getLogger("SystemLog"); loggerName.info("==我是新记录的日志==");
/* * Log4j2新增加的功能 * System.out.prinln(); * */ String name = "张三" ; /* 拼接字符串 */ logger.info("计数:" + 2 + ";名字:" + name + ";age:" + 30); /* Log4j2新增加的功能和占位符很像 * 参数1:字符串+占位符,占位符要用{} * 参数>2:为占位符赋值 * 如果参数的个数>占位符的个数,不赋值就可以 * */ logger.info("计数:{},名字:{},age:{}" , 2 , name , 30 , 100 , 200 ); /* 异常 * 把异常信息也写到日志文件中 * */ try { String str = null ; str.toString() ; } catch (Exception e) { /* 写到日志文件中,得用Logger对象 */ //e.printStackTrace(); /* 异常一般是error级别 * 级别由我们自己控制 * * 在为占位符赋值的时候,e一定要写到最后一个 * */ logger.error("调用toString;str:{}报,age:{}错了","来吧",20,e); } } } |
3.3 Mybatis的Hw
- Mybatis是替换Dao层的框架,先准备一个数据库;名字:mybatis
- 创建两张表,叫做一对多的表;朝代表和皇上表;crud(增删改查);
- 查询朝代表中所有的记录
- 拷贝jar包;将mybatis-3.4.5.jar和lib下面所有的包都拷贝到项目中,并且增加到classpath中,删除重复的jar包,删除老版本,留下新版本;mysql的驱动包;Junit,Log4j
创建一个配置文件,叫做:mybatis.cfg.xml;(只要扩展名是xml就可以)
POJO(A_ChaoDai)
package com.carlinfo.mybatis.data.pojo; import java.util.Date; /** * pojo,entity pojo == javaBean的三要素: Bean:豆子,对象 ~属性 ~读写器 ~无参的构造函数 * * @author wangshMac */ public class AChaoDai { /* 只有包装类型,默认才有可能会为null */ private Integer id; private String name; private String content; private Byte status; private Date createTime; private Date updateTime; Set/get方法 } |
映射文件:和POJO放到一起;名字叫做POJOMapper.xml(AChaoDaiMapper.xml)
<?xml version="1.0" encoding="UTF-8"?> <!-- 一个POJO对应一个Mapper文件 Mapper:映射文件 写SQL语句 --> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace的作用和package的作用一样; package的作用是:解决两个名字相同的类的问题;打一个文件夹 如果相同的目录中有两个名字一模一样的文件(映射文件中的sql的id),namespace --> <mapper namespace="test"> <!-- 查询是select标签 id:java中的类 在相同的namespace下面不能有相同的id,id如果同重复,要放到不同的namespace中 select:三要素: ~标签名:select ~属性 ~开始标签和结束标签中的内容:sql语句 resultType:返回值类型;如果返回值是多个,它指的是List中存储的元素 如果返回值是单个,它指的就是返回值的类型 值:指的是POJO的包名+类名; 底层用的是反射 --> <select id="selectList" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> select * from a_chaodai ; </select> </mapper> |
Mybatis核心配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!-- 普通的XML文件,里面的标签名和属性随便写 要想让它成为Mybatis的配置文件,里面的标签名和属性不能随便写 需要引用一个dtd; --> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 环境 default默认的myDefault; 多个environment的默认的id --> <environments default="myDefault"> <!-- 里面有多个environment,id不能重复 --> <environment id="myDefault"> <!-- 配置的是数据源的信息 JDBC的信息 --> <!-- transactionManager:事务管理器 --> <transactionManager type="JDBC"/> <!-- 数据源;数据存储的位置 type:POOLED;连接池 连接池是一个容器,里面放的是链接(Connection) --> <dataSource type="POOLED"> <!-- property的name不能随便写 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis?useSSL=true"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments>
<!-- 将映射文件(mapper)增加到核心的配置文件中 --> <mappers> <!-- resource:指的是Mapper文件存储的相对目录(参照物是:classpath) --> <mapper resource="com/carlinfo/mybatis/data/pojo/AChaoDaiMapper.xml"/> </mappers> </configuration> |
测试代码
package com.carlinfo.mybatis.test; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; 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.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.Test; import com.carlinfo.mybatis.data.pojo.AChaoDai; /** * Mybatis的测试类 * * @author wangshMac * */ public class MyBatisTest { /* Log4j2的对象 */ private Logger logger = LogManager.getLogger(); /** * Mybatis的第一个例子 */ @Test public void select() { /* * JDBC最关心的是SQL语句和条件,其它的不关心 * 获取类似于Connection,PreparedStatement,ResultSet * * SqlSessionFactory===Connection * Session===PreparedStatement * */ /* 配对于ClassPath的路径;JAVA文件编译成的Class存储的目录 * 所有的SourceFoler都是Classpath的根路径 * */ String resource = "mybatis.cfg.xml"; try { /*Mybatis以前的名字叫做IBatis*/ InputStream inputStream = Resources.getResourceAsStream(resource); /* 获取了sqlsessionFactory */ SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); /* 检测我的配置文件有没有写错 */ this.logger.info("==初始化成功==sqlSessionFactory:{}",sqlSessionFactory);
/* 创建一个session */ SqlSession session = sqlSessionFactory.openSession() ; /* 发送一个sql语句 */ /* 查询多条记录 * 参数是:namespace+sql的id * 如果id在所有的包里面只有一份,那么namespcace可以省略 * * selectList:查询多条, * selectOne:查询单条 * */ List<AChaoDai> chaoDaiList = session.selectList("test.selectList"); for (Iterator iterator = chaoDaiList.iterator(); iterator.hasNext();) { AChaoDai chaodai = (AChaoDai) iterator.next(); this.logger.info("id:{},name:{},status:{};createTime:{}" , chaodai.getId() , chaodai.getName() , chaodai.getStatus(), chaodai.getCreateTime().toLocaleString()); } } catch (IOException e) { this.logger.error("加载Mybatis配置文件报错了;路径:{}",resource , e); } } } |
Log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- status=debug 可以查看log4j的装配过程 --> <configuration status="off" monitorInterval="1800"> <appenders> <!-- 定义控制台输出 --> <Console name="Console" target="SYSTEM_OUT" follow="true"> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" /> </Console> <!-- 系统打印日志 ,按照天记录日志;filePattern文件的格式--> <RollingRandomAccessFile name="System" fileName="logs/system.log" filePattern="logs/system_%d{yyyy-MM-dd}_%i.log"> <!-- 日志文件中内容的格式 --> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" /> <Policies> <!-- 一天记录的日志如果大于100m,重新再创建一个新的日志 --> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> <SizeBasedTriggeringPolicy size="100M" /> </Policies> </RollingRandomAccessFile> </appenders> <loggers> <!-- Root Logger debug:可以看到mybatis的sql语句 --> <root level="debug"> <!-- 引入了一个Console和System --> <appender-ref ref="Console" /> <appender-ref ref="System" /> </root> <!-- 外部日志,只记录到文件中,不记录到控制台中 --> <logger name="SystemLog" level="info" additivity="false"> <appender-ref ref="System" /> </logger> </loggers> </configuration> |
Hw优化(常见问题)
如果出现以下错误:使用的是Log4j1.x版本,加上log4j1.x的配置文件(log4j.properties),
而我们现在使用的是log4j2;mybatis会自动的或者手动的log4j的版本;
解决方案:删除所有的日志版本,仅留下log4j2.x版本;
删除:commons-logging-1.2.jar;log4j-1.2.17.jar,slf4j-api-1.7.25.jar和slf4j-log4j12-1.7.25.jar
文件删除,classpath没有删除;
建议将mybatis的log4j2级别设成debug;可以看到sql语句
3.4 Mybatis-CRUD
- Mybatis的HW
- 先写映射文件,
<?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="test"> <!-- 查询多条记录 id:唯一标识 resultType=包名+类名 --> <select id="selectList" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> select * from a_chaodai </select>
<!-- 增加一条记录 如何让添加的记录变活呢? parameterType:参数的类型;都是POJO #{parameterType.属性};或者是提供了get方法; ===${对象名.属性} --> <insert id="insertOne" parameterType="com.carlinfo.mybatis.data.pojo.AChaoDai"> <!-- 增加的SQL语句 --> INSERT INTO a_chaodai(name, content, status, createTime, updateTime) VALUES (#{name}, #{content}, #{status}, #{createTime}, #{updateTime}) </insert>
<!-- 增加一条记录 useGeneratedKeys:使用主键 keyColumn:表里面哪一列是主键 keyProperty:pojo哪个属性是主键
只适用于数据库有主键自动递增的选项; --> <insert id="insertOneKey" parameterType="com.carlinfo.mybatis.data.pojo.AChaoDai" useGeneratedKeys="true" keyColumn="id" keyProperty="id"> <!-- 增加的SQL语句 --> INSERT INTO a_chaodai(name, content, status, createTime, updateTime) VALUES (#{name}, #{content}, #{status}, #{createTime}, #{updateTime}) </insert>
<!-- 增加一条记录 useGeneratedKeys:使用主键 keyColumn:表里面哪一列是主键 keyProperty:pojo哪个属性是主键
只适用于主键是序列的方式;(Oracle,Postgresql) --> <insert id="insertTwoKey" parameterType="com.carlinfo.mybatis.data.pojo.AChaoDai"> <!-- 增加的SQL语句 --> INSERT INTO a_chaodai(name, content, status, createTime, updateTime) VALUES (#{name}, #{content}, #{status}, #{createTime}, #{updateTime})
<!-- keyColumn:表里面哪一列是主键 keyProperty:pojo哪个属性是主键 resultType:主键的类型 order:顺序,获取主键的sql语句,执行的时候是在insert语句之前呢?还是之后呢? 序列的时候;是在插入数据库之前获取 --> <selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int"> <!-- 获取和insert语句一块执行时,insert语句的主键 --> <!-- select LAST_INSERT_ID(); --> select @@identity ; </selectKey> </insert>
<!-- 更新一条记录 --> <update id="update" parameterType="com.carlinfo.mybatis.data.pojo.AChaoDai"> update a_chaodai set name = #{name},content = #{content},updateTime = #{updateTime} where id = #{id} </update>
<!-- 更新一条记录 parameterType:是按照id删除,参数类型就是int 如果parameterType要是一个基本数据类型,#{随便填写} --> <delete id="delete" parameterType="int"> delete from a_chaodai where id = #{asdfasfasfasasf} </delete> </mapper> |
- BaseTest
package com.carlinfo.mybatis.test; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.After; import org.junit.Before; /** * 基本的测试类 * @author wangshMac * */ public class BaseTest { protected Logger logger = LogManager.getLogger(); protected SqlSessionFactory sqlSessionFactory ;
/** * 就是为了创建一个sqlsessionFactory */ @Before public void init() { /* 相对于Classpath的路径 */ String resource = "mybatis.cfg.xml" ; try { InputStream inputStream = Resources.getResourceAsStream(resource); /* 创建一个sqlsessionFactory */ sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); this.logger.info("-sqlSessionFactory-->{}" ,sqlSessionFactory); } catch (IOException e) { e.printStackTrace(); } }
@After public void close() { this.logger.info("--执行完毕 -"); } } |
- CRUDTest
package com.carlinfo.mybatis.test; import java.util.Date; import java.util.Iterator; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.carlinfo.mybatis.data.pojo.AChaoDai; /** * 测试Mybatis的CRUD * @author wangshMac */ public class CRUDTest extends BaseTest { /** * 查询多条记录 */ @Test public void selectList() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; /** * 参数为:sql语句的Id */ List<AChaoDai> chaoDaiList = session.selectList("selectList"); for (Iterator iterator = chaoDaiList.iterator(); iterator.hasNext();) { AChaoDai chaoDai = (AChaoDai) iterator.next(); this.logger.info("朝代:{}",chaoDai); }
/* 关闭session */ session.close(); }
/** * 添加一条朝代 */ @Test public void insert() { /** * 参数如果为true:表示自动提交,再也不需要手动提交了 */ SqlSession session = this.sqlSessionFactory.openSession(true); /** * 参数是sql语句的Id * 为sql语句传参就是第二个参数;第二个参数的类型和sql语句中的parameterType类型一致 */ AChaoDai chaoDai = new AChaoDai() ; chaoDai.setName("大明"); chaoDai.setContent("还是大明"); /* 有自动装箱和解箱 */ chaoDai.setStatus(Byte.valueOf("1")); chaoDai.setCreateTime(new Date()); chaoDai.setUpdateTime(new Date()); int res = session.insert("insertOne",chaoDai); /* 事务提交 * 如果opensession(true),此代码可以省略 * */ //session.commit(); this.logger.info("--增加一条记录返回:{}--主键:{}",res,chaoDai.getId()); }
/** * 添加一条朝代 */ @Test public void insertOneKey() { /** * 参数如果为true:表示自动提交,再也不需要手动提交了 */ SqlSession session = this.sqlSessionFactory.openSession(true); /** * 参数是sql语句的Id * 为sql语句传参就是第二个参数;第二个参数的类型和sql语句中的parameterType类型一致 */ AChaoDai chaoDai = new AChaoDai() ; chaoDai.setName("大明"); chaoDai.setContent("还是大明"); /* 有自动装箱和解箱 */ chaoDai.setStatus(Byte.valueOf("1")); chaoDai.setCreateTime(new Date()); chaoDai.setUpdateTime(new Date()); int res = session.insert("insertOneKey",chaoDai); /* 事务提交 * 如果opensession(true),此代码可以省略 * */ //session.commit(); this.logger.info("--增加一条记录返回:{}--主键:{}",res,chaoDai.getId()); }
/** * 添加一条朝代 */ @Test public void insertTwoKey() { /** * 参数如果为true:表示自动提交,再也不需要手动提交了 */ SqlSession session = this.sqlSessionFactory.openSession(true); /** * 参数是sql语句的Id * 为sql语句传参就是第二个参数;第二个参数的类型和sql语句中的parameterType类型一致 */ AChaoDai chaoDai = new AChaoDai() ; chaoDai.setName("大明"); chaoDai.setContent("还是大明"); /* 有自动装箱和解箱 */ chaoDai.setStatus(Byte.valueOf("1")); chaoDai.setCreateTime(new Date()); chaoDai.setUpdateTime(new Date()); int res = session.insert("insertOneKey",chaoDai); /* 事务提交 * 如果opensession(true),此代码可以省略 * */ //session.commit(); this.logger.info("--增加一条记录返回:{}--主键:{}",res,chaoDai.getId()); }
/** * 更新一条朝代 */ @Test public void updateTwoKey() { /** * 参数如果为true:表示自动提交,再也不需要手动提交了 */ SqlSession session = this.sqlSessionFactory.openSession(true); /** * 参数是sql语句的Id * 为sql语句传参就是第二个参数;第二个参数的类型和sql语句中的parameterType类型一致 */ AChaoDai chaoDai = new AChaoDai() ; /* 参数在设置的时候,sql语句用到的条件,一定要设置进去 */ chaoDai.setName("我是修改以后的"); chaoDai.setContent("我还是修改以后的"); chaoDai.setUpdateTime(new Date()); chaoDai.setId(2); int res = session.update("update",chaoDai); /* 事务提交 * 如果opensession(true),此代码可以省略 * */ //session.commit(); this.logger.info("--增加一条记录返回:{}--主键:{}",res,chaoDai.getId()); }
/** * 更新一条朝代 */ @Test public void delete() { /** * 参数如果为true:表示自动提交,再也不需要手动提交了 */ SqlSession session = this.sqlSessionFactory.openSession(true); /** * 参数是sql语句的Id * 为sql语句传参就是第二个参数;第二个参数的类型和sql语句中的parameterType类型一致 */ int res = session.delete("delete",1); /* 事务提交 * 如果opensession(true),此代码可以省略 * */ //session.commit(); this.logger.info("--删除一条记录返回:{}--主键:{}",res); } } |
3.5Mybatis配置
已经跑起来,说明配置木有问题;配置还其它的玩法
- 属性文件(数据源的配置)
- 别名的配置
- 全局变量的的配置
- 资源文件加载的配置
- 凡是一开始写的默认的就是强烈建议的
mybatis的核心配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"> <property name="url" value="jdbc:mysql:///mybatis?useSSL=true"/> <!-- 一个是当前配置文件中的properties标签, 一个是properties文件, 如果两个有重复的,以哪个为准呢?
如果正常:说明:以属性文件为主 如果不正常:说明以properties为主;
加载顺序:是以属性文件为先 --> <property name="jdbc.username" value="aaa"/> </properties>
<!-- 全局变量配置 --> <settings> <!-- name:是键,value:是值 --> <!-- 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 老是出问题,建议将其它的日志工具都删除掉,只留下你期望的日志版本 --> <setting name="logImpl" value="LOG4J2"/> </settings>
<!-- 类型别名 --> <typeAliases> <!-- 为包名+类名起一个别名,简化配置 --> <typeAlias type="com.carlinfo.mybatis.data.pojo.AChaoDai" alias="a"/> </typeAliases>
<environments default="my"> <environment id="my"> <!-- 事务管理器 --> <transactionManager type="JDBC"/> <!-- 数据源 --> <dataSource type="POOLED"> <!-- 推荐的配置是写在dataSource下面的property标签中 属性文件中的中文,还需要编码,如果木有插件,看不性配置文件中的中文是什么 如果是properties标签,都是xml配置文件,写哪不一样?分开写,容易开发人员找不到 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- ${};引用的其它地方的url --> <property name="url" value="${url}"/> <!-- ${}键值对中的键 每一个property:name就是键,value就是值 属性文件中=左边的是键,右边的是值 --> <property name="username" value="${jdbc.username}"/> <property name="password" value="123456"/> </dataSource> </environment> </environments>
<!-- 指定映射文件的路径 --> <mappers> <!-- 默认写的是相对路径,参照物是:classpath --> <!-- <mapper resource="com/carlinfo/mybatis/data/pojo/AChaoDaiMapper.xml"/> --> <!-- 写的是url的路径 url是在浏览器访问的绝对路径;如果有中文,你还得编码 class:注解;这些sql语句可以放到java代码中,就像@test一样; sql语句天天变,经常变,把sql挪到了xml配置文件中,现在又放到java代码中; --> <mapper url="file:///D:/%E7%8F%AD%E7%BA%A7/20171108/20180123-mybatis_%E5%9F%BA%E6%9C%AC/%E4%BB%A3%E7%A0%81/mybatis-03-config/src_data/com/carlinfo/mybatis/data/pojo/AChaoDaiMapper.xml"/> </mappers> </configuration> |
- Jdbc.properties
# =左边是键,=右边是值 jdbc.username = root |
3.6 输入参数和输出结果
输入参数:paramterType
输出结果:resultType
- 参照的是Mapper.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"> <mapper namespace="test"> <!-- 输入参数 parameterType: 基本数据类型:四类八种;#{随便写};char==string 自定义引用类型:#{对象的属性} map:#{map的键} --> <select id="selectInputBase" parameterType="int" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> select * from a_chaodai where id = #{afdasfasfasf} </select>
<!-- 自定义引用类型:#{对象的属性} --> <select id="selectInputRef" parameterType="com.carlinfo.mybatis.data.pojo.AChaoDai" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> select * from a_chaodai where id = #{id} </select>
<!-- map:#{map的键} parameterType:java.util.Map和map都可以,因为mybatis有自带的别名 --> <select id="selectInputMap" parameterType="java.util.Map" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> select * from a_chaodai where id = #{mapId} </select>
<!-- 输出结果,不再是条件,对应的是resultType 基本数据类型:四类八种;#{随便写};char==string 自定义引用类型:#{对象的属性} map: --> <select id="selectOutputBase" parameterType="map" resultType="int"> <!-- sql语句查询的结果是有多列,但是返回值是只有int接收, 那木有办法,mybatis不报错,把sql语句的第一列int值给放进去了 --> <!-- select * from a_chaodai --> select count(*) from a_chaodai </select>
<!-- 返回值为自定义引用类型; 如果返回的结果有多条,List中放的就是此类型 如果返回的结果有一条,返回值类型就是它 --> <select id="selectOutputRef" parameterType="map" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> <!-- sql语句查询的结果是有多列,但是返回值是只有int接收, 那木有办法,mybatis不报错,把sql语句的第一列int值给放进去了 --> <!-- select * from a_chaodai --> select * from a_chaodai </select>
<!-- 如果返回值类型是map 如果查询的结果是多条,List中放的就是map 如果查询的结果有一条,返回值类型就是map
map中放的是啥? 键是sql语句执行完以后的列名,值就是列的值 --> <select id="selectOutputMap" parameterType="map" resultType="map"> <!-- sql语句查询的结果是有多列,但是返回值是只有int接收, 那木有办法,mybatis不报错,把sql语句的第一列int值给放进去了 --> <!-- select * from a_chaodai --> select * from a_chaodai </select> <!-- $和#的区别 #:生成的SQL语句是占位符,PreparedStatement $:生成的SQL语句是原样输入,Statement --> <select id="selectOther" parameterType="map" resultType="com.carlinfo.mybatis.data.pojo.AChaoDai"> select * from a_chaodai where id = ${mapId} </select> </mapper> |
- 测试代码:
package com.carlinfo.mybatis.test; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.carlinfo.mybatis.data.pojo.AChaoDai; /** * 测试Mybatis的CRUD * * 输入参数:parameterType:在CRUD标签中都有 * 输出结果:resultType在CRUD标签中都有 * int save(自定义引用类型); * update(自定义引用类型) * delete(map) * 自定义引用类型 findOne(map);selecOne * 自定义引用类型 findCondList(map):selectList(); * * @author wangshMac */ public class IOTest extends BaseTest { /** * 查询一条记录 */ @Test public void selectOne() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; /** * 参数为:sql语句的Id * 参数2:sql语句的条件它必须和parameterType类型一致 */ AChaoDai chaoDai= session.selectOne("selectInputBase",2); this.logger.info("朝代:{}",chaoDai);
/* 关闭session */ session.close(); }
/** * 查询一条记录 */ @Test public void selectInputRef() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; /** * 参数为:sql语句的Id * 参数2:sql语句的条件它必须和parameterType类型一致 */ AChaoDai chaoDaiCond = new AChaoDai() ; chaoDaiCond.setId(2); AChaoDai chaoDai= session.selectOne("selectInputRef",chaoDaiCond); this.logger.info("朝代:{}",chaoDai);
/* 关闭session */ session.close(); }
/** * 查询一条记录 */ @Test public void selectInputMap() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; /** * 参数为:sql语句的Id * 参数2:sql语句的条件它必须和parameterType类型一致 */ Map<String, Object> condMap = new HashMap<String, Object>(); /* map的键应该和sql语句中#{}中间的一样 */ condMap.put("mapId", 5); AChaoDai chaoDai= session.selectOne("selectInputMap",condMap); this.logger.info("朝代:{}",chaoDai);
/* 关闭session */ session.close(); }
/** * 查询一条记录 */ @Test public void selectOutputBase() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; /** * 参数为:sql语句的Id * 参数2:sql语句的条件它必须和parameterType类型一致 * 如果sql语句的结果是多条,非要拿selectOne去接收,就会报以下错误 * org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 11 */ Map<String, Object> condMap = new HashMap<String, Object>(); /* map木有用 */ List<AChaoDai> chaoDaiList= session.selectList("selectOutputBase",condMap); /* 为什么不循环打印List中的内容,主要是为了在session.close处打断点, * 通过断点看看里面List放的是什么 */ //this.logger.info("朝代:{}",chaoDai); /* 关闭session */ session.close(); }
/** * 查询一条记录 */ @Test public void selectOutputMap() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; /** * 参数为:sql语句的Id * 参数2:sql语句的条件它必须和parameterType类型一致 * 如果sql语句的结果是多条,非要拿selectOne去接收,就会报以下错误 * org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 11 */ Map<String, Object> condMap = new HashMap<String, Object>(); /* map木有用 */ List<Map> chaoDaiList= session.selectList("selectOutputMap",condMap); for (Iterator iterator = chaoDaiList.iterator(); iterator.hasNext();) { Map map = (Map) iterator.next(); this.logger.info("结果:{}",map); } //this.logger.info("朝代:{}",chaoDai); /* 关闭session */ session.close(); }
/** * 查询一条记录 */ @Test public void selectOther() { /* 创建一个session */ SqlSession session = this.sqlSessionFactory.openSession() ; Map<String, Object> condMap = new HashMap<String, Object>(); /* map木有用 */ condMap.put("mapId", 5); List<AChaoDai> chaoDaiList= session.selectList("selectOther",condMap); for (Iterator iterator = chaoDaiList.iterator(); iterator.hasNext();) { AChaoDai map = (AChaoDai) iterator.next(); this.logger.info("结果:{}",map); } //this.logger.info("朝代:{}",chaoDai); /* 关闭session */ session.close(); } } |