public class Product {
private Long id;
//商品名称
private String productName;
//品牌
private String brand;
//供应商
private String supplier;
//零售价
private BigDecimal salePrice;
//进价
private BigDecimal costPrice;
//折扣价
private Double cutoff;
//商品分类编号
private Long dir_id;
//提供getter与setter...
}
public interface IProductDao {
void save(Product product);
void remove(Long id);
void update(Product product);
Product loadOne(Long id);
List loadAll();
}
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql:///mybatistest
db.username=xxx
db.password=xxxxx
INSERT INTO product (productName,brand,supplier,salePrice,costPrice,cutoff,dir_id) VALUES (
#{productName},
#{brand},
#{supplier},
#{salePrice},
#{costPrice},
#{cutoff},
#{dir_id})
DELETE FROM product WHERE id = #{id}
update product set
productName = #{productName},
brand = #{brand},
supplier = #{supplier},
salePrice = #{salePrice},
costPrice = #{costPrice},
cutoff = #{cutoff},
dir_id = #{dir_id}
where id = #{id}
小结:
配置MyBatis-Config.xml
引入关系映射xml,关系映射文件中的sql决定了功能
映射文件要取命名空间,方便区分使用
映射文件中的sql方法取id,实现的时候调用这个id就可以
注意 sql中的配置
注意配置文件中的文件路径和实体路径,如果是文件的地址,是斜杠划分
实体类是.划分
实现方法的时候,是使用的命名空间的命名加上方法id
MyBatis-Config.xml引入的是xml映射关系文件
问题:
每次实现方法都需要创建,获取,关闭。。
@Override
public void save(Product product) {
SqlSession sqlSession = null;
try {
//加载mybatis.xml文件
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//获取session工厂对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//测试工厂对象是否加载成功
System.out.println(sessionFactory);
//拿到session
sqlSession = sessionFactory.openSession();
//返回集合selectList
sqlSession.insert("com.lr.mybatis._01_hello.domain.ProductMapper.save",product);
sqlSession.commit();
}catch (Exception e){
sqlSession.rollback();
e.printStackTrace();
}finally {
//关闭session
if (sqlSession!=null){
sqlSession.close();
}
}
}
入门小结
为了减少重复代码,抽取一个工具类,可以方便的获取session对象和关闭对象
public enum MybatisUtil {
INSTANCE;
//获取session的工厂
private static SqlSessionFactory sessionFactory;
//静态代码块,运行就创建
//在其他地方可以随时调用获取session
static {
//加载工厂对象
//加载mybatis.xml文件
try {
//注意try catch中如果先没有处理异常,会报错
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//获取session工厂对象
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
}catch (Exception e){
e.printStackTrace();
}
}
//得到sqlsession的方法
public SqlSession openSqlSession (){
//System.out.println("================");
SqlSession sqlSession = sessionFactory.openSession();
//System.out.println("+++++++++++++++++++++++");
return sqlSession;
}
//关闭 SqlSession 的方法 需要传入sqlSession 确定要关闭的对象是哪一个
public void endSqlSession(SqlSession sqlSession){
if (sqlSession!=null){
sqlSession.close();
}
}
}
配置的方法
log4j.rootLogger=DEBUG, stdout
#log4j.rootLogger=NONE
log4j.logger.com.lr=TRACE
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
一定要根据自己的包名情况进行修改
如果配置成功,那么在MyBatis运行操作数据时就可以看到相应的日志了。
如果要打印到debug,需要改成
log4j.rootLogger=DEBUG, stdout
MyBatis会把这个表达式使用?(占位符)替换,作为一个sql参数使用:推荐使用
比如name的值为:
定义SQL: select * from t_user where name = #{name}
最终SQL: select * from t_user where name = ?
MyBatis会把这个表达式的值替换到sql中,作为sql的组成部分;
该方式主要用于程序拼接SQL;
如果sql中使用${OGNL},并且参数的类型是(integer,string…)那么OGNL表达式可以写成任意东西;
User user=new User();
user.setName("\"admin\" or \"1=1\" ");
user.setPassword("\"admin\" ");
定义SQL: select id,name,password from t_user where name = ${name} and password=${password}
最终SQL: select id,name,password from t_user where name="test" or "1=1" and password="test" 出现sql注入
2)用在order by + limit的场景
DELETE FROM product WHERE id IN
#{id}
实现方法
@Override
public void removeMany(List ids) {
System.out.println("=======================");
SqlSession sqlSession =null;
try {
sqlSession = MybatisUtil.INSTANCE.openSqlSession();
sqlSession.delete("com.lr.mybatis._04_batch_many.domain.ProductMapper.removeMany", ids);
//提交事务
sqlSession.commit();
}catch (Exception e){
//事务回滚
sqlSession.rollback();
e.printStackTrace();
}finally {
MybatisUtil.INSTANCE.endSqlSession(sqlSession);
}
}
INSERT INTO product (productName,brand,supplier,salePrice,costPrice,cutoff,dir_id)VALUES
(#{product.productName},#{product.brand},#{product.supplier},#{product.salePrice},
#{product.costPrice},#{product.cutoff},#{product.dir_id})
实现方法
@Override
public void addMany(List list) {
SqlSession sqlSession =null;
try {
sqlSession = MybatisUtil.INSTANCE.openSqlSession();
sqlSession.delete("com.lr.mybatis._04_batch_many.domain.ProductMapper.addMany", list);
//提交事务
sqlSession.commit();
}catch (Exception e){
//事务回滚
sqlSession.rollback();
e.printStackTrace();
}finally {
MybatisUtil.INSTANCE.endSqlSession(sqlSession);
}
}